⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 extlinux.asm

📁 linux内核
💻 ASM
📖 第 1 页 / 共 3 页
字号:
; Truncate BP to MaxTransfer;maxtrans:		cmp bp,[MaxTransfer]		jna .ok		mov bp,[MaxTransfer].ok:		ret;; Error message on failure;bailmsg:	db 'Boot error', 0Dh, 0Ah, 0		; This fails if the boot sector overflows		zb 1F8h-($-$$)FirstSector	dd 0xDEADBEEF			; Location of sector 1MaxTransfer	dw 0x007F			; Max transfer sizebootsignature	dw 0AA55h;; ===========================================================================;  End of boot sector; ===========================================================================;  Start of LDLINUX.SYS; ===========================================================================ldlinux_sys:syslinux_banner	db 0Dh, 0Ah		db 'EXTLINUX '		db version_str, ' ', date, ' ', 0		db 0Dh, 0Ah, 1Ah	; EOF if we "type" this in DOS		align 8, db 0ldlinux_magic	dd LDLINUX_MAGIC		dd LDLINUX_MAGIC^HEXDATE;; This area is patched by the installer.  It is found by looking for; LDLINUX_MAGIC, plus 8 bytes.;patch_area:LDLDwords	dw 0		; Total dwords starting at ldlinux_sysLDLSectors	dw 0		; Number of sectors - (bootsec+this sec)CheckSum	dd 0		; Checksum starting at ldlinux_sys				; value = LDLINUX_MAGIC - [sum of dwords]CurrentDir	dd 2		; "Current" directory inode number; Space for up to 64 sectors, the theoretical maximumSectorPtrs	times 64 dd 0ldlinux_ent:; ; Note that some BIOSes are buggy and run the boot sector at 07C0:0000; instead of 0000:7C00 and the like.  We don't want to add anything; more to the boot sector, so it is written to not assume a fixed; value in CS, but we don't want to deal with that anymore from now; on.;		jmp 0:.next.next:;; Tell the user we got this far;		mov si,syslinux_banner		call writestr;; Tell the user if we're using EBIOS or CBIOS;print_bios:		mov si,cbios_name		cmp byte [getlinsec.jmp+1],(getlinsec_ebios-(getlinsec.jmp+2))		jne .cbios		mov si,ebios_name.cbios:		mov [BIOSName],si		call writestr		section .bss%define	HAVE_BIOSNAME 1BIOSName	resw 1		section .text;; Now we read the rest of LDLINUX.SYS.	Don't bother loading the first; sector again, though.;load_rest:		mov si,SectorPtrs		mov bx,7C00h+2*SECTOR_SIZE	; Where we start loading		mov cx,[LDLSectors].get_chunk:		jcxz .done		xor bp,bp		lodsd				; First sector of this chunk		mov edx,eax.make_chunk:		inc bp		dec cx		jz .chunk_ready		inc edx				; Next linear sector		cmp [si],edx			; Does it match		jnz .chunk_ready		; If not, this is it		add si,4			; If so, add sector to chunk		jmp short .make_chunk.chunk_ready:		call getlinsecsr		shl bp,SECTOR_SHIFT		add bx,bp		jmp .get_chunk.done:;; All loaded up, verify that we got what we needed.; Note: the checksum field is embedded in the checksum region, so; by the time we get to the end it should all cancel out.;verify_checksum:		mov si,ldlinux_sys		mov cx,[LDLDwords]		mov edx,-LDLINUX_MAGIC.checksum:		lodsd		add edx,eax		loop .checksum		and edx,edx			; Should be zero		jz all_read			; We're cool, go for it!;; Uh-oh, something went bad...;		mov si,checksumerr_msg		call writestr		jmp kaboom;; -----------------------------------------------------------------------------; Subroutines that have to be in the first sector; -----------------------------------------------------------------------------;;; writestr: write a null-terminated string to the console;	    This assumes we're on page 0.  This is only used for early;           messages, so it should be OK.;writestr:.loop:		lodsb		and al,al                jz .return		mov ah,0Eh		; Write to screen as TTY		mov bx,0007h		; Attribute		int 10h		jmp short .loop.return:	ret; getlinsecsr: save registers, call getlinsec, restore registers;getlinsecsr:	pushad		call getlinsec		popad		ret;; Checksum error message;checksumerr_msg	db ' Load error - ', 0	; Boot failed appended;; BIOS type string;cbios_name	db 'CBIOS', 0ebios_name	db 'EBIOS', 0;; Debug routine;%ifdef debugsafedumpregs:		cmp word [Debug_Magic],0D00Dh		jnz nc_return		jmp dumpregs%endifrl_checkpt	equ $				; Must be <= 8000hrl_checkpt_off	equ ($-$$)%ifndef DEPEND%if rl_checkpt_off > 400h%error "Sector 1 overflow"%endif%endif; ----------------------------------------------------------------------------;  End of code and data that have to be in the first sector; ----------------------------------------------------------------------------all_read:;; Let the user (and programmer!) know we got this far.  This used to be; in Sector 1, but makes a lot more sense here.;		mov si,copyright_str		call writestr;; Insane hack to expand the DOS superblock to dwords;expand_super:		xor eax,eax		mov si,superblock		mov di,SuperInfo		mov cx,superinfo_size.loop:		lodsw		dec si		stosd				; Store expanded word		xor ah,ah		stosd				; Store expanded byte		loop .loop;; Load the real (ext2) superblock; 1024 bytes long at offset 1024;		mov bx,SuperBlock		mov eax,1024 >> SECTOR_SHIFT		mov bp,ax		call getlinsec;; Compute some values...;		xor edx,edx		inc edx		; s_log_block_size = log2(blocksize) - 10		mov cl,[SuperBlock+s_log_block_size]		add cl,10		mov [ClustByteShift],cl		mov eax,edx		shl eax,cl		mov [ClustSize],eax		sub cl,SECTOR_SHIFT		mov [ClustShift],cl		shr eax,SECTOR_SHIFT		mov [SecPerClust],eax		dec eax		mov [ClustMask],eax		add cl,SECTOR_SHIFT-2		; 4 bytes/pointer		shl edx,cl		mov [PtrsPerBlock1],edx		shl edx,cl		mov [PtrsPerBlock2],edx;; Common initialization code;%include "init.inc"%include "cpuinit.inc";; Initialize the metadata cache;		call initcache;; Now, everything is "up and running"... patch kaboom for more; verbosity and using the full screen system;		; E9 = JMP NEAR		mov dword [kaboom.patch],0e9h+((kaboom2-(kaboom.patch+3)) << 8);; Now we're all set to start with our *real* business.	First load the; configuration file (if any) and parse it.;; In previous versions I avoided using 32-bit registers because of a; rumour some BIOSes clobbered the upper half of 32-bit registers at; random.  I figure, though, that if there are any of those still left; they probably won't be trying to install Linux on them...;; The code is still ripe with 16-bitisms, though.  Not worth the hassle; to take'm out.  In fact, we may want to put them back if we're going; to boot ELKS at some point.;;; Load configuration file;load_config:		mov di,ConfigName		call open		jz no_config_file;; Now we have the config file open.  Parse the config file and; run the user interface.;%include "ui.inc";; Linux kernel loading code is common.;%include "runkernel.inc";; COMBOOT-loading code;%include "comboot.inc"%include "com32.inc"%include "cmdline.inc";; Boot sector loading code;%include "bootsect.inc";; getlinsec_ext: same as getlinsec, except load any sector from the zero;		 block as all zeros; use to load any data derived;		 from an ext2 block pointer, i.e. anything *except the;		 superblock.*;getonesec_ext:		mov bp,1getlinsec_ext:		cmp eax,[SecPerClust]		jae getlinsec			; Nothing fancy		; If we get here, at least part of what we want is in the		; zero block.  Zero one sector at a time and loop.		push eax		push cx		xchg di,bx		xor eax,eax		mov cx,SECTOR_SIZE >> 2		rep stosd		xchg di,bx		pop cx		pop eax		inc eax		dec bp		jnz getlinsec_ext		ret;; Abort loading code;%include "abort.inc";; allocate_file: Allocate a file structure;;		If successful:;		  ZF set;		  BX = file pointer;		In unsuccessful:;		  ZF clear;allocate_file:		TRACER 'a'		push cx		mov bx,Files		mov cx,MAX_OPEN.check:		cmp dword [bx], byte 0		je .found		add bx,open_file_t_size		; ZF = 0		loop .check		; ZF = 0 if we fell out of the loop.found:		pop cx		ret;; open_inode:;	     Open a file indicated by an inode number in EAX;;	     NOTE: This file considers finding a zero-length file an;	     error.  This is so we don't have to deal with that special;	     case elsewhere in the program (most loops have the test;	     at the end).;;	     If successful:;		ZF clear;		SI	    = file pointer;		DX:AX = EAX = file length in bytes;		ThisInode   = the first 128 bytes of the inode;	     If unsuccessful;		ZF set;;	     Assumes CS == DS == ES.;open_inode.allocate_failure:		xor eax,eax		pop bx		pop di		retopen_inode:		push di		push bx		call allocate_file		jnz .allocate_failure		push cx		push gs		; First, get the appropriate inode group and index		dec eax				; There is no inode 0		xor edx,edx		mov [bx+file_sector],edx		div dword [SuperBlock+s_inodes_per_group]		; EAX = inode group; EDX = inode within group		push edx		; Now, we need the block group descriptor.		; To get that, we first need the relevant descriptor block.						shl eax, ext2_group_desc_lg2size ; Get byte offset in desc table		xor edx,edx		div dword [ClustSize]		; eax = block #, edx = offset in block		add eax,dword [SuperBlock+s_first_data_block]		inc eax				; s_first_data_block+1		mov cl,[ClustShift]		shl eax,cl		push edx		shr edx,SECTOR_SHIFT		add eax,edx		pop edx		and dx,SECTOR_SIZE-1		call getcachesector		; Get the group descriptor		add si,dx		mov esi,[gs:si+bg_inode_table]	; Get inode table block #		pop eax				; Get inode within group		movzx edx, word [SuperBlock+s_inode_size]		mul edx		; edx:eax = byte offset in inode table		div dword [ClustSize]		; eax = block # versus inode table, edx = offset in block		add eax,esi		shl eax,cl			; Turn into sector		push dx		shr edx,SECTOR_SHIFT		add eax,edx		mov [bx+file_in_sec],eax		pop dx		and dx,SECTOR_SIZE-1		mov [bx+file_in_off],dx		call getcachesector		add si,dx		mov cx,EXT2_GOOD_OLD_INODE_SIZE >> 2		mov di,ThisInode		gs rep movsd		mov ax,[ThisInode+i_mode]		mov [bx+file_mode],ax		mov eax,[ThisInode+i_size]		push eax		add eax,SECTOR_SIZE-1		shr eax,SECTOR_SHIFT		mov [bx+file_left],eax		pop eax		mov si,bx		mov edx,eax		shr edx,16			; 16-bitism, sigh		and eax,eax			; ZF clear unless zero-length file		pop gs		pop cx		pop bx		pop di		ret		section .latebss		alignb 4ThisInode	resb EXT2_GOOD_OLD_INODE_SIZE	; The most recently opened inode		section .text;; close:;	     Deallocates a file structure (pointer in SI);	     Assumes CS == DS.;close:		mov dword [si],0		; First dword == file_left		ret;; searchdir:;	     Search the root directory for a pre-mangled filename in DS:DI.;;	     NOTE: This file considers finding a zero-length file an;	     error.  This is so we don't have to deal with that special;	     case elsewhere in the program (most loops have the test;	     at the end).;;	     If successful:;		ZF clear;		SI	    = file pointer;		DX:AX = EAX = file length in bytes;	     If unsuccessful;		ZF set;;	     Assumes CS == DS == ES; *** IS THIS CORRECT ***?;searchdir:		push bx		push cx		push bp		mov byte [SymlinkCtr],MAX_SYMLINKS		mov eax,[CurrentDir].begin_path:.leadingslash:		cmp byte [di],'/'	; Absolute filename?		jne .gotdir		mov eax,EXT2_ROOT_INO		inc di			; Skip slash		jmp .leadingslash.gotdir:		; At this point, EAX contains the directory inode,		; and DS:DI contains a pathname tail..open:		push eax		; Save directory inode		call open_inode		jz .done		; If error, done		mov cx,[si+file_mode]		shr cx,S_IFSHIFT	; Get file type		cmp cx,T_IFDIR		je .directory

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -