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

📄 isolinux.asm

📁 linux内核
💻 ASM
📖 第 1 页 / 共 3 页
字号:
; -*- fundamental -*- (asm-mode sucks); $Id$; ****************************************************************************;;  isolinux.asm;;  A program to boot Linux kernels off a CD-ROM using the El Torito;  boot standard in "no emulation" mode, making the entire filesystem;  available.  It is based on the SYSLINUX boot loader for MS-DOS;  floppies.;;   Copyright (C) 1994-2005  H. Peter Anvin;;  This program is free software; you can redistribute it and/or modify;  it under the terms of the GNU General Public License as published by;  the Free Software Foundation, Inc., 53 Temple Place Ste 330,;  Boston MA 02111-1307, USA; either version 2 of the License, or;  (at your option) any later version; incorporated herein by reference.;; ****************************************************************************%define IS_ISOLINUX 1%include "macros.inc"%include "config.inc"%include "kernel.inc"%include "bios.inc"%include "tracers.inc"%include "layout.inc";; Some semi-configurable constants... change on your own risk.;my_id		equ isolinux_idFILENAME_MAX_LG2 equ 8			; log2(Max filename size Including final null)FILENAME_MAX	equ (1 << FILENAME_MAX_LG2)NULLFILE	equ 0			; Zero byte == null file nameNULLOFFSET	equ 0			; Position in which to lookretry_count	equ 6			; How patient are we with the BIOS?%assign HIGHMEM_SLOP 128*1024		; Avoid this much memory near the topMAX_OPEN_LG2	equ 6			; log2(Max number of open files)MAX_OPEN	equ (1 << MAX_OPEN_LG2)SECTOR_SHIFT	equ 11			; 2048 bytes/sector (El Torito requirement)SECTOR_SIZE	equ (1 << SECTOR_SHIFT);; This is what we need to do when idle;%macro	RESET_IDLE 0	; Nothing%endmacro%macro	DO_IDLE 0	; Nothing%endmacro;; The following structure is used for "virtual kernels"; i.e. LILO-style; option labels.  The options we permit here are `kernel' and `append; Since there is no room in the bottom 64K for all of these, we; stick them at vk_seg:0000 and copy them down before we need them.;		struc vkernelvk_vname:	resb FILENAME_MAX	; Virtual name **MUST BE FIRST!**vk_rname:	resb FILENAME_MAX	; Real namevk_appendlen:	resw 1		alignb 4vk_append:	resb max_cmd_len+1	; Command line		alignb 4vk_end:		equ $			; Should be <= vk_size		endstruc;; Segment assignments in the bottom 640K; 0000h - main code/data segment (and BIOS segment);real_mode_seg	equ 3000hvk_seg          equ 2000h		; Virtual kernelsxfer_buf_seg	equ 1000h		; Bounce buffer for I/O to high memcomboot_seg	equ real_mode_seg	; COMBOOT image loading zone;; File structure.  This holds the information for each currently open file.;		struc open_file_tfile_sector	resd 1			; Sector pointer (0 = structure free)file_left	resd 1			; Number of sectors left		endstruc%ifndef DEPEND%if (open_file_t_size & (open_file_t_size-1))%error "open_file_t is not a power of 2"%endif%endif		struc dir_tdir_lba		resd 1			; Directory start (LBA)dir_len		resd 1			; Length in bytesdir_clust	resd 1			; Length in clusters		endstruc; ---------------------------------------------------------------------------;   BEGIN CODE; ---------------------------------------------------------------------------;; Memory below this point is reserved for the BIOS and the MBR;		section .earlybsstrackbufsize	equ 8192trackbuf	resb trackbufsize	; Track buffer goes heregetcbuf		resb trackbufsize;		ends at 4800h		section .bss		alignb 4ISOFileName	resb 64			; ISO filename canonicalization bufferISOFileNameEnd	equ $CurDir		resb dir_t_size		; Current directoryRootDir		resb dir_t_size		; Root directoryFirstSecSum	resd 1			; Checksum of bytes 64-2048ImageDwords	resd 1			; isolinux.bin size, dwordsInitStack	resd 1			; Initial stack pointer (SS:SP)DiskSys		resw 1			; Last INT 13h callImageSectors	resw 1			; isolinux.bin size, sectorsDiskError	resb 1			; Error code for disk I/ODriveNo		resb 1			; CD-ROM BIOS drive numberISOFlags	resb 1			; Flags for ISO directory searchRetryCount      resb 1			; Used for disk access retries_spec_start	equ $;; El Torito spec packet;		alignb 8spec_packet:	resb 1				; Size of packetsp_media:	resb 1				; Media typesp_drive:	resb 1				; Drive numbersp_controller:	resb 1				; Controller indexsp_lba:		resd 1				; LBA for emulated disk imagesp_devspec:	resw 1				; IDE/SCSI informationsp_buffer:	resw 1				; User-provided buffersp_loadseg:	resw 1				; Load segmentsp_sectors:	resw 1				; Sector countsp_chs:		resb 3  			; Simulated CHS geometrysp_dummy:	resb 1				; Scratch, safe to overwrite;; EBIOS drive parameter packet;		alignb 8drive_params:	resw 1				; Buffer sizedp_flags:	resw 1				; Information flagsdp_cyl:		resd 1				; Physical cylindersdp_head:	resd 1				; Physical headsdp_sec:		resd 1				; Physical sectors/trackdp_totalsec:	resd 2				; Total sectorsdp_secsize:	resw 1				; Bytes per sectordp_dpte:	resd 1				; Device Parameter Tabledp_dpi_key:	resw 1				; 0BEDDh if rest validdp_dpi_len:	resb 1				; DPI len		resb 1		resw 1dp_bus:		resb 4				; Host bus typedp_interface:	resb 8				; Interface typedb_i_path:	resd 2				; Interface pathdb_d_path:	resd 2				; Device path		resb 1db_dpi_csum:	resb 1				; Checksum for DPI info;; EBIOS disk address packet;		alignb 8dapa:		resw 1				; Packet size.count:		resw 1				; Block count.off:		resw 1				; Offset of buffer.seg:		resw 1				; Segment of buffer.lba:		resd 2				; LBA (LSW, MSW);; Spec packet for disk image emulation;		alignb 8dspec_packet:	resb 1				; Size of packetdsp_media:	resb 1				; Media typedsp_drive:	resb 1				; Drive numberdsp_controller:	resb 1				; Controller indexdsp_lba:	resd 1				; LBA for emulated disk imagedsp_devspec:	resw 1				; IDE/SCSI informationdsp_buffer:	resw 1				; User-provided bufferdsp_loadseg:	resw 1				; Load segmentdsp_sectors:	resw 1				; Sector countdsp_chs:	resb 3				; Simulated CHS geometrydsp_dummy:	resb 1				; Scratch, safe to overwrite		alignb 4_spec_end	equ $_spec_len	equ _spec_end - _spec_start		alignb open_file_t_sizeFiles		resb MAX_OPEN*open_file_t_size;; Constants for the xfer_buf_seg;; The xfer_buf_seg is also used to store message file buffers.  We; need two trackbuffers (text and graphics), plus a work buffer; for the graphics decompressor.;xbs_textbuf	equ 0			; Also hard-coded, do not changexbs_vgabuf	equ trackbufsizexbs_vgatmpbuf	equ 2*trackbufsize		section .text;;;; Primary entry point.  Because BIOSes are buggy, we only load the first;; CD-ROM sector (2K) of the file, so the number one priority is actually;; loading the rest.;;StackBuf	equ $bootsec		equ $_start:		; Far jump makes sure we canonicalize the address		cli		jmp 0:_start1		times 8-($-$$) nop		; Pad to file offset 8		; This table hopefully gets filled in by mkisofs using the		; -boot-info-table option.  If not, the values in this		; table are default values that we can use to get us what		; we need, at least under a certain set of assumptions.bi_pvd:		dd 16				; LBA of primary volume descriptorbi_file:	dd 0				; LBA of boot filebi_length:	dd 0xdeadbeef			; Length of boot filebi_csum:	dd 0xdeadbeef			; Checksum of boot filebi_reserved:	times 10 dd 0xdeadbeef		; Reserved_start1:	mov [cs:InitStack],sp		; Save initial stack pointer		mov [cs:InitStack+2],ss		xor ax,ax		mov ss,ax		mov sp,StackBuf			; Set up stack		mov ds,ax		mov es,ax		mov fs,ax		mov gs,ax		sti		cld		; Show signs of life		mov si,syslinux_banner		call writestr%ifdef DEBUG_MESSAGES		mov si,copyright_str		call writestr%endif		;		; Before modifying any memory, get the checksum of bytes		; 64-2048		;initial_csum:	xor edi,edi		mov si,_start1		mov cx,(SECTOR_SIZE-64) >> 2.loop:		lodsd		add edi,eax		loop .loop		mov [FirstSecSum],edi		mov [DriveNo],dl%ifdef DEBUG_MESSAGES		mov si,startup_msg		call writemsg		mov al,dl		call writehex2		call crlf%endif		;		; Initialize spec packet buffers		;		mov di,_spec_start		mov cx,_spec_len >> 2		xor eax,eax		rep stosd		; Initialize length field of the various packets		mov byte [spec_packet],13h		mov byte [drive_params],30		mov byte [dapa],16		mov byte [dspec_packet],13h		; Other nonzero fields		inc word [dsp_sectors]		; Now figure out what we're actually doing		; Note: use passed-in DL value rather than 7Fh because		; at least some BIOSes will get the wrong value otherwise		mov ax,4B01h			; Get disk emulation status		mov dl,[DriveNo]		mov si,spec_packet		int 13h		jc award_hack			; changed for BrokenAwardHack		mov dl,[DriveNo]		cmp [sp_drive],dl		; Should contain the drive number		jne spec_query_failed%ifdef DEBUG_MESSAGES		mov si,spec_ok_msg		call writemsg		mov al,byte [sp_drive]		call writehex2		call crlf%endiffound_drive:		; Alright, we have found the drive.  Now, try to find the		; boot file itself.  If we have a boot info table, life is		; good; if not, we have to make some assumptions, and try		; to figure things out ourselves.  In particular, the		; assumptions we have to make are:		; - single session only		; - only one boot entry (no menu or other alternatives)		cmp dword [bi_file],0		; Address of code to load		jne found_file			; Boot info table present :)%ifdef DEBUG_MESSAGES		mov si,noinfotable_msg		call writemsg%endif				; No such luck.  See if the the spec packet contained one.		mov eax,[sp_lba]		and eax,eax		jz set_file			; Good enough%ifdef DEBUG_MESSAGES		mov si,noinfoinspec_msg		call writemsg%endif				; No such luck.  Get the Boot Record Volume, assuming single		; session disk, and that we're the first entry in the chain		mov eax,17			; Assumed address of BRV		mov bx,trackbuf		call getonesec		mov eax,[trackbuf+47h]		; Get boot catalog address		mov bx,trackbuf		call getonesec			; Get boot catalog		mov eax,[trackbuf+28h]		; First boot entry		; And hope and pray this is us...		; Some BIOSes apparently have limitations on the size 		; that may be loaded (despite the El Torito spec being very		; clear on the fact that it must all be loaded.)  Therefore,		; we load it ourselves, and *bleep* the BIOS.set_file:		mov [bi_file],eaxfound_file:		; Set up boot file sizes		mov eax,[bi_length]		sub eax,SECTOR_SIZE-3		shr eax,2			; bytes->dwords		mov [ImageDwords],eax		; boot file dwords		add eax,(2047 >> 2)		shr eax,9			; dwords->sectors		mov [ImageSectors],ax		; boot file sectors		mov eax,[bi_file]		; Address of code to load		inc eax				; Don't reload bootstrap code%ifdef DEBUG_MESSAGES		mov si,offset_msg		call writemsg		call writehex8		call crlf%endif		; Just in case some BIOSes have problems with		; segment wraparound, use the normalized address		mov bx,((7C00h+2048) >> 4)		mov es,bx		xor bx,bx		mov bp,[ImageSectors]%ifdef DEBUG_MESSAGES		push ax		mov si,size_msg		call writemsg		mov ax,bp		call writehex4		call crlf		pop ax%endif		call getlinsec		push ds		pop es%ifdef DEBUG_MESSAGES		mov si,loaded_msg		call writemsg%endif		; Verify the checksum on the loaded image.verify_image:		mov si,7C00h+2048		mov bx,es		mov ecx,[ImageDwords]		mov edi,[FirstSecSum]		; First sector checksum.loop		es lodsd		add edi,eax		dec ecx		jz .done		and si,si		jnz .loop		; SI wrapped around, advance ES		add bx,1000h		mov es,bx		jmp short .loop.done:		mov ax,ds		mov es,ax		cmp [bi_csum],edi		je integrity_ok		mov si,checkerr_msg		call writemsg		jmp kaboomintegrity_ok:%ifdef DEBUG_MESSAGES		mov si,allread_msg		call writemsg%endif		jmp all_read			; Jump to main code;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Start of BrokenAwardHack --- 10-nov-2002           Knut_Petersen@t-online.de;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; There is a problem with certain versions of the AWARD BIOS ... ;; the boot sector will be loaded and executed correctly, but, because the;; int 13 vector points to the wrong code in the BIOS, every attempt to;; load the spec packet will fail. We scan for the equivalent of;;;;	mov	ax,0201h;;	mov	bx,7c00h;;	mov	cx,0006h;;	mov	dx,0180h;;	pushf;;	call	<direct far>;;;; and use <direct far> as the new vector for int 13. The code above is;; used to load the boot code into ram, and there should be no reason;; for anybody to change it now or in the future. There are no opcodes;; that use encodings relativ to IP, so scanning is easy. If we find the;; code above in the BIOS code we can be pretty sure to run on a machine;; with an broken AWARD BIOS ... ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;									     ;;%ifdef DEBUG_MESSAGES							     ;;									     ;;award_notice	db	"Trying BrokenAwardHack first ...",CR,LF,0	     ;;award_not_orig	db	"BAH: Original Int 13 vector   : ",0		     ;;award_not_new	db	"BAH: Int 13 vector changed to : ",0		     ;;award_not_succ	db	"BAH: SUCCESS",CR,LF,0				     ;;award_not_fail	db	"BAH: FAILURE"					     ;;award_not_crlf	db	CR,LF,0						     ;;									     ;;%endif									     ;;									     ;;award_oldint13	dd	0						     ;;award_string	db	0b8h,1,2,0bbh,0,7ch,0b9h,6,0,0bah,80h,1,09ch,09ah    ;;									     ;;						;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;award_hack:	mov 	si,spec_err_msg		; Moved to this place from		call 	writemsg		; spec_query_faild						;%ifdef DEBUG_MESSAGES				;						;		mov	si,award_notice		; display our plan		call	writemsg		;		mov	si,award_not_orig	; display original int 13		call	writemsg		; vector%endif						;		mov	eax,[13h*4]		;		mov	[award_oldint13],eax	;						;%ifdef DEBUG_MESSAGES				;						;		call	writehex8		;		mov	si,award_not_crlf	; 		call	writestr		;%endif						;		push	es			; save ES		mov 	ax,0f000h		; ES = BIOS Seg		mov 	es,ax			;	    	cld				;		xor 	di,di			; start at ES:DI = f000:0award_loop:	push 	di			; save DI		mov 	si,award_string		; scan for award_string		mov	cx,7			; length of award_string = 7dw		repz 	cmpsw			; compare		pop 	di			; restore DI		jcxz 	award_found		; jmp if found		inc 	di			; not found, inc di		jno	award_loop		; 						;award_failed:	pop	es			; No, not this way :-((award_fail2:					;						;%ifdef DEBUG_MESSAGES				;						;		mov	si,award_not_fail	; display failure ...		call	writemsg		;%endif						;		mov	eax,[award_oldint13]	; restore the original int		or	eax,eax			; 13 vector if there is one		jz	spec_query_failed	; and try other workarounds		mov	[13h*4],eax		;		jmp	spec_query_failed	;						;award_found:	mov	eax,[es:di+0eh]		; load possible int 13 addr		pop	es			; restore ES						;		cmp	eax,[award_oldint13]	; give up if this is the		jz	award_failed		; active int 13 vector,		mov	[13h*4],eax		; otherwise change 0:13h*4						;						;%ifdef DEBUG_MESSAGES				;						;		push	eax			; display message and 		mov	si,award_not_new	; new vector address		call	writemsg		;		pop	eax			;

⌨️ 快捷键说明

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