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

📄 extlinux.asm

📁 linux内核
💻 ASM
📖 第 1 页 / 共 3 页
字号:
		add sp,4		; Drop directory inode		cmp cx,T_IFREG		je .file		cmp cx,T_IFLNK		je .symlink		; Otherwise, something bad....err:		call close.err_noclose:		xor eax,eax		xor si,si		cwd			; DX <- 0.done:		and eax,eax		; Set/clear ZF		pop bp		pop cx		pop bx		ret		;		; It's a file.		;.file:		cmp byte [di],0		; End of path?		je .done		; If so, done		jmp .err		; Otherwise, error		;		; It's a directory.		;.directory:		pop dword [ThisDir]	; Remember what directory we're searching		cmp byte [di],0		; More path?		je .err			; If not, bad		.skipslash:				; Skip redundant slashes		cmp byte [di],'/'		jne .readdir		inc di		jmp .skipslash.readdir:		mov bx,trackbuf		push bx		mov cx,[SecPerClust]		call getfssec		pop bx		pushf			; Save EOF flag		push si			; Save filesystem pointer.getent:		cmp dword [bx+d_inode],0		je .endblock				push di		movzx cx,byte [bx+d_name_len]		lea si,[bx+d_name]		repe cmpsb		je .maybe.nope:		pop di		add bx,[bx+d_rec_len]		jmp .getent.endblock:		pop si		popf		jnc .readdir		; There is more		jmp .err		; Otherwise badness....maybe:		mov eax,[bx+d_inode]				; Does this match the end of the requested filename?		cmp byte [di],0		je .finish		cmp byte [di],'/'		jne .nope		; We found something; now we need to open the file.finish:		pop bx			; Adjust stack (di)		pop si		call close		; Close directory		pop bx			; Adjust stack (flags)		jmp .open		;		; It's a symlink.  We have to determine if it's a fast symlink		; (data stored in the inode) or not (data stored as a regular		; file.)  Either which way, we start from the directory		; which we just visited if relative, or from the root directory		; if absolute, and append any remaining part of the path.		;.symlink:		dec byte [SymlinkCtr]		jz .err			; Too many symlink references		cmp eax,SYMLINK_SECTORS*SECTOR_SIZE		jae .err		; Symlink too long		; Computation for fast symlink, as defined by ext2/3 spec		xor ecx,ecx		cmp [ThisInode+i_file_acl],ecx		setne cl		; ECX <- i_file_acl ? 1 : 0		cmp [ThisInode+i_blocks],ecx		jne .slow_symlink		; It's a fast symlink.fast_symlink:		call close		; We've got all we need		mov si,ThisInode+i_block		push di		mov di,SymlinkTmpBuf		mov ecx,eax		rep movsb		pop si.symlink_finish:		cmp byte [si],0		je .no_slash		mov al,'/'		stosb.no_slash:		mov bp,SymlinkTmpBufEnd		call strecpy		jc .err_noclose		; Buffer overflow		; Now copy it to the "real" buffer; we need to have		; two buffers so we avoid overwriting the tail on the		; next copy		mov si,SymlinkTmpBuf		mov di,SymlinkBuf		push di		call strcpy		pop di		mov eax,[ThisDir]	; Resume searching previous directory		jmp .begin_path.slow_symlink:		mov bx,SymlinkTmpBuf		mov cx,SYMLINK_SECTORS		call getfssec		; The EOF closed the file		mov si,di		; SI = filename tail		mov di,SymlinkTmpBuf		add di,ax		; AX = file length		jmp .symlink_finish		section .bss		alignb	4SymlinkBuf	resb	SYMLINK_SECTORS*SECTOR_SIZE+64SymlinkTmpBuf	 equ	trackbufSymlinkTmpBufEnd equ	trackbuf+SYMLINK_SECTORS*SECTOR_SIZE+64ThisDir		resd	1SymlinkCtr	resb	1		section .text;; mangle_name: Mangle a filename pointed to by DS:SI into a buffer pointed;	       to by ES:DI; ends on encountering any whitespace.;;	       This verifies that a filename is < FILENAME_MAX characters,;	       doesn't contain whitespace, zero-pads the output buffer,;	       and removes redundant slashes,;	       so "repe cmpsb" can do a compare, and the;	       path-searching routine gets a bit of an easier job.;;	       FIX: we may want to support \-escapes here (and this would;	       be the place.);	       mangle_name:		push bx		xor ax,ax		mov cx,FILENAME_MAX-1		mov bx,di.mn_loop:		lodsb		cmp al,' '			; If control or space, end		jna .mn_end		cmp al,ah			; Repeated slash?		je .mn_skip		xor ah,ah		cmp al,'/'		jne .mn_ok		mov ah,al.mn_ok		stosb.mn_skip:	loop .mn_loop.mn_end:		cmp bx,di			; At the beginning of the buffer?		jbe .mn_zero		cmp byte [di-1],'/'		; Terminal slash?		jne .mn_zero.mn_kill:	dec di				; If so, remove it		inc cx		jmp short .mn_end.mn_zero:		inc cx				; At least one null byte		xor ax,ax			; Zero-fill name		rep stosb		pop bx		ret				; Done;; unmangle_name: Does the opposite of mangle_name; converts a DOS-mangled;                filename to the conventional representation.  This is needed;                for the BOOT_IMAGE= parameter for the kernel.;                NOTE: A 13-byte buffer is mandatory, even if the string is;                known to be shorter.;;                DS:SI -> input mangled file name;                ES:DI -> output buffer;;                On return, DI points to the first byte after the output name,;                which is set to a null byte.;unmangle_name:	call strcpy		dec di				; Point to final null byte		ret;; writechr:	Write a single character in AL to the console without;		mangling any registers; handle video pages correctly.;writechr:		call write_serial	; write to serial port if needed		pushfd		test byte [cs:DisplayCon],01h		jz .nothing		pushad		mov ah,0Eh		mov bl,07h		; attribute		mov bh,[cs:BIOS_page]	; current page		int 10h		popad.nothing:		popfd		ret;;; kaboom2: once everything is loaded, replace the part of kaboom;	   starting with "kaboom.patch" with this partkaboom2:		mov si,err_bootfailed		call cwritestr		call getchar		call vgaclearmode		int 19h			; And try once more to boot....norge:		jmp short .norge	; If int 19h returned; this is the end;; linsector:	Convert a linear sector index in a file to a linear sector number;	EAX	-> linear sector number;	DS:SI	-> open_file_t;;		Returns next sector number in EAX; CF on EOF (not an error!);linsector:		push gs		push ebx		push esi		push edi		push ecx		push edx		push ebp		push eax		; Save sector index		mov cl,[ClustShift]		shr eax,cl		; Convert to block number		push eax		mov eax,[si+file_in_sec]		mov bx,si		call getcachesector	; Get inode		add si,[bx+file_in_off]	; Get *our* inode		pop eax		lea ebx,[i_block+4*eax]		cmp eax,EXT2_NDIR_BLOCKS		jb .direct		mov ebx,i_block+4*EXT2_IND_BLOCK		sub eax,EXT2_NDIR_BLOCKS		mov ebp,[PtrsPerBlock1]		cmp eax,ebp		jb .ind1		mov ebx,i_block+4*EXT2_DIND_BLOCK		sub eax,ebp		mov ebp,[PtrsPerBlock2]		cmp eax,ebp		jb .ind2		mov ebx,i_block+4*EXT2_TIND_BLOCK		sub eax,ebp.ind3:		; Triple indirect; eax contains the block no		; with respect to the start of the tind area;		; ebx contains the pointer to the tind block.		xor edx,edx		div dword [PtrsPerBlock2]		; EAX = which dind block, EDX = pointer within dind block		push ax		shr eax,SECTOR_SHIFT-2		mov ebp,[gs:si+bx]		shl ebp,cl		add eax,ebp		call getcachesector		pop bx		and bx,(SECTOR_SIZE >> 2)-1		shl bx,2		mov eax,edx		; The ind2 code wants the remainder....ind2:		; Double indirect; eax contains the block no		; with respect to the start of the dind area;		; ebx contains the pointer to the dind block.		xor edx,edx		div dword [PtrsPerBlock1]		; EAX = which ind block, EDX = pointer within ind block		push ax		shr eax,SECTOR_SHIFT-2		mov ebp,[gs:si+bx]		shl ebp,cl		add eax,ebp		call getcachesector		pop bx		and bx,(SECTOR_SIZE >> 2)-1		shl bx,2		mov eax,edx		; The int1 code wants the remainder....ind1:		; Single indirect; eax contains the block no		; with respect to the start of the ind area;		; ebx contains the pointer to the ind block.		push ax		shr eax,SECTOR_SHIFT-2		mov ebp,[gs:si+bx]		shl ebp,cl		add eax,ebp		call getcachesector		pop bx		and bx,(SECTOR_SIZE >> 2)-1		shl bx,2.direct:		mov ebx,[gs:bx+si]	; Get the pointer		pop eax			; Get the sector index again		shl ebx,cl		; Convert block number to sector		and eax,[ClustMask]	; Add offset within block		add eax,ebx		pop ebp		pop edx		pop ecx		pop edi		pop esi		pop ebx		pop gs		ret;; getfssec: Get multiple sectors from a file;;	Same as above, except SI is a pointer to a open_file_t;;	ES:BX	-> Buffer;	DS:SI	-> Pointer to open_file_t;	CX	-> Sector count (0FFFFh = until end of file);                  Must not exceed the ES segment;	Returns CF=1 on EOF (not necessarily error);	All arguments are advanced to reflect data read.;getfssec:		push ebp		push eax		push edx		push edi		movzx ecx,cx		cmp ecx,[si]			; Number of sectors left		jbe .lenok		mov cx,[si].lenok:.getfragment:		mov eax,[si+file_sector]	; Current start index		mov edi,eax		call linsector		push eax			; Fragment start sector		mov edx,eax		xor ebp,ebp			; Fragment sector count.getseccnt:		inc bp		dec cx		jz .do_read		xor eax,eax		mov ax,es		shl ax,4		add ax,bx			; Now DI = how far into 64K block we are		not ax				; Bytes left in 64K block		inc eax		shr eax,SECTOR_SHIFT		; Sectors left in 64K block		cmp bp,ax		jnb .do_read			; Unless there is at least 1 more sector room...		inc edi				; Sector index		inc edx				; Linearly next sector		mov eax,edi		call linsector		; jc .do_read		cmp edx,eax		je .getseccnt.do_read:		pop eax				; Linear start sector		pushad		call getlinsec_ext		popad		push bp		shl bp,9		add bx,bp			; Adjust buffer pointer		pop bp		add [si+file_sector],ebp	; Next sector index		sub [si],ebp			; Sectors consumed		jcxz .done		jnz .getfragment		; Fall through.done:		cmp dword [si],1		; Did we run out of file?		; CF set if [SI] < 1, i.e. == 0		pop edi		pop edx		pop eax		pop ebp		ret; -----------------------------------------------------------------------------;  Common modules; -----------------------------------------------------------------------------%include "getc.inc"		; getc et al%include "conio.inc"		; Console I/O%include "writestr.inc"		; String output%include "parseconfig.inc"	; High-level config file handling%include "parsecmd.inc"		; Low-level config file handling%include "bcopy32.inc"		; 32-bit bcopy%include "loadhigh.inc"		; Load a file into high memory%include "font.inc"		; VGA font stuff%include "graphics.inc"		; VGA graphics%include "highmem.inc"		; High memory sizing%include "strcpy.inc"           ; strcpy()%include "strecpy.inc"          ; strcpy with end pointer check%include "cache.inc"; -----------------------------------------------------------------------------;  Begin data section; -----------------------------------------------------------------------------		section .datacopyright_str   db ' Copyright (C) 1994-', year, ' H. Peter Anvin'		db CR, LF, 0boot_prompt	db 'boot: ', 0wipe_char	db BS, ' ', BS, 0err_notfound	db 'Could not find kernel image: ',0err_notkernel	db CR, LF, 'Invalid or corrupt kernel image.', CR, LF, 0err_noram	db 'It appears your computer has less than '		asciidec dosram_k		db 'K of low ("DOS")'		db CR, LF		db 'RAM.  Linux needs at least this amount to boot.  If you get'		db CR, LF		db 'this message in error, hold down the Ctrl key while'		db CR, LF		db 'booting, and I will take your word for it.', CR, LF, 0err_badcfg      db 'Unknown keyword in extlinux.conf.', CR, LF, 0err_noparm      db 'Missing parameter in extlinux.conf.', CR, LF, 0err_noinitrd    db CR, LF, 'Could not find ramdisk image: ', 0err_nohighmem   db 'Not enough memory to load specified kernel.', CR, LF, 0err_highload    db CR, LF, 'Kernel transfer failure.', CR, LF, 0err_oldkernel   db 'Cannot load a ramdisk with an old kernel image.'                db CR, LF, 0err_notdos	db ': attempted DOS system call', CR, LF, 0err_comlarge	db 'COMBOOT image too large.', CR, LF, 0err_bssimage	db 'BSS images not supported.', CR, LF, 0err_a20		db CR, LF, 'A20 gate not responding!', CR, LF, 0err_bootfailed	db CR, LF, 'Boot failed: please change disks and press '		db 'a key to continue.', CR, LF, 0ready_msg	db 'Ready.', CR, LF, 0crlfloading_msg	db CR, LFloading_msg     db 'Loading ', 0dotdot_msg      db '.'dot_msg         db '.', 0aborted_msg	db ' aborted.'			; Fall through to crlf_msg!crlf_msg	db CR, LFnull_msg	db 0crff_msg	db CR, FF, 0ConfigName	db 'extlinux.conf',0		; Unmangled form;; Command line options we'd like to take a look at;; mem= and vga= are handled as normal 32-bit integer valuesinitrd_cmd	db 'initrd='initrd_cmd_len	equ 7;; Config file keyword table;%include "keywords.inc";; Extensions to search for (in *forward* order).;		align 4, db 0exten_table:	db '.cbt'		; COMBOOT (specific)		db '.img'		; Disk image		db '.bs', 0		; Boot sector		db '.com'		; COMBOOT (same as DOS)		db '.c32'		; COM32exten_table_end:		dd 0, 0			; Need 8 null bytes here;; Misc initialized (data) variables;%ifdef debug				; This code for debugging onlydebug_magic	dw 0D00Dh		; Debug code sentinel%endif		alignb 4, db 0BufSafe		dw trackbufsize/SECTOR_SIZE	; Clusters we can load into trackbufBufSafeSec	dw trackbufsize/SECTOR_SIZE	; = how many sectors?BufSafeBytes	dw trackbufsize		; = how many bytes?EndOfGetCBuf	dw getcbuf+trackbufsize	; = getcbuf+BufSafeBytes%ifndef DEPEND%if ( trackbufsize % SECTOR_SIZE ) != 0%error trackbufsize must be a multiple of SECTOR_SIZE%endif%endif

⌨️ 快捷键说明

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