diff options
Diffstat (limited to 'ldlinux.asm')
-rw-r--r-- | ldlinux.asm | 337 |
1 files changed, 11 insertions, 326 deletions
diff --git a/ldlinux.asm b/ldlinux.asm index d81353b5..73803308 100644 --- a/ldlinux.asm +++ b/ldlinux.asm @@ -144,6 +144,7 @@ ClustPerMoby resd 1 ; Clusters per 64K ClustSize resd 1 ; Bytes/cluster KernelName resb 12 ; Mangled name for kernel ; (note the spare byte after!) +OrigKernelExt resd 1 ; Original kernel extension FBytes equ $ ; Used by open/getc FBytes1 resw 1 FBytes2 resw 1 @@ -1028,325 +1029,12 @@ mkkeymap: stosb mov di,syslinux_cfg call open jz no_config_file -; -; Now we have the config file open -; - call parse_config ; Parse configuration file -no_config_file: -; -; Check whether or not we are supposed to display the boot prompt. -; -check_for_key: - cmp word [ForcePrompt],byte 0 ; Force prompt? - jnz enter_command - test byte [KbdFlags],5Bh ; Caps, Scroll, Shift, Alt - jz auto_boot ; If neither, default boot - -enter_command: - mov si,boot_prompt - call cwritestr - - mov byte [FuncFlag],0 ; <Ctrl-F> not pressed - mov di,command_line -; -; get the very first character -- we can either time -; out, or receive a character press at this time. Some dorky BIOSes stuff -; a return in the buffer on bootup, so wipe the keyboard buffer first. -; -clear_buffer: mov ah,1 ; Check for pending char - int 16h - jz get_char_time - xor ax,ax ; Get char - int 16h - jmp short clear_buffer -get_char_time: - call vgashowcursor - mov cx,[KbdTimeOut] - and cx,cx - jz get_char ; Timeout == 0 -> no timeout - inc cx ; The first loop will happen - ; immediately as we don't - ; know the appropriate DX value -time_loop: push cx -tick_loop: push dx - call pollchar - jnz get_char_pop - xor ax,ax - int 1Ah ; Get time "of day" - pop ax - cmp dx,ax ; Has the timer advanced? - je tick_loop - pop cx - loop time_loop ; If so, decrement counter - call vgahidecursor - jmp command_done ; Timeout! - -get_char_pop: pop eax ; Clear stack -get_char: - call vgashowcursor - call getchar - call vgahidecursor - and al,al - jz func_key - -got_ascii: cmp al,7Fh ; <DEL> == <BS> - je backspace - cmp al,' ' ; ASCII? - jb not_ascii - ja enter_char - cmp di,command_line ; Space must not be first - je get_char -enter_char: test byte [FuncFlag],1 - jz .not_ctrl_f - mov byte [FuncFlag],0 - cmp al,'0' - jb .not_ctrl_f - je ctrl_f_0 - cmp al,'9' - jbe ctrl_f -.not_ctrl_f: cmp di,max_cmd_len+command_line ; Check there's space - jnb get_char - stosb ; Save it - call writechr ; Echo to screen -get_char_2: jmp short get_char -not_ascii: mov byte [FuncFlag],0 - cmp al,0Dh ; Enter - je command_done - cmp al,06h ; <Ctrl-F> - je set_func_flag - cmp al,08h ; Backspace - jne get_char -backspace: cmp di,command_line ; Make sure there is anything - je get_char ; to erase - dec di ; Unstore one character - mov si,wipe_char ; and erase it from the screen - call cwritestr - jmp short get_char_2 - -set_func_flag: - mov byte [FuncFlag],1 - jmp short get_char_2 -ctrl_f_0: add al,10 ; <Ctrl-F>0 == F10 -ctrl_f: push di - sub al,'1' - xor ah,ah - jmp short show_help - -func_key: - ; AL = 0 if we get here - push di - cmp ah,68 ; F10 - ja get_char_2 - sub ah,59 ; F1 - jb get_char_2 - xchg al,ah -show_help: ; AX = func key # (0 = F1, 9 = F10) - shl ax,FILENAME_MAX_LG2 ; Convert to pointer - xchg di,ax - add di,FKeyName - cmp byte [di],NULLFILE - je get_char_2 ; Undefined F-key - call searchdir - jz fk_nofile - push si - call crlf - pop si - call get_msg_file - jmp short fk_wrcmd -fk_nofile: - call crlf -fk_wrcmd: - mov si,boot_prompt - call cwritestr - pop di ; Command line write pointer - push di - mov byte [di],0 ; Null-terminate command line - mov si,command_line - call cwritestr ; Write command line so far - pop di - jmp short get_char_2 -auto_boot: - mov si,default_cmd - mov di,command_line - mov cx,(max_cmd_len+4) >> 2 - rep movsd - jmp short load_kernel -command_done: - call crlf - cmp di,command_line ; Did we just hit return? - je auto_boot - xor al,al ; Store a final null - stosb - -load_kernel: ; Load the kernel now -; -; First we need to mangle the kernel name the way DOS would... -; - mov si,command_line - mov di,KernelName - push si - push di - call mangle_name - pop di - pop si -; -; Fast-forward to first option (we start over from the beginning, since -; mangle_name doesn't necessarily return a consistent ending state.) -; -clin_non_wsp: lodsb - cmp al,' ' - ja clin_non_wsp -clin_is_wsp: and al,al - jz clin_opt_ptr - lodsb - cmp al,' ' - jbe clin_is_wsp -clin_opt_ptr: dec si ; Point to first nonblank - mov [CmdOptPtr],si ; Save ptr to first option -; -; Now check if it is a "virtual kernel" ; - mov cx,[VKernelCtr] - push ds - push word vk_seg - pop ds - cmp cx,byte 0 - je not_vk - xor si,si ; Point to first vkernel -vk_check: pusha - mov cx,11 - repe cmpsb ; Is this it? - je vk_found - popa - add si,vk_size - loop vk_check -not_vk: pop ds -; -; Not a "virtual kernel" - check that's OK and construct the command line -; - cmp word [AllowImplicit],byte 0 - je bad_implicit - push es - push si - push di - mov di,real_mode_seg - mov es,di - mov si,AppendBuf - mov di,cmd_line_here - mov cx,[AppendLen] - rep movsb - mov [CmdLinePtr],di - pop di - pop si - pop es - mov bx,exten_count << 2 ; Alternates to try -; -; Find the kernel on disk -; -get_kernel: mov byte [KernelName+11],0 ; Zero-terminate filename/extension - mov eax,[KernelName+8] ; Save initial extension - mov [OrigKernelExt],eax -.search_loop: push bx - mov di,KernelName ; Search on disk - call searchdir - pop bx - jnz kernel_good - mov eax,[exten_table+bx] ; Try a different extension - mov [KernelName+8],eax - sub bx,byte 4 - jnb .search_loop -bad_kernel: - mov si,KernelName - mov di,KernelCName - push di - call unmangle_name ; Get human form - mov si,err_notfound ; Complain about missing kernel - call cwritestr - pop si ; KernelCName - call cwritestr - mov si,crlf_msg - jmp abort_load ; Ask user for clue +; Now we have the config file open. Parse the config file and +; run the user interface. ; -; bad_implicit: The user entered a nonvirtual kernel name, with "implicit 0" -; -bad_implicit: mov si,KernelName ; For the error message - mov di,KernelCName - call unmangle_name - jmp short bad_kernel -; -; vk_found: We *are* using a "virtual kernel" -; -vk_found: popa - push di - mov di,VKernelBuf - mov cx,vk_size >> 2 - rep movsd - push es ; Restore old DS - pop ds - push es - push word real_mode_seg - pop es - mov di,cmd_line_here - mov si,VKernelBuf+vk_append - mov cx,[VKernelBuf+vk_appendlen] - rep movsb - mov [CmdLinePtr],di ; Where to add rest of cmd - pop es - pop di ; DI -> KernelName - push di - mov si,VKernelBuf+vk_rname - mov cx,11 ; We need ECX == CX later - rep movsb - pop di - xor bx,bx ; Try only one version - jmp get_kernel -; -; kernel_corrupt: Called if the kernel file does not seem healthy -; -kernel_corrupt: mov si,err_notkernel - jmp abort_load -; -; This is it! We have a name (and location on the disk)... let's load -; that sucker!! First we have to decide what kind of file this is; base -; that decision on the file extension. The following extensions are -; recognized: -; -; .com - COMBOOT image -; .cbt - COMBOOT image -; .c32 - COM32 image -; .bs - Boot sector -; .0 - PXE bootstrap program (PXELINUX only) -; .bin - Boot sector -; .bss - Boot sector, but transfer over DOS superblock (SYSLINUX only) -; .img - Floppy image (ISOLINUX only) -; -; Anything else is assumed to be a Linux kernel. -; -kernel_good: - pusha - mov si,KernelName - mov di,KernelCName - call unmangle_name ; Get human form - sub di,KernelCName - mov [KernelCNameLen],di - popa - - mov ecx,[KernelName+8] ; Get (mangled) extension - and ecx,00ffffffh ; 3 bytes only - cmp ecx,'COM' - je is_comboot_image - cmp ecx,'CBT' - je is_comboot_image - cmp ecx,'C32' - je is_com32_image - cmp ecx,'BS ' - je is_bootsector - cmp ecx,'BIN' - je is_bootsector - cmp ecx,'BSS' - je is_bss_sector - ; Otherwise Linux kernel +%include "ui.inc" ; ; Linux kernel loading code is common. @@ -1699,20 +1387,17 @@ initrd_cmd_len equ 7 ; Config file keyword table ; %include "keywords.inc" + ; -; Extensions to search for (in *reverse* order). Note that the last -; (lexically first) entry in the table is a placeholder for the original -; extension, needed for error messages. The exten_table is shifted so -; the table is 1-based; this is because a "loop" cx is used as index. +; Extensions to search for (in *forward* order). ; -exten_table: -OrigKernelExt: dd 0 ; Original extension - db 'COM',0 ; COMBOOT (same as DOS) - db 'BS ',0 ; Boot Sector +exten_table: db 'CBT',0 ; COMBOOT (specific) db 'BSS',0 ; Boot Sector (add superblock) - db 'CBT',0 ; COMBOOT (specific) + db 'BS ',0 ; Boot Sector + db 'COM',0 ; COMBOOT (same as DOS) +exten_table_end: + dd 0, 0 ; Need 8 null bytes here -exten_count equ (($-exten_table) >> 2) - 1 ; Number of alternates ; ; Misc initialized (data) variables ; |