home *** CD-ROM | disk | FTP | other *** search
/ Chip 2005 August (Alt) / CHIP 2005-08.1.iso / program / guvenlik / syslinux-3.07.exe / ui.inc < prev    next >
Encoding:
Text File  |  2004-12-22  |  11.6 KB  |  490 lines

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