* Unify the command-line handling and extension-scanning code
authorhpa <hpa>
Thu, 24 Oct 2002 00:59:08 +0000 (00:59 +0000)
committerhpa <hpa>
Thu, 24 Oct 2002 00:59:08 +0000 (00:59 +0000)
* Fix bug relating to '/' characters in ISOLINUX
* Add <Ctrl-V> to display the version number

NEWS
bootsect.inc
isolinux.asm
ldlinux.asm
pxelinux.asm
ui.inc [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 89c4ca2..1c483dd 100644 (file)
--- 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
index d3e50fc..b114c4e 100644 (file)
@@ -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
index ce2520c..7966f9e 100644 (file)
@@ -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
index d81353b..7380330 100644 (file)
@@ -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
 ;
index e4572b8..7df0bc7 100644 (file)
@@ -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 (file)
index 0000000..c8d309d
--- /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
+