summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2009-03-18 20:40:26 -0700
committerH. Peter Anvin <hpa@zytor.com>2009-03-18 20:42:42 -0700
commitff78e2b62a45f18c0d427153f957d2f06c0f5c1c (patch)
tree8ee5c6ed812f739755d91dfe1d4dab64b490fe0e
parent332a924759efe50e783ad3116ecf17d518dfebe2 (diff)
downloadsyslinux-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--NEWS2
-rw-r--r--core/abort.inc12
-rw-r--r--core/getc.inc14
-rw-r--r--core/loadhigh.inc7
-rw-r--r--core/parseconfig.inc4
-rw-r--r--core/runkernel.inc219
-rw-r--r--core/ui.inc10
7 files changed, 178 insertions, 90 deletions
diff --git a/NEWS b/NEWS
index a5aa8912..e9bde135 100644
--- a/NEWS
+++ b/NEWS
@@ -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