summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhpa <hpa>2002-10-24 00:59:08 +0000
committerhpa <hpa>2002-10-24 00:59:08 +0000
commitea2c13ab4e1760cc2e5b5737016eb6d308bfe29e (patch)
tree583238aba27b0fdcf10861c6127aeb45fdbb838e
parent6f5159e474dd731591e536f15776c94ce4754f73 (diff)
downloadsyslinux-ea2c13ab4e1760cc2e5b5737016eb6d308bfe29e.tar.gz
* Unify the command-line handling and extension-scanning codesyslinux-2.00-pre10
* Fix bug relating to '/' characters in ISOLINUX * Add <Ctrl-V> to display the version number
-rw-r--r--NEWS7
-rw-r--r--bootsect.inc2
-rw-r--r--isolinux.asm361
-rw-r--r--ldlinux.asm337
-rw-r--r--pxelinux.asm355
-rw-r--r--ui.inc414
6 files changed, 443 insertions, 1033 deletions
diff --git a/NEWS b/NEWS
index 89c4ca2e..1c483dd8 100644
--- a/NEWS
+++ b/NEWS
@@ -4,13 +4,18 @@ apply to that specific program only; other changes apply to both.
Changes in 2.00:
* ALL: Add support for "COM32" (32-bit COMBOOT) images.
* ALL: Add an API for COMBOOT/COM32 images. See comboot.doc
- for details.
+ for details. There is a C development environment for
+ COM32 being created; it should be ready at some point in
+ the future.
* Fix mbr.asm so that it actually works.
* SYSLINUX: The syslinux installer *SHOULD* now be safe to
run setuid root.
* PXELINUX: Fix bug where PXELINUX would override random
chunks of the UNDI code segment! Thanks to Kevin Tran for
finding this bug.
+ * ISOLINUX: Fix a bug related to slashes in pathnames.
+ * ALL: Make the <Ctrl-V> key print out the version; this is
+ to help debugging.
Changes in 1.76:
* ISOLINUX: Remove code no longer used which caused hangs on
diff --git a/bootsect.inc b/bootsect.inc
index d3e50fc9..b114c4eb 100644
--- a/bootsect.inc
+++ b/bootsect.inc
@@ -108,7 +108,7 @@ load_bootsec:
jmp bcopy_over_self
%if IS_SYSLINUX = 0
-is_bss_image:
+is_bss_sector:
mov si,err_bssimage
call cwritestr
jmp enter_command
diff --git a/isolinux.asm b/isolinux.asm
index ce2520c5..7966f9ea 100644
--- a/isolinux.asm
+++ b/isolinux.asm
@@ -838,359 +838,10 @@ load_config:
%endif
;
-; Now we have the config file open
+; Now we have the config file open. Parse the config file and
+; run the user interface.
;
- 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
- mov dx,[BIOS_timer] ; 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,FILENAME_MAX
- 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
-;
-; Find the kernel on disk
-;
-get_kernel: mov byte [KernelName+FILENAME_MAX],0 ; Zero-terminate filename/extension
- mov di,KernelName
- xor al,al
- mov cx,FILENAME_MAX-5 ; Need 4 chars + null
- repne scasb ; Scan for final null
- jne .no_skip
- dec di ; Point to final null
-.no_skip: mov [KernelExtPtr],di
- mov bx,exten_table
-.search_loop: push bx
- mov di,KernelName ; Search on disk
- call searchdir
- pop bx
- jnz kernel_good
- mov eax,[bx] ; Try a different extension
- mov si,[KernelExtPtr]
- mov [si],eax
- mov byte [si+4],0
- add bx,byte 4
- cmp bx,exten_table_end
- jna .search_loop ; allow == case (final case)
-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
-;
-; 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,FILENAME_MAX ; We need ECX == CX later
- rep movsb
- pop di
- xor bx,bx ; Try only one version
-
- ; Is this a "localboot" pseudo-kernel?
- cmp byte [VKernelBuf+vk_rname], 0
- jne get_kernel ; No, it's real, go get it
-
- mov ax, [VKernelBuf+vk_rname+1]
- jmp local_boot
-;
-; 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; case insensitive:
-;
-; .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
- sub di,KernelCName
- mov [KernelCNameLen],di
- popa
-
- push di
- push ax
- mov di,KernelName
- xor al,al
- mov cx,FILENAME_MAX
- repne scasb
- jne .one_step
- dec di
-.one_step: mov ecx,[di-4] ; 4 bytes before end
- pop ax
- pop di
-
-;
-; At this point, DX:AX contains the size of the kernel, and SI contains
-; the file handle/cluster pointer.
-;
- or ecx,20202000h ; Force lower case
-
- cmp ecx,'.com'
- je is_comboot_image
- cmp ecx,'.cbt'
- je is_comboot_image
- cmp ecx,'.c32'
- je is_com32_image
- cmp ecx,'.img'
- je is_disk_image
- cmp ecx,'.bss'
- je is_bss_image
- cmp ecx,'.bin'
- je is_bootsector
- shr ecx,8
- cmp ecx,'.bs'
- je is_bootsector
- shr ecx,8
- cmp cx,'.0'
- je is_bootsector
- ; Otherwise Linux kernel
+%include "ui.inc"
;
; Linux kernel loading code is common.
@@ -1476,8 +1127,11 @@ searchdir_iso:
mov [di-1],byte 0 ; Terminate at directory name
mov cl,02h ; Search for directory
xchg cl,[ISOFlags]
- push di
+
+ push di ; Save these...
push cx
+
+ ; Create recursion stack frame...
push word .resume ; Where to "return" to
push es
.isfile: xchg ax,di
@@ -1554,6 +1208,7 @@ searchdir_iso:
xchg edx,eax ; Directory length in edx
pop cx ; Old ISOFlags
pop di ; Next filename pointer
+ 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
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
;
diff --git a/pxelinux.asm b/pxelinux.asm
index e4572b88..7df0bc7c 100644
--- a/pxelinux.asm
+++ b/pxelinux.asm
@@ -772,364 +772,15 @@ config_scan:
jmp no_config_file
-;
-; Now we have the config file open
-;
.success: add sp,byte 16 ; Adjust stack
- 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
- mov dx,[BIOS_timer] ; 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,FILENAME_MAX
- 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
-;
-; Find the kernel on disk
-;
-get_kernel: mov byte [KernelName+FILENAME_MAX],0 ; Zero-terminate filename/extension
- mov di,KernelName
- xor al,al
- mov cx,FILENAME_MAX-5 ; Need 4 chars + null
- repne scasb ; Scan for final null
- jne .no_skip
- dec di ; Point to final null
-.no_skip: mov [KernelExtPtr],di
- mov bx,exten_table
-.search_loop: push bx
- mov di,KernelName ; Search on disk
- call searchdir
- pop bx
- jnz kernel_good
- mov eax,[bx] ; Try a different extension
- mov si,[KernelExtPtr]
- mov [si],eax
- mov byte [si+4],0
- add bx,byte 4
- cmp bx,exten_table_end
- jna .search_loop ; allow == case (final case)
-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
-;
-; 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,FILENAME_MAX ; We need ECX == CX later
- rep movsb
- pop di
- mov al,[VKernelBuf+vk_ipappend]
- mov [IPAppend],al
- xor bx,bx ; Try only one version
- ; Is this a "localboot" pseudo-kernel?
- cmp byte [VKernelBuf+vk_rname], 0
- jne get_kernel ; No, it's real, go get it
-
- mov ax, [VKernelBuf+vk_rname+1]
- jmp local_boot
-;
-; 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; case insensitive:
;
-; .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)
+; Now we have the config file open. Parse the config file and
+; run the user interface.
;
-; Boot sectors are currently not supported by PXELINUX.
-;
-; Anything else is assumed to be a Linux kernel.
-;
-kernel_good:
- pusha
- mov si,KernelName
- mov di,KernelCName
- call unmangle_name
- sub di,KernelCName
- mov [KernelCNameLen],di
- popa
-
- push di
- push ax
- mov di,KernelName
- xor al,al
- mov cx,FILENAME_MAX
- repne scasb
- jne .one_step
- dec di
-.one_step: mov ecx,[di-4] ; 4 bytes before end
- pop ax
- pop di
+%include "ui.inc"
;
-; At this point, DX:AX contains the size of the kernel, and SI contains
-; the file handle/cluster pointer.
-;
- or ecx,20202000h ; Force lower case
-
- cmp ecx,'.com'
- je is_comboot_image
- cmp ecx,'.cbt'
- je is_comboot_image
- cmp ecx,'.c32'
- je is_com32_image
- cmp ecx,'.bss'
- je is_bss_image
- cmp ecx,'.bin'
- je is_bootsector
- shr ecx,8
- cmp ecx,'.bs'
- je is_bootsector
- shr ecx,8
- cmp cx,'.0'
- je is_bootsector
- ; Otherwise Linux kernel
-;
; Linux kernel loading code is common. However, we need to define
; a couple of helper macros...
;
diff --git a/ui.inc b/ui.inc
new file mode 100644
index 00000000..c8d309d6
--- /dev/null
+++ b/ui.inc
@@ -0,0 +1,414 @@
+;; $Id$
+;; -----------------------------------------------------------------------
+;;
+;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
+;;
+;; 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,
+;; Bostom MA 02111-1307, USA; either version 2 of the License, or
+;; (at your option) any later version; incorporated herein by reference.
+;;
+;; -----------------------------------------------------------------------
+
+;
+; This file should be entered with the config file open (for getc)
+;
+ 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
+ mov dx,[BIOS_timer] ; 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 short 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 short get_char
+ stosb ; Save it
+ call writechr ; Echo to screen
+ 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,16h ; <Ctrl-V>
+ je print_version
+ 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
+get_char_2:
+ jmp short get_char
+
+ctrl_f_0: add al,10 ; <Ctrl-F>0 == F10
+ctrl_f: sub al,'1'
+ xor ah,ah
+ jmp short show_help
+
+func_key:
+ ; AL = 0 if we get here
+ xchg al,ah
+ cmp al,68 ; F10
+ ja short get_char_2
+ sub al,59 ; F1
+ jb short get_char_2
+show_help: ; AX = func key # (0 = F1, 9 = F10)
+ push di ; Save end-of-cmdline pointer
+ shl ax,FILENAME_MAX_LG2 ; Convert to pointer
+ add ax,FKeyName
+ xchg di,ax
+ cmp byte [di],NULLFILE
+ je short fk_nofile ; Undefined F-key
+ call searchdir
+ jz short fk_nofile ; File not found
+ push si
+ call crlf
+ pop si
+ call get_msg_file
+ jmp short fk_wrcmd
+
+print_version:
+ push di ; Command line write pointer
+ mov si,syslinux_banner
+ call cwritestr
+ mov si,copyright_str
+ call cwritestr
+
+ ; ... fall through ...
+
+ ; Write the boot prompt and command line again and
+ ; wait for input. Note that this expects the cursor
+ ; to already have been CRLF'd, and that the old value
+ ; of DI (the command line write pointer) is on the stack.
+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
+fk_nofile: 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,FILENAME_MAX
+ 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
+;
+; Find the kernel on disk
+;
+get_kernel: mov byte [KernelName+FILENAME_MAX],0 ; Zero-terminate filename/extension
+%if IS_SYSLINUX ; SYSLINUX has to deal with DOS mangled names...
+ mov eax,[KernelName+8] ; Save initial extension
+ mov [exten_table_end],eax ; Last case == initial ext.
+%else
+ mov di,KernelName
+ xor al,al
+ mov cx,FILENAME_MAX-5 ; Need 4 chars + null
+ repne scasb ; Scan for final null
+ jne .no_skip
+ dec di ; Point to final null
+.no_skip: mov [KernelExtPtr],di
+%endif
+ mov bx,exten_table
+.search_loop: push bx
+ mov di,KernelName ; Search on disk
+ call searchdir
+ pop bx
+ jnz kernel_good
+ mov eax,[bx] ; Try a different extension
+%if IS_SYSLINUX
+ mov [KernelName+8],eax
+%else
+ mov si,[KernelExtPtr]
+ mov [si],eax
+ mov byte [si+4],0
+%endif
+ add bx,byte 4
+ cmp bx,exten_table_end
+ jna .search_loop ; allow == case (final case)
+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
+;
+; 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,FILENAME_MAX ; We need ECX == CX later
+ rep movsb
+ pop di
+%if IS_PXELINUX
+ mov al,[VKernelBuf+vk_ipappend]
+ mov [IPAppend],al
+%endif
+ xor bx,bx ; Try only one version
+
+%if IS_SYSLINUX
+ jmp get_kernel
+%else
+ ; Is this a "localboot" pseudo-kernel?
+ cmp byte [VKernelBuf+vk_rname], 0
+ jne get_kernel ; No, it's real, go get it
+
+ mov ax, [VKernelBuf+vk_rname+1]
+ jmp local_boot
+%endif
+
+;
+; 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; case insensitive:
+;
+; .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
+ sub di,KernelCName
+ mov [KernelCNameLen],di
+ popa
+
+%if IS_SYSLINUX
+ mov ecx,[KernelName+7]
+ mov cl,'.'
+%else
+ push di
+ push ax
+ mov di,KernelName
+ xor al,al
+ mov cx,FILENAME_MAX
+ repne scasb
+ jne .one_step
+ dec di
+.one_step: mov ecx,[di-4] ; 4 bytes before end
+ pop ax
+ pop di
+%endif
+
+;
+; At this point, DX:AX contains the size of the kernel, and SI contains
+; the file handle/cluster pointer.
+;
+ or ecx,20202000h ; Force lower case
+
+ cmp ecx,'.com'
+ je is_comboot_image
+ cmp ecx,'.cbt'
+ je is_comboot_image
+ cmp ecx,'.c32'
+ je is_com32_image
+%if IS_ISOLINUX
+ cmp ecx,'.img'
+ je is_disk_image
+%endif
+ cmp ecx,'.bss'
+ je is_bss_sector
+ cmp ecx,'.bin'
+ je is_bootsector
+%if IS_SYSLINUX
+ cmp ecx,'.bs '
+ je is_bootsector
+ cmp ecx,'.0 '
+ je is_bootsector
+%else
+ shr ecx,8
+ cmp ecx,'.bs'
+ je is_bootsector
+ shr ecx,8
+ cmp cx,'.0'
+ je is_bootsector
+%endif
+ ; Otherwise Linux kernel
+