📄 isolinux.asm
字号:
xor al,al mov cx,256mkkeymap: stosb inc al loop mkkeymap;; Now, we need to sniff out the actual filesystem data structures.; mkisofs gave us a pointer to the primary volume descriptor; (which will be at 16 only for a single-session disk!); from the PVD; we should be able to find the rest of what we need to know.; get_fs_structures: mov eax,[bi_pvd] mov bx,trackbuf call getonesec mov eax,[trackbuf+156+2] mov [RootDir+dir_lba],eax mov [CurDir+dir_lba],eax%ifdef DEBUG_MESSAGES mov si,dbg_rootdir_msg call writemsg call writehex8 call crlf%endif mov eax,[trackbuf+156+10] mov [RootDir+dir_len],eax mov [CurDir+dir_len],eax add eax,SECTORSIZE-1 shr eax,SECTORSIZE_LG2 mov [RootDir+dir_clust],eax mov [CurDir+dir_clust],eax ; Look for an isolinux directory, and if found, ; make it the current directory instead of the root ; directory. mov di,boot_dir ; Search for /boot/isolinux mov al,02h call searchdir_iso jnz .found_dir mov di,isolinux_dir mov al,02h ; Search for /isolinux call searchdir_iso jz .no_isolinux_dir.found_dir: mov [CurDir+dir_len],eax mov eax,[si+file_left] mov [CurDir+dir_clust],eax xor eax,eax ; Free this file pointer entry xchg eax,[si+file_sector] mov [CurDir+dir_lba],eax%ifdef DEBUG_MESSAGES push si mov si,dbg_isodir_msg call writemsg pop si call writehex8 call crlf%endif.no_isolinux_dir:;; Locate the configuration file;load_config:%ifdef DEBUG_MESSAGES mov si,dbg_config_msg call writemsg%endif mov di,isolinux_cfg call open jz no_config_file ; Not found or empty%ifdef DEBUG_MESSAGES mov si,dbg_configok_msg call writemsg%endif;; 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";; Enable disk emulation. The kind of disk we emulate is dependent on the size of; the file: 1200K, 1440K or 2880K floppy, otherwise harddisk.;is_disk_image: TRACER CR TRACER LF TRACER 'D' TRACER ':' shl edx,16 mov dx,ax ; Set EDX <- file size mov di,img_table mov cx,img_table_count mov eax,[si+file_sector] ; Starting LBA of file mov [dsp_lba],eax ; Location of file mov byte [dsp_drive], 0 ; 00h floppy, 80h hard disk.search_table: TRACER 't' mov eax,[di+4] cmp edx,[di] je .type_found add di,8 loop .search_table ; Hard disk image. Need to examine the partition table ; in order to deduce the C/H/S geometry. Sigh..hard_disk_image: TRACER 'h' cmp edx,512 jb .bad_image mov bx,trackbuf mov cx,1 ; Load 1 sector call getfssec cmp word [trackbuf+510],0aa55h ; Boot signature jne .bad_image ; Image not bootable mov cx,4 ; 4 partition entries mov di,trackbuf+446 ; Start of partition table xor ax,ax ; Highest sector(al) head(ah).part_scan: cmp byte [di+4], 0 jz .part_loop lea si,[di+1] call .hs_check add si,byte 4 call .hs_check.part_loop: add di,byte 16 loop .part_scan push eax ; H/S push edx ; File size mov bl,ah xor bh,bh inc bx ; # of heads in BX xor ah,ah ; # of sectors in AX cwde ; EAX[31:16] <- 0 mul bx shl eax,9 ; Convert to bytes ; Now eax contains the number of bytes per cylinder pop ebx ; File size xor edx,edx div ebx and edx,edx jz .no_remainder inc eax ; Fractional cylinder... ; Now (e)ax contains the number of cylinders.no_remainder: cmp eax,1024 jna .ok_cyl mov ax,1024 ; Max possible #.ok_cyl: dec ax ; Convert to max cylinder no pop ebx ; S(bl) H(bh) shl ah,6 or bl,ah xchg ax,bx shl eax,16 mov ah,bl mov al,4 ; Hard disk boot mov byte [dsp_drive], 80h ; Drive 80h = hard disk.type_found: TRACER 'T' mov bl,[sp_media] and bl,0F0h ; Copy controller info bits or al,bl mov [dsp_media],al ; Emulation type shr eax,8 mov [dsp_chs],eax ; C/H/S geometry mov ax,[sp_devspec] ; Copy device spec mov [dsp_devspec],ax mov al,[sp_controller] ; Copy controller index mov [dsp_controller],al TRACER 'V' call vgaclearmode ; Reset video mov ax,4C00h ; Enable emulation and boot mov si,dspec_packet mov dl,[DriveNo] lss sp,[InitStack] TRACER 'X' int 13h ; If this returns, we have problems.bad_image: mov si,err_disk_image call cwritestr jmp enter_command;; Look for the highest seen H/S geometry; We compute cylinders separately;.hs_check: mov bl,[si] ; Head # cmp bl,ah jna .done_track mov ah,bl ; New highest head #.done_track: mov bl,[si+1] and bl,3Fh ; Sector # cmp bl,al jna .done_sector mov al,bl.done_sector: ret;; Boot a specified local disk. AX specifies the BIOS disk number; or; 0xFFFF in case we should execute INT 18h ("next device.");local_boot: call vgaclearmode lss sp,[cs:Stack] ; Restore stack pointer xor dx,dx mov ds,dx mov es,dx mov fs,dx mov gs,dx mov si,localboot_msg call writestr cmp ax,-1 je .int18 ; Load boot sector from the specified BIOS device and jump to it. mov dl,al xor dh,dh push dx xor ax,ax ; Reset drive call xint13 mov ax,0201h ; Read one sector mov cx,0001h ; C/H/S = 0/0/1 (first sector) mov bx,trackbuf call xint13 pop dx cli ; Abandon hope, ye who enter here mov si,trackbuf mov di,07C00h mov cx,512 ; Probably overkill, but should be safe rep movsd lss sp,[cs:InitStack] jmp 0:07C00h ; Jump to new boot sector.int18: int 18h ; Hope this does the right thing... jmp kaboom ; If we returned, oh boy...;; abort_check: let the user abort with <ESC> or <Ctrl-C>;abort_check: call pollchar jz ac_ret1 pusha call getchar cmp al,27 ; <ESC> je ac_kill cmp al,3 ; <Ctrl-C> jne ac_ret2ac_kill: mov si,aborted_msg;; abort_load: Called by various routines which wants to print a fatal; error message and return to the command prompt. Since this; may happen at just about any stage of the boot process, assume; our state is messed up, and just reset the segment registers; and the stack forcibly.;; SI = offset (in _text) of error message to print;abort_load: mov ax,cs ; Restore CS = DS = ES mov ds,ax mov es,ax cli lss sp,[cs:Stack] ; Reset the stack sti call cwritestr ; Expects SI -> error msgal_ok: jmp enter_command ; Return to command prompt;; End of abort_check;ac_ret2: popaac_ret1: ret;; searchdir:;; Open a file;; On entry:; DS:DI = filename; If successful:; ZF clear; SI = file pointer; DX:AX or EAX = file length in bytes; If unsuccessful; ZF set;;; searchdir_iso is a special entry point for ISOLINUX only. In addition; to the above, searchdir_iso passes a file flag mask in AL. This is useful; for searching for directories.;alloc_failure: xor ax,ax ; ZF <- 1 retsearchdir: xor al,alsearchdir_iso: mov [ISOFlags],al TRACER 'S' call allocate_file ; Temporary file structure for directory jnz alloc_failure push es push ds pop es ; ES = DS mov si,CurDir cmp byte [di],'/' ; If filename begins with slash jne .not_rooted inc di ; Skip leading slash mov si,RootDir ; Reference root directory instead.not_rooted: mov eax,[si+dir_clust] mov [bx+file_left],eax mov eax,[si+dir_lba] mov [bx+file_sector],eax mov edx,[si+dir_len].look_for_slash: mov ax,di.scan: mov cl,[di] inc di and cl,cl jz .isfile cmp cl,'/' jne .scan mov [di-1],byte 0 ; Terminate at directory name mov cl,02h ; Search for directory xchg cl,[ISOFlags] push di ; Save these... push cx ; Create recursion stack frame... push word .resume ; Where to "return" to push es.isfile: xchg ax,di.getsome: ; Get a chunk of the directory ; This relies on the fact that ISOLINUX doesn't change SI mov si,trackbuf TRACER 'g' pushad xchg bx,si mov cx,[BufSafe] call getfssec popad.compare: movzx eax,byte [si] ; Length of directory entry cmp al,33 jb .next_sector TRACER 'c' mov cl,[si+25] xor cl,[ISOFlags] test cl, byte 8Eh ; Unwanted file attributes! jnz .not_file pusha movzx cx,byte [si+32] ; File identifier length add si,byte 33 ; File identifier offset TRACER 'i' call iso_compare_names popa je .success.not_file: sub edx,eax ; Decrease bytes left jbe .failure add si,ax ; Advance pointer.check_overrun: ; Did we finish the buffer? cmp si,trackbuf+trackbufsize jb .compare ; No, keep going jmp short .getsome ; Get some more directory.next_sector: ; Advance to the beginning of next sector lea ax,[si+SECTORSIZE-1] and ax,~(SECTORSIZE-1) sub ax,si jmp short .not_file ; We still need to do length checks.failure: xor eax,eax ; ZF = 1 mov [bx+file_sector],eax pop es ret.success: mov eax,[si+2] ; Location of extent mov [bx+file_sector],eax mov eax,[si+10] ; Data length push eax add eax,SECTORSIZE-1 shr eax,SECTORSIZE_LG2 mov [bx+file_left],eax pop eax mov edx,eax shr edx,16 and bx,bx ; ZF = 0 mov si,bx pop es ret.resume: ; We get here if we were only doing part of a lookup ; This relies on the fact that .success returns bx == si xchg edx,eax ; Directory length in edx pop cx ; Old ISOFlags pop di ; Next filename pointer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -