2 ;; -----------------------------------------------------------------------
4 ;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
6 ;; This program is free software; you can redistribute it and/or modify
7 ;; it under the terms of the GNU General Public License as published by
8 ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
9 ;; Bostom MA 02111-1307, USA; either version 2 of the License, or
10 ;; (at your option) any later version; incorporated herein by reference.
12 ;; -----------------------------------------------------------------------
15 ; This file should be entered with the config file open (for getc)
17 call parse_config ; Parse configuration file
20 ; Check whether or not we are supposed to display the boot prompt.
23 cmp word [ForcePrompt],byte 0 ; Force prompt?
25 test byte [KbdFlags],5Bh ; Caps, Scroll, Shift, Alt
26 jz auto_boot ; If neither, default boot
32 mov byte [FuncFlag],0 ; <Ctrl-F> not pressed
35 ; get the very first character -- we can either time
36 ; out, or receive a character press at this time. Some dorky BIOSes stuff
37 ; a return in the buffer on bootup, so wipe the keyboard buffer first.
39 clear_buffer: mov ah,1 ; Check for pending char
44 jmp short clear_buffer
49 jz get_char ; Timeout == 0 -> no timeout
50 inc cx ; The first loop will happen
51 ; immediately as we don't
52 ; know the appropriate DX value
57 mov dx,[BIOS_timer] ; Get time "of day"
59 cmp dx,ax ; Has the timer advanced?
63 loop time_loop ; If so, decrement counter
67 mov si,TimeOutCmd ; Copy timeoutcommand if we have one...
68 mov cx,[TimeOutCmdLen]
73 get_char_pop: pop eax ; Clear stack
81 got_ascii: cmp al,7Fh ; <DEL> == <BS>
86 cmp di,command_line ; Space must not be first
88 enter_char: test byte [FuncFlag],1
96 .not_ctrl_f: cmp di,max_cmd_len+command_line ; Check there's space
99 call writechr ; Echo to screen
101 not_ascii: mov byte [FuncFlag],0
104 cmp al,06h ; <Ctrl-F>
106 cmp al,16h ; <Ctrl-V>
108 cmp al,08h ; Backspace
110 backspace: cmp di,command_line ; Make sure there is anything
111 je get_char ; to erase
112 dec di ; Unstore one character
113 mov si,wipe_char ; and erase it from the screen
118 mov byte [FuncFlag],1
122 ctrl_f_0: add al,10 ; <Ctrl-F>0 == F10
128 ; AL = 0 if we get here
134 show_help: ; AX = func key # (0 = F1, 9 = F10)
135 push di ; Save end-of-cmdline pointer
136 shl ax,FILENAME_MAX_LG2 ; Convert to pointer
139 cmp byte [di],NULLFILE
140 je short fk_nofile ; Undefined F-key
142 jz short fk_nofile ; File not found
150 push di ; Command line write pointer
151 mov si,syslinux_banner
156 ; ... fall through ...
158 ; Write the boot prompt and command line again and
159 ; wait for input. Note that this expects the cursor
160 ; to already have been CRLF'd, and that the old value
161 ; of DI (the command line write pointer) is on the stack.
165 pop di ; Command line write pointer
167 mov byte [di],0 ; Null-terminate command line
169 call cwritestr ; Write command line so far
175 mov cx,(max_cmd_len+4) >> 2
177 jmp short load_kernel
180 cmp di,command_line ; Did we just hit return?
182 xor al,al ; Store a final null
185 load_kernel: ; Load the kernel now
187 ; First we need to mangle the kernel name the way DOS would...
197 ; Fast-forward to first option (we start over from the beginning, since
198 ; mangle_name doesn't necessarily return a consistent ending state.)
203 clin_is_wsp: and al,al
208 clin_opt_ptr: dec si ; Point to first nonblank
209 mov [CmdOptPtr],si ; Save ptr to first option
211 ; Now check if it is a "virtual kernel"
219 xor si,si ; Point to first vkernel
222 repe cmpsb ; Is this it?
229 ; Not a "virtual kernel" - check that's OK and construct the command line
231 cmp word [AllowImplicit],byte 0
247 ; Find the kernel on disk
249 get_kernel: mov byte [KernelName+FILENAME_MAX],0 ; Zero-terminate filename/extension
250 %if IS_SYSLINUX || IS_MDSLINUX ; SYSLINUX has to deal with DOS mangled names...
251 mov eax,[KernelName+8] ; Save initial extension
252 mov [exten_table_end],eax ; Last case == initial ext.
256 mov cx,FILENAME_MAX-5 ; Need 4 chars + null
257 repne scasb ; Scan for final null
259 dec di ; Point to final null
260 .no_skip: mov [KernelExtPtr],di
263 .search_loop: push bx
264 mov di,KernelName ; Search on disk
268 mov eax,[bx] ; Try a different extension
269 %if IS_SYSLINUX || IS_MDSLINUX
270 mov [KernelName+8],eax
272 mov si,[KernelExtPtr]
277 cmp bx,exten_table_end
278 jna .search_loop ; allow == case (final case)
283 call unmangle_name ; Get human form
284 mov si,err_notfound ; Complain about missing kernel
289 jmp abort_load ; Ask user for clue
291 ; bad_implicit: The user entered a nonvirtual kernel name, with "implicit 0"
293 bad_implicit: mov si,KernelName ; For the error message
298 ; vk_found: We *are* using a "virtual kernel"
305 push es ; Restore old DS
308 push word real_mode_seg
311 mov si,VKernelBuf+vk_append
312 mov cx,[VKernelBuf+vk_appendlen]
314 mov [CmdLinePtr],di ; Where to add rest of cmd
316 pop di ; DI -> KernelName
318 mov si,VKernelBuf+vk_rname
319 mov cx,FILENAME_MAX ; We need ECX == CX later
323 mov al,[VKernelBuf+vk_ipappend]
326 xor bx,bx ; Try only one version
328 %if IS_SYSLINUX || IS_MDSLINUX
331 ; Is this a "localboot" pseudo-kernel?
332 cmp byte [VKernelBuf+vk_rname], 0
333 jne get_kernel ; No, it's real, go get it
335 mov ax, [VKernelBuf+vk_rname+1]
340 ; kernel_corrupt: Called if the kernel file does not seem healthy
342 kernel_corrupt: mov si,err_notkernel
345 ; This is it! We have a name (and location on the disk)... let's load
346 ; that sucker!! First we have to decide what kind of file this is; base
347 ; that decision on the file extension. The following extensions are
348 ; recognized; case insensitive:
350 ; .com - COMBOOT image
351 ; .cbt - COMBOOT image
354 ; .0 - PXE bootstrap program (PXELINUX only)
356 ; .bss - Boot sector, but transfer over DOS superblock (SYSLINUX only)
357 ; .img - Floppy image (ISOLINUX only)
359 ; Anything else is assumed to be a Linux kernel.
367 mov [KernelCNameLen],di
370 %if IS_SYSLINUX || IS_MDSLINUX
371 mov ecx,[KernelName+7]
382 .one_step: mov ecx,[di-4] ; 4 bytes before end
388 ; At this point, DX:AX contains the size of the kernel, and SI contains
389 ; the file handle/cluster pointer.
391 or ecx,20202000h ; Force lower case
407 %if IS_SYSLINUX || IS_MDSLINUX
420 ; Otherwise Linux kernel