Magellan Linux

Annotation of /trunk/mkinitrd-magellan/isolinux/ui.inc

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (hide annotations) (download)
Sat Sep 1 22:45:15 2007 UTC (16 years, 8 months ago) by niro
File size: 13067 byte(s)
-import if magellan mkinitrd; it is a fork of redhats mkinitrd-5.0.8 with all magellan patches and features; deprecates magellan-src/mkinitrd

1 niro 532 ;; $Id: ui.inc,v 1.1 2007-09-01 22:44:05 niro Exp $
2     ;; -----------------------------------------------------------------------
3     ;;
4     ;; Copyright 1994-2005 H. Peter Anvin - All Rights Reserved
5     ;;
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     ;; Boston MA 02111-1307, USA; either version 2 of the License, or
10     ;; (at your option) any later version; incorporated herein by reference.
11     ;;
12     ;; -----------------------------------------------------------------------
13    
14     ;
15     ; This file should be entered with the config file open (for getc)
16     ;
17     call parse_config ; Parse configuration file
18     no_config_file:
19     ;
20     ; Check whether or not we are supposed to display the boot prompt.
21     ;
22     check_for_key:
23     cmp word [ForcePrompt],0 ; Force prompt?
24     jnz enter_command
25     test byte [KbdFlags],5Bh ; Shift Alt Caps Scroll
26     jz auto_boot ; If neither, default boot
27    
28     enter_command:
29     cmp word [NoEscape],0 ; If NOESCAPE, no prompt,
30     jne auto_boot ; always run default cmd
31    
32     mov si,boot_prompt
33     call cwritestr
34    
35     mov byte [FuncFlag],0 ; <Ctrl-F> not pressed
36     mov di,command_line
37    
38     ;
39     ; get the very first character -- we can either time
40     ; out, or receive a character press at this time. Some dorky BIOSes stuff
41     ; a return in the buffer on bootup, so wipe the keyboard buffer first.
42     ;
43     clear_buffer: mov ah,11h ; Check for pending char
44     int 16h
45     jz get_char_time
46     mov ah,10h ; Get char
47     int 16h
48     jmp short clear_buffer
49    
50     ; For the first character, both KbdTimeout and
51     ; TotalTimeout apply; after that, only TotalTimeout.
52    
53     get_char_time:
54     mov eax,[TotalTimeout]
55     mov [ThisTotalTo],eax
56     mov eax,[KbdTimeout]
57     mov [ThisKbdTo],eax
58    
59     get_char:
60     call getchar_timeout
61     and dword [ThisKbdTo],0 ; For the next time...
62    
63     and al,al
64     jz func_key
65    
66     got_ascii: cmp al,7Fh ; <DEL> == <BS>
67     je backspace
68     cmp al,' ' ; ASCII?
69     jb not_ascii
70     ja enter_char
71     cmp di,command_line ; Space must not be first
72     je short get_char
73     enter_char: test byte [FuncFlag],1
74     jz .not_ctrl_f
75     mov byte [FuncFlag],0
76     cmp al,'0'
77     jb .not_ctrl_f
78     je ctrl_f_0
79     cmp al,'9'
80     jbe ctrl_f
81     .not_ctrl_f: cmp di,max_cmd_len+command_line ; Check there's space
82     jnb short get_char
83     stosb ; Save it
84     call writechr ; Echo to screen
85     jmp short get_char
86     not_ascii: mov byte [FuncFlag],0
87     cmp al,0Dh ; Enter
88     je command_done
89     cmp al,'F' & 1Fh ; <Ctrl-F>
90     je set_func_flag
91     cmp al,'U' & 1Fh ; <Ctrl-U>
92     je kill_command ; Kill input line
93     cmp al,'V' & 1Fh ; <Ctrl-V>
94     je print_version
95     cmp al,'X' & 1Fh ; <Ctrl-X>
96     je force_text_mode
97     cmp al,08h ; Backspace
98     jne get_char
99     backspace: cmp di,command_line ; Make sure there is anything
100     je get_char ; to erase
101     dec di ; Unstore one character
102     mov si,wipe_char ; and erase it from the screen
103     call cwritestr
104     jmp short get_char_2
105    
106     kill_command:
107     call crlf
108     jmp enter_command
109    
110     force_text_mode:
111     call vgaclearmode
112     jmp enter_command
113    
114     set_func_flag:
115     mov byte [FuncFlag],1
116     get_char_2:
117     jmp short get_char
118    
119     ctrl_f_0: add al,10 ; <Ctrl-F>0 == F10
120     ctrl_f: sub al,'1'
121     xor ah,ah
122     jmp short show_help
123    
124     func_key:
125     ; AL = 0 if we get here
126     xchg al,ah
127     cmp al,68 ; F10
128     ja short get_char_2
129     sub al,59 ; F1
130     jb short get_char_2
131     show_help: ; AX = func key # (0 = F1, 9 = F10)
132     push di ; Save end-of-cmdline pointer
133     shl ax,FILENAME_MAX_LG2 ; Convert to pointer
134     add ax,FKeyName
135     xchg di,ax
136     cmp byte [di+NULLOFFSET],NULLFILE
137     je short fk_nofile ; Undefined F-key
138     call searchdir
139     jz short fk_nofile ; File not found
140     push si
141     call crlf
142     pop si
143     call get_msg_file
144     jmp short fk_wrcmd
145    
146     print_version:
147     push di ; Command line write pointer
148     mov si,syslinux_banner
149     call cwritestr
150     %ifdef HAVE_BIOSNAME
151     mov si,[BIOSName]
152     call cwritestr
153     %endif
154     mov si,copyright_str
155     call cwritestr
156    
157     ; ... fall through ...
158    
159     ; Write the boot prompt and command line again and
160     ; wait for input. Note that this expects the cursor
161     ; to already have been CRLF'd, and that the old value
162     ; of DI (the command line write pointer) is on the stack.
163     fk_wrcmd:
164     mov si,boot_prompt
165     call cwritestr
166     pop di ; Command line write pointer
167     push di
168     mov byte [di],0 ; Null-terminate command line
169     mov si,command_line
170     call cwritestr ; Write command line so far
171     fk_nofile: pop di
172     jmp short get_char_2
173    
174     ;
175     ; Jump here to run the default command line
176     ;
177     auto_boot:
178     mov si,default_cmd
179     mov di,command_line
180     mov cx,(max_cmd_len+4) >> 2
181     rep movsd
182     jmp short load_kernel
183    
184     ;
185     ; Jump here when the command line is completed
186     ;
187     command_done:
188     call crlf
189     cmp di,command_line ; Did we just hit return?
190     je auto_boot
191     xor al,al ; Store a final null
192     stosb
193    
194     load_kernel: ; Load the kernel now
195     ;
196     ; First we need to mangle the kernel name the way DOS would...
197     ;
198     mov si,command_line
199     mov di,KernelName
200     push si
201     push di
202     call mangle_name
203     pop di
204     pop si
205     ;
206     ; Fast-forward to first option (we start over from the beginning, since
207     ; mangle_name doesn't necessarily return a consistent ending state.)
208     ;
209     clin_non_wsp: lodsb
210     cmp al,' '
211     ja clin_non_wsp
212     clin_is_wsp: and al,al
213     jz clin_opt_ptr
214     lodsb
215     cmp al,' '
216     jbe clin_is_wsp
217     clin_opt_ptr: dec si ; Point to first nonblank
218     mov [CmdOptPtr],si ; Save ptr to first option
219     ;
220     ; If "allowoptions 0", put a null character here in order to ignore any
221     ; user-specified options.
222     ;
223     mov ax,[AllowOptions]
224     and ax,ax
225     jnz clin_opt_ok
226     mov [si],al
227     clin_opt_ok:
228    
229     ;
230     ; Now check if it is a "virtual kernel"
231     ;
232     vk_check:
233     xor si,si ; Beginning of vk_seg
234     .scan:
235     cmp si,[VKernelBytes]
236     jae .not_vk
237    
238     push ds
239     push word vk_seg
240     pop ds
241    
242     mov di,VKernelBuf
243     call rllunpack
244     pop ds
245     ; SI updated on return
246    
247     sub di,cx ; Return to beginning of buf
248     push si
249     mov si,KernelName
250     mov cx,FILENAME_MAX
251     es repe cmpsb
252     pop si
253     je .found
254     jmp .scan
255    
256     ;
257     ; We *are* using a "virtual kernel"
258     ;
259     .found:
260     push es
261     push word real_mode_seg
262     pop es
263     mov di,cmd_line_here
264     mov si,VKernelBuf+vk_append
265     mov cx,[VKernelBuf+vk_appendlen]
266     rep movsb
267     mov [CmdLinePtr],di ; Where to add rest of cmd
268     pop es
269     mov di,KernelName
270     push di
271     mov si,VKernelBuf+vk_rname
272     mov cx,FILENAME_MAX ; We need ECX == CX later
273     rep movsb
274     pop di
275     %if IS_PXELINUX
276     mov al,[VKernelBuf+vk_ipappend]
277     mov [IPAppend],al
278     %endif
279     xor bx,bx ; Try only one version
280    
281     %if IS_PXELINUX || IS_ISOLINUX
282     ; Is this a "localboot" pseudo-kernel?
283     %if IS_PXELINUX
284     cmp byte [VKernelBuf+vk_rname+4], 0
285     %else
286     cmp byte [VKernelBuf+vk_rname], 0
287     %endif
288     jne get_kernel ; No, it's real, go get it
289    
290     mov ax, [VKernelBuf+vk_rname+1]
291     jmp local_boot
292     %else
293     jmp get_kernel
294     %endif
295    
296     .not_vk:
297    
298     ;
299     ; Not a "virtual kernel" - check that's OK and construct the command line
300     ;
301     cmp word [AllowImplicit],byte 0
302     je bad_implicit
303     push es
304     push si
305     push di
306     mov di,real_mode_seg
307     mov es,di
308     mov si,AppendBuf
309     mov di,cmd_line_here
310     mov cx,[AppendLen]
311     rep movsb
312     mov [CmdLinePtr],di
313     pop di
314     pop si
315     pop es
316     ;
317     ; Find the kernel on disk
318     ;
319     get_kernel: mov byte [KernelName+FILENAME_MAX],0 ; Zero-terminate filename/extension
320     %if IS_SYSLINUX || IS_MDSLINUX ; SYSLINUX has to deal with DOS mangled names...
321     mov eax,[KernelName+8] ; Save initial extension
322     mov [exten_table_end],eax ; Last case == initial ext.
323     %else
324     mov di,KernelName+4*IS_PXELINUX
325     xor al,al
326     mov cx,FILENAME_MAX-5 ; Need 4 chars + null
327     repne scasb ; Scan for final null
328     jne .no_skip
329     dec di ; Point to final null
330     .no_skip: mov [KernelExtPtr],di
331     %endif
332     mov bx,exten_table
333     .search_loop: push bx
334     mov di,KernelName ; Search on disk
335     call searchdir
336     pop bx
337     jnz kernel_good
338     mov eax,[bx] ; Try a different extension
339     %if IS_SYSLINUX || IS_MDSLINUX
340     mov [KernelName+8],eax
341     %else
342     mov si,[KernelExtPtr]
343     mov [si],eax
344     mov byte [si+4],0
345     %endif
346     add bx,byte 4
347     cmp bx,exten_table_end
348     jna .search_loop ; allow == case (final case)
349     ; Fall into bad_kernel
350     ;
351     ; bad_kernel: Kernel image not found
352     ; bad_implicit: The user entered a nonvirtual kernel name, with "implicit 0"
353     ;
354     bad_implicit:
355     bad_kernel:
356     mov cx,[OnerrorLen]
357     and cx,cx
358     jnz on_error
359     .really:
360     mov si,KernelName
361     mov di,KernelCName
362     push di
363     call unmangle_name ; Get human form
364     mov si,err_notfound ; Complain about missing kernel
365     call cwritestr
366     pop si ; KernelCName
367     call cwritestr
368     mov si,crlf_msg
369     jmp abort_load ; Ask user for clue
370    
371     ;
372     ; on_error: bad kernel, but we have onerror set
373     ;
374     on_error:
375     mov si,Onerror
376     mov di,command_line
377     push si ; <A>
378     push di ; <B>
379     push cx ; <C>
380     push cx ; <D>
381     push di ; <E>
382     repe cmpsb
383     pop di ; <E> di == command_line
384     pop bx ; <D> bx == [OnerrorLen]
385     je bad_kernel.really ; Onerror matches command_line already
386     neg bx ; bx == -[OnerrorLen]
387     lea cx,[max_cmd_len+bx]
388     ; CX == max_cmd_len-[OnerrorLen]
389     mov di,command_line+max_cmd_len-1
390     mov byte [di+1],0 ; Enforce null-termination
391     lea si,[di+bx]
392     std
393     rep movsb ; Make space in command_line
394     cld
395     pop cx ; <C> cx == [OnerrorLen]
396     pop di ; <B> di == command_line
397     pop si ; <A> si == Onerror
398     rep movsb
399     jmp load_kernel
400    
401     ;
402     ; kernel_corrupt: Called if the kernel file does not seem healthy
403     ;
404     kernel_corrupt: mov si,err_notkernel
405     jmp abort_load
406    
407     ;
408     ; Get a key, observing ThisKbdTO and ThisTotalTO -- those are timeouts
409     ; which can be adjusted by the caller based on the corresponding
410     ; master variables; on return they're updated.
411     ;
412     ; This cheats. If we say "no timeout" we actually get a timeout of
413     ; 7.5 years.
414     ;
415     getchar_timeout:
416     call vgashowcursor
417     RESET_IDLE
418    
419     .loop:
420     push word [BIOS_timer]
421     call pollchar
422     jnz .got_char
423     pop ax
424     cmp ax,[BIOS_timer] ; Has the timer advanced?
425     je .loop
426     DO_IDLE
427    
428     dec dword [ThisKbdTo]
429     jz .timeout
430     dec dword [ThisTotalTo]
431     jnz .loop
432    
433     .timeout:
434     ; Timeout!!!!
435     pop cx ; Discard return address
436     call vgahidecursor
437     mov si,Ontimeout ; Copy ontimeout command
438     mov di,command_line
439     mov cx,[OntimeoutLen] ; if we have one...
440     rep movsb
441     jmp command_done
442    
443     .got_char:
444     pop cx ; Discard
445     call getchar
446     call vgahidecursor
447     ret
448    
449     ;
450     ; This is it! We have a name (and location on the disk)... let's load
451     ; that sucker!! First we have to decide what kind of file this is; base
452     ; that decision on the file extension. The following extensions are
453     ; recognized; case insensitive:
454     ;
455     ; .com - COMBOOT image
456     ; .cbt - COMBOOT image
457     ; .c32 - COM32 image
458     ; .bs - Boot sector
459     ; .0 - PXE bootstrap program (PXELINUX only)
460     ; .bin - Boot sector
461     ; .bss - Boot sector, but transfer over DOS superblock (SYSLINUX only)
462     ; .img - Floppy image (ISOLINUX only)
463     ;
464     ; Anything else is assumed to be a Linux kernel.
465     ;
466     section .bss
467     alignb 4
468     Kernel_EAX resd 1
469     Kernel_SI resw 1
470    
471     section .text
472     kernel_good_saved:
473     ; Alternate entry point for which the return from
474     ; searchdir is stored in memory. This is used for
475     ; COMBOOT function INT 22h, AX=0016h.
476     mov si,[Kernel_SI]
477     mov eax,[Kernel_EAX]
478     mov dx,[Kernel_EAX+2]
479    
480     kernel_good:
481     pusha
482     mov si,KernelName
483     mov di,KernelCName
484     call unmangle_name
485     sub di,KernelCName
486     mov [KernelCNameLen],di
487     popa
488    
489     %if IS_SYSLINUX || IS_MDSLINUX
490     mov ecx,[KernelName+7]
491     mov cl,'.'
492     %else
493     push di
494     push ax
495     mov di,KernelName+4*IS_PXELINUX
496     xor al,al
497     mov cx,FILENAME_MAX
498     repne scasb
499     jne .one_step
500     dec di
501     .one_step: mov ecx,[di-4] ; 4 bytes before end
502     pop ax
503     pop di
504     %endif
505    
506     ;
507     ; At this point, DX:AX contains the size of the kernel, and SI contains
508     ; the file handle/cluster pointer.
509     ;
510     or ecx,20202000h ; Force lower case
511    
512     cmp ecx,'.com'
513     je is_comboot_image
514     cmp ecx,'.cbt'
515     je is_comboot_image
516     cmp ecx,'.c32'
517     je is_com32_image
518     %if IS_ISOLINUX
519     cmp ecx,'.img'
520     je is_disk_image
521     %endif
522     cmp ecx,'.bss'
523     je is_bss_sector
524     cmp ecx,'.bin'
525     je is_bootsector
526     %if IS_SYSLINUX || IS_MDSLINUX
527     cmp ecx,'.bs '
528     je is_bootsector
529     cmp ecx,'.0 '
530     je is_bootsector
531     %else
532     shr ecx,8
533     cmp ecx,'.bs'
534     je is_bootsector
535     shr ecx,8
536     cmp cx,'.0'
537     je is_bootsector
538     %endif
539     ; Otherwise Linux kernel
540    
541     section .bss
542     alignb 4
543     ThisKbdTo resd 1 ; Temporary holder for KbdTimeout
544     ThisTotalTo resd 1 ; Temporary holder for TotalTimeout
545     KernelExtPtr resw 1 ; During search, final null pointer
546     CmdOptPtr resw 1 ; Pointer to first option on cmd line
547     KbdFlags resb 1 ; Check for keyboard escapes
548     FuncFlag resb 1 ; Escape sequences received from keyboard
549    
550     section .text