Magellan Linux

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 532 - (show 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 ;; $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