diff options
author | H. Peter Anvin <hpa@zytor.com> | 2009-03-18 20:40:26 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@zytor.com> | 2009-03-18 20:42:42 -0700 |
commit | ff78e2b62a45f18c0d427153f957d2f06c0f5c1c (patch) | |
tree | 8ee5c6ed812f739755d91dfe1d4dab64b490fe0e | |
parent | 332a924759efe50e783ad3116ecf17d518dfebe2 (diff) | |
download | syslinux-ff78e2b62a45f18c0d427153f957d2f06c0f5c1c.tar.gz |
Refactor command line parsing; support "quiet" optionsyslinux-3.74-pre7
Refactor the command line parser to be more of a general parser
instead of treating each option as an ad hoc feature.
Suppress the Loading... prompt if "quiet" is specified on the command
line. Some messed-up people want it this way.
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | core/abort.inc | 12 | ||||
-rw-r--r-- | core/getc.inc | 14 | ||||
-rw-r--r-- | core/loadhigh.inc | 7 | ||||
-rw-r--r-- | core/parseconfig.inc | 4 | ||||
-rw-r--r-- | core/runkernel.inc | 219 | ||||
-rw-r--r-- | core/ui.inc | 10 |
7 files changed, 178 insertions, 90 deletions
@@ -22,6 +22,8 @@ Changes in 3.74: for a large floppy disk image if (and only if) it is formatted with a FAT filesystem. * SYSLINUX: fix the handling of .bss files on FAT12/16. + * Suppress the Loading ... message if "quiet" is specified on + the kernel command line. Changes in 3.73: * Upgrade gPXE to release version 0.9.5. diff --git a/core/abort.inc b/core/abort.inc index 12d00063..19cc6419 100644 --- a/core/abort.inc +++ b/core/abort.inc @@ -17,6 +17,18 @@ ; section .text + +; +; dot_pause: same as abort_check, except prints a dot, too +; assumes CS == DS +; +dot_pause: + push si + mov si,dot_msg + call writestr_qchk + pop si + ; fall through + ; ; abort_check: let the user abort with <ESC> or <Ctrl-C> ; diff --git a/core/getc.inc b/core/getc.inc index ec8dab2a..4c273a2b 100644 --- a/core/getc.inc +++ b/core/getc.inc @@ -244,6 +244,20 @@ getint: ; Fall through to parseint ; +; parseint_esdi: +; Same as parseint, but takes the input in ES:DI +; +parseint_esdi: + push ds + push es + pop ds + xchg si,di + call parseint + xchg si,di + pop ds + ret + +; ; parseint: Convert an integer to a number in EBX ; Get characters from string in DS:SI ; Return CF on error diff --git a/core/loadhigh.inc b/core/loadhigh.inc index 63041483..21d4cc6f 100644 --- a/core/loadhigh.inc +++ b/core/loadhigh.inc @@ -102,13 +102,6 @@ load_high: .overflow: mov si,err_nohighmem jmp abort_load -dot_pause: - push ax - mov al,'.' - call writechr - pop ax - jmp abort_check ; Handles the return - section .data err_nohighmem db CR, LF db 'Not enough memory to load specified image.', CR, LF, 0 diff --git a/core/parseconfig.inc b/core/parseconfig.inc index 2f0db489..37fe97fe 100644 --- a/core/parseconfig.inc +++ b/core/parseconfig.inc @@ -413,8 +413,8 @@ commit_vk: cmp byte [InitRD+NULLOFFSET],NULLFILE je .noinitrd - mov si,initrd_cmd - mov cx,initrd_cmd_len + mov si,str_initrd + mov cx,7 ; "initrd=" rep movsb mov si,InitRD call unmangle_name diff --git a/core/runkernel.inc b/core/runkernel.inc index f42abf08..fe392c0f 100644 --- a/core/runkernel.inc +++ b/core/runkernel.inc @@ -46,11 +46,6 @@ ; is_linux_kernel: push si ; <A> file pointer - mov si,loading_msg - call writestr - mov si,KernelCName ; Print kernel name part of - call writestr ; "Loading" message - ; ; Now start transferring the kernel @@ -63,7 +58,7 @@ is_linux_kernel: ; do something funky. It should fit in the first 32K (loading 64K won't ; work since we might have funny stuff up near the end of memory). ; - call dot_pause ; Check for abort key + call abort_check ; Check for abort key mov cx,8000h >> SECTOR_SHIFT ; Half a moby (32K) xor bx,bx pop si ; <A> file pointer @@ -102,83 +97,112 @@ construct_cmdline: ; interested in. The original version of this code automatically assumed ; the first option was BOOT_IMAGE=, but that is no longer certain. ; - mov si,cmd_line_here +parse_cmdline: + mov di,cmd_line_here xor ax,ax - mov [InitRDPtr],ax ; No initrd= option (yet) - push es ; Set DS <- real_mode_seg - pop ds -get_next_opt: lodsb + mov [InitRDPtr],ax ; No initrd= option (yet) + mov [QuietBoot],al +%if IS_PXELINUX + and byte [KeepPXE],~2 +%endif +.skipspace: mov al,[es:di] + inc di +.skipspace_loaded: and al,al jz cmdline_end cmp al,' ' - jbe get_next_opt - dec si - mov eax,[si] - cmp eax,'vga=' - je is_vga_cmd - cmp eax,'mem=' - je is_mem_cmd -%if IS_PXELINUX - cmp eax,'keep' ; Is it "keeppxe"? - jne .notkeep - cmp dword [si+3],'ppxe' - jne .notkeep - cmp byte [si+7],' ' ; Must be whitespace or EOS - ja .notkeep - or byte [cs:KeepPXE],1 -.notkeep: -%endif - push es ; <B> ES -> real_mode_seg - push cs - pop es ; Set ES <- normal DS - mov di,initrd_cmd - mov cx,initrd_cmd_len - repe cmpsb - jne .not_initrd + jbe .skipspace + dec di + ; ES:DI now points to the beginning of an option + mov bx,options_list + mov cx,options_list_len +.next_opt: + push di + mov si,[bx] + add bx,4 +.next_char: + lodsb + and al,al + jz .end_opt + scasb + jne .not_equal + cmp al,'=' + jne .next_char +.is_match: + pop ax ; Drop pointer to the option + call [bx-2] +.skip_opt: + mov al,[es:di] + inc di cmp al,' ' - jbe .noramdisk - mov [cs:InitRDPtr],si - jmp .not_initrd -.noramdisk: - xor ax,ax - mov [cs:InitRDPtr],ax -.not_initrd: pop es ; <B> ES -> real_mode_seg -skip_this_opt: lodsb ; Load from command line - cmp al,' ' - ja skip_this_opt - dec si - jmp short get_next_opt -is_vga_cmd: - add si,4 - mov eax,[si-1] - mov bx,-1 - cmp eax,'=nor' ; vga=normal - je vc0 + ja .skip_opt + jmp .skipspace_loaded +.not_equal: + pop di + loop .next_opt + jmp .skip_opt +.end_opt: + ; End of a unitary option (no equal sign) - match whitespace + cmp byte [es:di],' ' + ja .not_equal + jmp .is_match + + section .rodata + section .text +opt_vga: + mov eax,[es:di-1] + mov bx,-1 + cmp eax,'=nor' ; vga=normal + je .vc0 dec bx ; bx <- -2 - cmp eax,'=ext' ; vga=ext - je vc0 - dec bx ; bx <- -3 - cmp eax,'=ask' ; vga=ask - je vc0 - call parseint ; vga=<number> - jc skip_this_opt ; Not an integer -vc0: mov [bs_vidmode],bx ; Set video mode - jmp short skip_this_opt -is_mem_cmd: - add si,4 - call parseint - jc skip_this_opt ; Not an integer + cmp eax,'=ext' ; vga=ext + je .vc0 + dec bx ; bx <- -3 + cmp eax,'=ask' ; vga=ask + je .vc0 + call parseint_esdi ; vga=<number> + jc .skip ; Not an integer +.vc0: mov [es:bs_vidmode],bx ; Set video mode +.skip: + ret + +opt_mem: + call parseint_esdi + jc .skip %if HIGHMEM_SLOP != 0 sub ebx,HIGHMEM_SLOP %endif - mov [cs:MyHighMemSize],ebx - jmp short skip_this_opt + mov [MyHighMemSize],ebx +.skip: + ret + +opt_quiet: + mov byte [QuietBoot],1 + ret + +%if IS_PXELINUX +opt_keeppxe: + or byte [KeepPXE],2 ; KeepPXE set by command line + ret +%endif + +opt_initrd: + mov ax,di + cmp byte [es:di],' ' + ja .have_initrd + xor ax,ax +.have_initrd: + mov [InitRDPtr],ax + ret + +; +; After command line parsing... +; cmdline_end: - push cs ; Restore standard DS - pop ds - sub si,cmd_line_here - mov [CmdLineLen],si ; Length including final null + sub di,cmd_line_here + mov [CmdLineLen],di ; Length including final null + ; ; Now check if we have a large kernel, which needs to be loaded high ; @@ -217,6 +241,10 @@ new_kernel: mov [LoadFlags],al any_kernel: + mov si,loading_msg + call writestr_qchk + mov si,KernelCName ; Print kernel name part of + call writestr_qchk ; "Loading" message ; ; Load the kernel. We always load it at 100000h even if we're supposed to @@ -263,7 +291,8 @@ high_load_done: mov es,ax mov si,dot_msg - call writestr + call writestr_qchk + ; ; Some older kernels (1.2 era) would have more than 4 setup sectors, but ; would not rely on the boot protocol to manage that. These kernels fail @@ -304,7 +333,7 @@ load_initrd: call abort_check ; Last chance!! mov si,ready_msg - call writestr + call writestr_qchk UNLOAD_PREP ; Module-specific hook @@ -581,13 +610,14 @@ loadinitrd: push si mov si,crlfloading_msg ; Write "Loading " - call writestr + call writestr_qchk mov si,InitRDCName ; Write ramdisk name - call writestr + call writestr_qchk mov si,dotdot_msg ; Write dots - call writestr + call writestr_qchk pop si +.li_skip_echo: mov dx,3 mov bx,dot_pause call load_high @@ -605,6 +635,15 @@ loadinitrd: mov si,crlf_msg jmp abort_load +; +; writestr_qchk: writestr, except allows output to be suppressed +; assumes CS == DS +; +writestr_qchk: + test byte [QuietBoot],01h + jz writestr + ret + section .data crlfloading_msg db CR, LF loading_msg db 'Loading ', 0 @@ -621,9 +660,23 @@ boot_image_len equ $-boot_image ; ; Command line options we'd like to take a look at ; -; mem= and vga= are handled as normal 32-bit integer values -initrd_cmd db 'initrd=' -initrd_cmd_len equ $-initrd_cmd +options_list: + dw str_vga, opt_vga + dw str_mem, opt_mem + dw str_quiet, opt_quiet + dw str_initrd, opt_initrd +%if IS_PXELINUX + dw str_keeppxe, opt_keeppxe +%endif +options_list_len equ ($-options_list)/4 + +str_vga db 'vga=' +str_mem db 'mem=' +str_quiet db 'quiet',0 +str_initrd db 'initrd=' +%if IS_PXELINUX +str_keeppxe db 'keeppxe',0 +%endif section .bss alignb 4 @@ -637,6 +690,10 @@ InitRDEnd resd 1 ; End of initrd (pre-relocation) CmdLineLen resw 1 ; Length of command line including null CmdLineEnd resw 1 ; End of the command line in real_mode_seg SetupSecs resw 1 ; Number of setup sectors (+bootsect) -InitRDPtr resw 1 ; Pointer to initrd= option in command line KernelVersion resw 1 ; Kernel protocol version +; +; These +; +InitRDPtr resw 1 ; Pointer to initrd= option in command line LoadFlags resb 1 ; Loadflags from kernel +QuietBoot resb 1 ; Set if a quiet boot is requested diff --git a/core/ui.inc b/core/ui.inc index 7f88cda0..937dd526 100644 --- a/core/ui.inc +++ b/core/ui.inc @@ -309,6 +309,16 @@ command_done: load_kernel: ; Load the kernel now ; +; Common initialization for all kernel types +; + xor ax,ax + mov [InitRDPtr],ax + mov [QuietBoot],al +%if IS_PXELINUX + mov [KeepPXE],al +%endif + +; ; First we need to mangle the kernel name the way DOS would... ; mov si,command_line |