📄 isolinux.asm
字号:
mov byte [di-1], '/' ; Restore slash mov [ISOFlags],cl ; Restore the flags jz .failure ; Did we fail? If so fail for real! jmp .look_for_slash ; Otherwise, next level;; 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;; iso_compare_names: ; Compare the names DS:SI and DS:DI and report if they are; equal from an ISO 9660 perspective. SI is the name from; the filesystem; CX indicates its length, and ';' terminates.; DI is expected to end with a null.;; Note: clobbers AX, CX, SI, DI; assumes DS == ES == base segment;iso_compare_names: ; First, terminate and canonicalize input filename push di mov di,ISOFileName.canon_loop: jcxz .canon_end lodsb dec cx cmp al,';' je .canon_end and al,al je .canon_end stosb cmp di,ISOFileNameEnd-1 ; Guard against buffer overrun jb .canon_loop.canon_end: cmp di,ISOFileName jbe .canon_done cmp byte [di-1],'.' ; Remove terminal dots jne .canon_done dec di jmp short .canon_end.canon_done: mov [di],byte 0 ; Null-terminate string pop di mov si,ISOFileName.compare: lodsb mov ah,[di] inc di and ax,ax jz .success ; End of string for both and al,al ; Is either one end of string? jz .failure ; If so, failure and ah,ah jz .failure or ax,2020h ; Convert to lower case cmp al,ah je .compare.failure: and ax,ax ; ZF = 0 (at least one will be nonzero).success: ret;; strcpy: Copy DS:SI -> ES:DI up to and including a null byte;strcpy: push ax.loop: lodsb stosb and al,al jnz .loop pop ax ret;; writechr: Write a single character in AL to the console without; mangling any registers. This does raw console writes,; since some PXE BIOSes seem to interfere regular console I/O.;writechr_full: push ds push cs pop ds call write_serial ; write to serial port if needed pushfd pushad mov bh,[BIOS_page] push ax mov ah,03h ; Read cursor position int 10h pop ax cmp al,8 je .bs cmp al,13 je .cr cmp al,10 je .lf push dx mov bh,[BIOS_page] mov bl,07h ; White on black mov cx,1 ; One only mov ah,09h ; Write char and attribute int 10h pop dx inc dl cmp dl,[VidCols] jna .curxyok xor dl,dl.lf: inc dh cmp dh,[VidRows] ja .scroll.curxyok: mov bh,[BIOS_page] mov ah,02h ; Set cursor position int 10h .ret: popad popfd pop ds ret.scroll: dec dh mov bh,[BIOS_page] mov ah,02h int 10h mov ax,0601h ; Scroll up one line mov bh,[ScrollAttribute] xor cx,cx mov dx,[ScreenSize] ; The whole screen int 10h jmp short .ret.cr: xor dl,dl jmp short .curxyok.bs: sub dl,1 jnc .curxyok mov dl,[VidCols] sub dh,1 jnc .curxyok xor dh,dh jmp short .curxyok;; 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 trailing dots and redundant slashes,; so "repe cmpsb" can do a compare, and the; path-searching routine gets a bit of an easier job.; 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 dot? je .mn_kill 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;; getfssec: Get multiple clusters from a file, given the file pointer.;; On entry:; ES:BX -> Buffer; SI -> File pointer; CX -> Cluster count; On exit:; SI -> File pointer (or 0 on EOF); CF = 1 -> Hit EOF;getfssec: TRACER 'F' push ds push cs pop ds ; DS <- CS movzx ecx,cx cmp ecx,[si+file_left] jna .ok_size mov ecx,[si+file_left].ok_size: mov bp,cx push cx push si mov eax,[si+file_sector] TRACER 'l' call getlinsec xor ecx,ecx pop si pop cx add [si+file_sector],ecx sub [si+file_left],ecx ja .not_eof ; CF = 0 xor ecx,ecx mov [si+file_sector],ecx ; Mark as unused xor si,si stc.not_eof: pop ds TRACER 'f' ret; -----------------------------------------------------------------------------; Common modules; -----------------------------------------------------------------------------%include "getc.inc" ; getc et al%include "conio.inc" ; Console I/O%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; -----------------------------------------------------------------------------; Begin data section; -----------------------------------------------------------------------------CR equ 13 ; Carriage ReturnLF equ 10 ; Line FeedFF equ 12 ; Form FeedBS equ 8 ; Backspaceboot_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 config file.', CR, LF, 0err_noparm db 'Missing parameter in config file.', 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, 0notfound_msg db 'not found', CR, LF, 0localboot_msg db 'Booting from local disk...', CR, LF, 0cmdline_msg db 'Command line: ', CR, LF, 0ready_msg db 'Ready.', CR, LF, 0trying_msg db 'Trying to load: ', 0crlfloading_msg db CR, LF ; Fall throughloading_msg db 'Loading ', 0dotdot_msg db '.'dot_msg db '.', 0fourbs_msg db BS, BS, BS, BS, 0aborted_msg db ' aborted.', CR, LF, 0crff_msg db CR, FF, 0default_str db 'default', 0default_len equ ($-default_str)boot_dir db '/boot' ; /boot/isolinuxisolinux_dir db '/isolinux', 0isolinux_cfg db 'isolinux.cfg', 0err_disk_image db 'Cannot load disk image (invalid file)?', CR, LF, 0%ifdef DEBUG_MESSAGESdbg_rootdir_msg db 'Root directory at LBA = ', 0dbg_isodir_msg db 'isolinux directory at LBA = ', 0dbg_config_msg db 'About to load config file...', CR, LF, 0dbg_configok_msg db 'Configuration file opened...', CR, LF, 0%endif;; 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 '.bin' ; CD boot sector db '.com' ; COMBOOT (same as DOS) db '.c32' ; COM32exten_table_end: dd 0, 0 ; Need 8 null bytes here;; Floppy image table; align 4, db 0img_table_count equ 3img_table: dd 1200*1024 ; 1200K floppy db 1 ; Emulation type db 80-1 ; Max cylinder db 15 ; Max sector db 2-1 ; Max head dd 1440*1024 ; 1440K floppy db 2 ; Emulation type db 80-1 ; Max cylinder db 18 ; Max sector db 2-1 ; Max head dd 2880*1024 ; 2880K floppy db 3 ; Emulation type db 80-1 ; Max cylinder db 36 ; Max sector db 2-1 ; Max head;; Misc initialized (data) variables;AppendLen dw 0 ; Bytes in append= commandOntimeoutLen dw 0 ; Bytes in ontimeout commandOnerrorLen dw 0 ; Bytes in onerror commandKbdTimeOut dw 0 ; Keyboard timeout (if any)CmdLinePtr dw cmd_line_here ; Command line advancing pointerinitrd_flag equ $initrd_ptr dw 0 ; Initial ramdisk pointer/flagVKernelCtr dw 0 ; Number of registered vkernelsForcePrompt dw 0 ; Force promptAllowImplicit dw 1 ; Allow implicit kernelsAllowOptions dw 1 ; User-specified options allowedSerialPort dw 0 ; Serial port base (or 0 for no serial port)VGAFontSize dw 16 ; Defaults to 16 byte fontUserFont db 0 ; Using a user-specified fontScrollAttribute db 07h ; White on black (for text mode);; Variables that are uninitialized in SYSLINUX but initialized here;; **** ISOLINUX:: We may have to make this flexible, based on what the; **** BIOS expects our "sector size" to be.; alignb 4, db 0ClustSize dd SECTORSIZE ; Bytes/clusterClustPerMoby dd 65536/SECTORSIZE ; Clusters per 64KSecPerClust dw 1 ; Same as bsSecPerClust, but a wordBufSafe dw trackbufsize/SECTORSIZE ; Clusters we can load into trackbufBufSafeSec dw trackbufsize/SECTORSIZE ; = how many sectors?BufSafeBytes dw trackbufsize ; = how many bytes?EndOfGetCBuf dw getcbuf+trackbufsize ; = getcbuf+BufSafeBytes%ifndef DEPEND%if ( trackbufsize % SECTORSIZE ) != 0%error trackbufsize must be a multiple of SECTORSIZE%endif%endif;; Stuff for the command line; we do some trickery here with equ to avoid; tons of zeros appended to our file and wasting space;linuxauto_cmd db 'linux auto',0linuxauto_len equ $-linuxauto_cmdboot_image db 'BOOT_IMAGE='boot_image_len equ $-boot_image align 4, db 0 ; For the good of REP MOVSDcommand_line equ $default_cmd equ $+(max_cmd_len+2)ldlinux_end equ default_cmd+(max_cmd_len+1)kern_cmd_len equ ldlinux_end-command_line;; Put the getcbuf right after the code, aligned on a sector boundary;end_of_code equ (ldlinux_end-bootsec)+7C00hgetcbuf equ (end_of_code + 511) & 0FE00h; VGA font buffer at the end of memory (so loading a font works even; in graphics mode.)vgafontbuf equ 0E000h; This is a compile-time assert that we didn't run out of space%ifndef DEPEND%if (getcbuf+trackbufsize) > vgafontbuf%error "Out of memory, better reorganize something..."%endif%endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -