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

📄 ldlinux.asm

📁 linux内核
💻 ASM
📖 第 1 页 / 共 3 页
字号:
		ret.error:		dec bp		jnz .retry		xchg ax,bp		; Sectors transferred <- 0		shr word [MaxTransfer],1		jnz .resume		; Fall through to disk_error	;; kaboom: write a message and bail out.;disk_error:kaboom:		xor si,si		mov ss,si				mov sp,StackBuf-4 	; Reset stack		mov ds,si		; Reset data segment		pop dword [fdctab]	; Restore FDC table.patch:					; When we have full code, intercept here		mov si,bailmsg		; Write error message, this assumes screen page 0.loop:		lodsb		and al,al                jz .done		mov ah,0Eh		; Write to screen as TTY		mov bx,0007h		; Attribute		int 10h		jmp short .loop.done:		cbw			; AH <- 0		int 16h			; Wait for keypress		int 19h			; And try once more to boot....norge:		jmp short .norge	; If int 19h returned; this is the end;; 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%if IS_MDSLINUX		db 'MDSLINUX '%else		db 'SYSLINUX '%endif		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]; 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 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;; Compute some information about this filesystem.;; First, generate the map of regionsgenfatinfo:		mov edx,[bxSectors]		and dx,dx		jnz .have_secs		mov edx,[bsHugeSectors].have_secs:		mov [TotalSectors],edx		add edx,eax		mov [EndSector],edx		mov eax,[bxResSectors]		mov [FAT],eax			; Beginning of FAT		mov edx,[bxFATsecs]		and dx,dx		jnz .have_fatsecs		mov edx,[bootsec+36]		; FAT32 BPB_FATsz32.have_fatsecs:		imul edx,[bxFATs]		add eax,edx		mov [RootDirArea],eax		; Beginning of root directory		mov [RootDir],eax		; For FAT12/16 == root dir location		mov edx,[bxRootDirEnts]		add dx,SECTOR_SIZE/32-1		shr dx,SECTOR_SHIFT-5		mov [RootDirSize],edx		add eax,edx		mov [DataArea],eax		; Beginning of data area; Next, generate a cluster size shift count and mask		mov eax,[bxSecPerClust]		bsr cx,ax		mov [ClustShift],cl		push cx		add cl,9		mov [ClustByteShift],cl		pop cx		dec ax		mov [ClustMask],eax		inc ax		shl eax,9		mov [ClustSize],eax;; FAT12, FAT16 or FAT28^H^H32?  This computation is fscking ridiculous.;getfattype:		mov eax,[EndSector]		sub eax,[DataArea]		shr eax,cl			; cl == ClustShift		mov cl,nextcluster_fat12-(nextcluster+2)		cmp eax,4085			; FAT12 limit		jb .setsize		mov cl,nextcluster_fat16-(nextcluster+2)		cmp eax,65525			; FAT16 limit		jb .setsize		;		; FAT32, root directory is a cluster chain		;		mov cl,[ClustShift]		mov eax,[bootsec+44]		; Root directory cluster		sub eax,2		shl eax,cl		add eax,[DataArea]		mov [RootDir],eax		mov cl,nextcluster_fat28-(nextcluster+2).setsize:		mov byte [nextcluster+1],cl;; Common initialization code;%include "cpuinit.inc"%include "init.inc";; Clear Files structures;		mov di,Files		mov cx,(MAX_OPEN*open_file_t_size)/4		xor eax,eax		rep stosd;; 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;		mov di,syslinux_cfg		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";; 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;; 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	= file length in bytes;	     If unsuccessful;		ZF set;searchdir:		push bx		call allocate_file		jnz .alloc_failure		push cx		push gs		push es		push ds		pop es				; ES = DS		mov eax,[RootDir]		; First root directory sector.scansector:		call getcachesector		; GS:SI now points to this sector		mov cx,SECTOR_SIZE/32		; 32 == directory entry size.scanentry:		cmp byte [gs:si],0		jz .failure			; Hit directory high water mark		push cx		push si		push di		mov cx,11		gs repe cmpsb		pop di		pop si		pop cx		jz .found		add si,32		loop .scanentry		call nextsector		jnc .scansector			; CF is set if we're at end		; If we get here, we failed.failure:		pop es		pop gs		pop cx.alloc_failure:		pop bx		xor eax,eax			; ZF <- 1		ret.found:		mov eax,[gs:si+28]		; File size		add eax,SECTOR_SIZE-1		shr eax,SECTOR_SHIFT		jz .failure			; Zero-length file		mov [bx+4],eax

⌨️ 快捷键说明

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