summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile23
-rw-r--r--ldlinux.asm6
-rw-r--r--parseconfig.inc342
-rw-r--r--pxelinux.asm293
4 files changed, 363 insertions, 301 deletions
diff --git a/Makefile b/Makefile
index 1e124b71..b7d17a34 100644
--- a/Makefile
+++ b/Makefile
@@ -25,6 +25,8 @@ NINCLUDE =
BINDIR = /usr/bin
LIBDIR = /usr/lib/syslinux
+PERL = perl
+
VERSION = $(shell cat version)
.c.o:
@@ -57,7 +59,7 @@ INSTALL_LIB = pxelinux.0 isolinux.bin isolinux-debug.bin \
# official release. Otherwise, substitute a hex string that is pretty much
# guaranteed to be unique to be unique from build to build.
ifndef HEXDATE
-HEXDATE := $(shell perl now.pl ldlinux.asm pxelinux.asm isolinux.asm)
+HEXDATE := $(shell $(PERL) now.pl ldlinux.asm pxelinux.asm isolinux.asm)
endif
ifndef DATE
DATE := $(HEXDATE)
@@ -77,24 +79,27 @@ samples:
memdisk:
$(MAKE) -C memdisk all
-ldlinux.bin: ldlinux.asm
+kwdhash.inc: keywords
+ $(PERL) genhash.pl < keywords > kwdhash.inc
+
+ldlinux.bin: ldlinux.asm kwdhash.inc
$(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
-dHEXDATE="$(HEXDATE)" \
-l ldlinux.lst -o ldlinux.bin ldlinux.asm
- perl genstupid.pl < ldlinux.lst
+ $(PERL) genstupid.pl < ldlinux.lst
-pxelinux.0: pxelinux.asm pxe.inc
+pxelinux.0: pxelinux.asm kwdhash.inc
$(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
-dHEXDATE="$(HEXDATE)" \
-l pxelinux.lst -o pxelinux.0 pxelinux.asm
-isolinux.bin: isolinux.asm
+isolinux.bin: isolinux.asm kwdhash.inc
$(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
-dHEXDATE="$(HEXDATE)" \
-l isolinux.lst -o isolinux.bin isolinux.asm
# Special verbose version of isolinux.bin
-isolinux-debug.bin: isolinux.asm
+isolinux-debug.bin: isolinux.asm kwdhash.inc
$(NASM) -f bin -dVERSION="'$(VERSION)'" -dDATE_STR="'$(DATE)'" \
-dHEXDATE="$(HEXDATE)" -dDEBUG_MESSAGES \
-l isolinux-debug.lst -o isolinux-debug.bin isolinux.asm
@@ -115,10 +120,10 @@ copybs.com: copybs.asm
$(NASM) -f bin -l copybs.lst -o copybs.com copybs.asm
bootsect_bin.c: ldlinux.bss bin2c.pl
- perl bin2c.pl bootsect < ldlinux.bss > bootsect_bin.c
+ $(PERL) bin2c.pl bootsect < ldlinux.bss > bootsect_bin.c
ldlinux_bin.c: ldlinux.sys bin2c.pl
- perl bin2c.pl ldlinux < ldlinux.sys > ldlinux_bin.c
+ $(PERL) bin2c.pl ldlinux < ldlinux.sys > ldlinux_bin.c
syslinux: syslinux.o bootsect_bin.o ldlinux_bin.o stupid.o
$(CC) $(LDFLAGS) -o syslinux \
@@ -128,7 +133,7 @@ ldlinux.lst: ldlinux.bin
: Generated by side effect
stupid.c: ldlinux.lst genstupid.pl
- perl genstupid.pl < ldlinux.lst
+ $(PERL) genstupid.pl < ldlinux.lst
stupid.inc: stupid.c
: Generated by side effect
diff --git a/ldlinux.asm b/ldlinux.asm
index 4c83e0d2..bbdc1bf3 100644
--- a/ldlinux.asm
+++ b/ldlinux.asm
@@ -37,6 +37,8 @@
;
my_id equ syslinux_id
max_cmd_len equ 255 ; Must be odd; 255 is the kernel limit
+FILENAME_MAX_LG2 equ 4 ; log2(Max filename size Including final null)
+FILENAME_MAX equ 11 ; Max mangled filename size
retry_count equ 6 ; How patient are we with the disk?
HIGHMEM_MAX equ 037FFFFFFh ; DEFAULT highest address for an initrd
DEFAULT_BAUD equ 9600 ; Default baud rate for serial port
@@ -62,8 +64,8 @@ BAUD_DIVISOR equ 115200 ; Serial port parameter
%define vk_size (1 << vk_shift) ; Size of a vkernel buffer
struc vkernel
-vk_vname: resb 11 ; Virtual name **MUST BE FIRST!**
-vk_rname: resb 11 ; Real name
+vk_vname: resb FILENAME_MAX ; Virtual name **MUST BE FIRST!**
+vk_rname: resb FILENAME_MAX ; Real name
vk_appendlen: resw 1
alignb 4
vk_append: resb max_cmd_len+1 ; Command line
diff --git a/parseconfig.inc b/parseconfig.inc
new file mode 100644
index 00000000..fd323666
--- /dev/null
+++ b/parseconfig.inc
@@ -0,0 +1,342 @@
+;; $Id$
+;; -----------------------------------------------------------------------
+;;
+;; Copyright 1994-2002 H. Peter Anvin - All Rights Reserved
+;;
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, Inc., 53 Temple Place Ste 330,
+;; Bostom MA 02111-1307, USA; either version 2 of the License, or
+;; (at your option) any later version; incorporated herein by reference.
+;;
+;; -----------------------------------------------------------------------
+
+;;
+;; parseconfig.inc
+;;
+;; Configuration file operations
+;;
+
+;
+; Main loop for configuration file parsing
+;
+parse_config:
+ call getcommand
+ jnc parse_config ; If not EOF do it again
+ ret ; Return on EOF
+
+;
+; "default" command
+;
+pc_default: mov di,default_cmd
+ call getline
+ xor al,al
+ stosb ; null-terminate
+ ret
+
+;
+; "append" command
+;
+pc_append: cmp word [VKernelCtr],byte 0
+ ja .vk
+ mov di,AppendBuf
+ call getline
+ sub di,AppendBuf
+.app1: mov [AppendLen],di
+ ret
+.vk: mov di,VKernelBuf+vk_append ; "append" command (vkernel)
+ call getline
+ sub di,VKernelBuf+vk_append
+ cmp di,byte 2
+ jne .app2
+ cmp byte [VKernelBuf+vk_append],'-'
+ jne .app2
+ xor di,di ; If "append -" -> null string
+.app2: mov [VKernelBuf+vk_appendlen],di
+ ret
+
+;
+; "ipappend" command (PXELINUX only)
+;
+%if my_id == pxelinux_id
+pc_ipappend: call getint
+ jc .err
+ and bx,bx
+ setnz bl
+ cmp word [VKernelCtr], byte 0
+ jne .vk
+ mov [IPAppend],bl
+.err: ret
+.vk: mov [VKernelBuf+vk_ipappend],bl
+ ret
+%endif
+
+;
+; "localboot" command (PXELINUX, ISOLINUX)
+;
+%if my_id == pxelinux_id || my_id == isolinux_id
+pc_localboot: call getint
+ cmp word [VKernelCtr],byte 0 ; ("label" section only)
+ je .err
+ mov [VKernelBuf+vk_rname], byte 0 ; Null kernel name
+ mov [VKernelBuf+vk_rname+1], bx ; Return type
+.err: ret
+%endif
+
+;
+; "kernel" command
+pc_kernel: cmp word [VKernelCtr],byte 0
+ je .err ; ("label" section only)
+ mov di,trackbuf
+ push di
+ call getline
+ pop si
+ mov di,VKernelBuf+vk_rname
+ call mangle_name
+.err: ret
+
+;
+; "timeout" command
+;
+pc_timeout: call getint
+ jc .err
+ mov ax,0D215h ; There are approx 1.D215h
+ mul bx ; clock ticks per 1/10 s
+ add bx,dx
+ mov [KbdTimeOut],bx
+.err: ret
+
+;
+; "display" command
+;
+pc_display: call pc_getfile
+ jz .err ; File not found?
+ call get_msg_file ; Load and display file
+.err: ret
+
+;
+; "prompt" command
+;
+pc_prompt: call getint
+ jc .err
+ mov [ForcePrompt],bx
+.err: ret
+
+;
+; "implicit" command
+;
+pc_implicit: call getint
+ jc .err
+ mov [AllowImplicit],bx
+.err: ret
+
+;
+; "serial" command
+;
+pc_serial: call getint
+ jc .err
+ push bx ; Serial port #
+ call skipspace
+ jnc .ok
+ pop bx
+.err: ret
+.ok:
+ call ungetc
+ call getint
+ mov [FlowControl], word 0 ; Default to no flow control
+ jc .nobaud
+.valid_baud:
+ push ebx
+ call skipspace
+ jc .no_flow
+ call ungetc
+ call getint ; Hardware flow control?
+ jnc .valid_flow
+.no_flow:
+ xor bx,bx ; Default -> no flow control
+.valid_flow:
+ and bh,0Fh ; FlowIgnore
+ shl bh,4
+ mov [FlowIgnore],bh
+ mov bh,bl
+ and bx,0F003h ; Valid bits
+ mov [FlowControl],bx
+ pop ebx ; Baud rate
+ jmp short .parse_baud
+.nobaud:
+ mov ebx,DEFAULT_BAUD ; No baud rate given
+.parse_baud:
+ pop di ; Serial port #
+ cmp ebx,byte 75
+ jb parse_config_2 ; < 75 baud == bogus
+ mov eax,BAUD_DIVISOR
+ cdq
+ div ebx
+ push ax ; Baud rate divisor
+ cmp di,3
+ ja .port_is_io ; If port > 3 then port is I/O addr
+ shl di,1
+ mov di,[di+serial_base] ; Get the I/O port from the BIOS
+.port_is_io:
+ mov [SerialPort],di
+ lea dx,[di+3] ; DX -> LCR
+ mov al,83h ; Enable DLAB
+ call slow_out
+ pop ax ; Divisor
+ mov dx,di ; DX -> LS
+ call slow_out
+ inc dx ; DX -> MS
+ mov al,ah
+ call slow_out
+ mov al,03h ; Disable DLAB
+ add dx,byte 2 ; DX -> LCR
+ call slow_out
+ in al,dx ; Read back LCR (detect missing hw)
+ cmp al,03h ; If nothing here we'll read 00 or FF
+ jne .serial_port_bad ; Assume serial port busted
+ sub dx,byte 2 ; DX -> IER
+ xor al,al ; IRQ disable
+ call slow_out
+
+ add dx,byte 3 ; DX -> MCR
+ in al,dx
+ or al,[FlowOutput] ; Assert bits
+ call slow_out
+
+ ; Show some life
+ mov si,pxelinux_banner
+ call write_serial_str
+ mov si,copyright_str
+ call write_serial_str
+ ret
+
+.serial_port_bad:
+ mov [SerialPort], word 0
+ ret
+
+;
+; "F"-key command
+;
+; This relies on the fact that [si] points to the address of the entrypoint
+;
+pc_f1: nop
+pc_f2: nop
+pc_f3: nop
+pc_f4: nop
+pc_f5: nop
+pc_f6: nop
+pc_f7: nop
+pc_f8: nop
+pc_f9: nop
+pc_f10:
+ mov cx,[si]
+ sub cx,pc_f1
+ push cx
+ mov ax,1
+ shl ax,cl
+ or [FKeyMap], ax ; Mark that we have this loaded
+ mov di,trackbuf
+ push di
+ call getline ; Get filename to display
+ pop si
+ pop di
+ shl di,FILENAME_MAX_LG2 ; Convert to offset
+ add di,FKeyName
+ call mangle_name ; Mangle file name
+ ret
+
+;
+; "label" command
+;
+pc_label: call commit_vk ; Commit any current vkernel
+ mov di,trackbuf ; Get virtual filename
+ push di
+ call getline
+ pop si
+ mov di,VKernelBuf+vk_vname
+ call mangle_name ; Mangle virtual name
+ inc word [VKernelCtr] ; One more vkernel
+ mov si,VKernelBuf+vk_vname ; By default, rname == vname
+ mov di,VKernelBuf+vk_rname
+ mov cx,FILENAME_MAX
+ rep movsb
+ mov si,AppendBuf ; Default append==global append
+ mov di,VKernelBuf+vk_append
+ mov cx,[AppendLen]
+ mov [VKernelBuf+vk_appendlen],cx
+ rep movsb
+ mov al,[IPAppend] ; Default ipappend==global ipappend
+ mov [VKernelBuf+vk_ipappend],al
+ ret
+
+;
+; "font" command
+;
+pc_font: call pc_getfile ; "font" command
+ jz .err ; File not found?
+ call loadfont ; Load and install font
+.err: ret
+
+;
+; "kbd" command
+;
+pc_kbd: call pc_getfile ; "kbd" command
+ jz .err
+ call loadkeys
+.err: ret
+
+;
+; "say" command
+;
+pc_say: mov di,trackbuf ; "say" command
+ push di
+ call getline
+ xor al,al
+ stosb ; Null-terminate
+ pop si
+ call writestr
+ jmp crlf ; tailcall
+
+;
+; pc_getfile: For command line options that take file argument, this
+; routine decodes the file argument and runs it through searchdir
+;
+pc_getfile: mov di,trackbuf
+ push di
+ call getline
+ pop si
+ mov di,MNameBuf
+ push di
+ call mangle_name
+ pop di
+ jmp searchdir ; tailcall
+
+;
+; commit_vk: Store the current VKernelBuf into buffer segment
+;
+commit_vk:
+ cmp word [VKernelCtr],byte 0
+ je cvk_ret ; No VKernel = return
+ cmp word [VKernelCtr],max_vk ; Above limit?
+ ja cvk_overflow
+ mov di,[VKernelCtr]
+ dec di
+ shl di,vk_shift
+ mov si,VKernelBuf
+ mov cx,(vk_size >> 2)
+ push es
+ push word vk_seg
+ pop es
+ rep movsd ; Copy to buffer segment
+ pop es
+cvk_ret: ret
+cvk_overflow: mov word [VKernelCtr],max_vk ; No more than max_vk, please
+ ret
+
+;
+; End of configuration file
+;
+; Commit vkernel and then return
+;
+end_config_file equ commit_vk
+
diff --git a/pxelinux.asm b/pxelinux.asm
index 18299f89..38b77a86 100644
--- a/pxelinux.asm
+++ b/pxelinux.asm
@@ -808,296 +808,7 @@ config_scan:
; Now we have the config file open
;
.success: add sp,byte 16 ; Adjust stack
-parse_config:
- call getkeyword
- jc near end_config_file ; Config file loaded
- cmp ax,'de' ; DEfault
- je pc_default
- cmp ax,'ap' ; APpend
- je pc_append
- cmp ax,'ti' ; TImeout
- je near pc_timeout
- cmp ax,'pr' ; PRompt
- je near pc_prompt
- cmp ax,'fo' ; FOnt
- je near pc_font
- cmp ax,'kb' ; KBd
- je near pc_kbd
- cmp ax,'di' ; DIsplay
- je near pc_display
- cmp ax,'la' ; LAbel
- je near pc_label
- cmp ax,'ke' ; KErnel
- je near pc_kernel
- cmp ax,'im' ; IMplicit
- je near pc_implicit
- cmp ax,'se' ; SErial
- je near pc_serial
- cmp ax,'sa' ; SAy
- je near pc_say
- cmp ax,'ip' ; IPappend
- je pc_ipappend
- cmp ax,'lo' ; LOcalboot
- je pc_localboot
- cmp al,'f' ; F-key
- jne parse_config
- jmp pc_fkey
-
-pc_default: mov di,default_cmd ; "default" command
- call getline
- xor al,al
- stosb ; null-terminate
- jmp short parse_config
-
-pc_append: cmp word [VKernelCtr],byte 0 ; "append" command
- ja pc_append_vk
- mov di,AppendBuf
- call getline
- sub di,AppendBuf
-pc_app1: mov [AppendLen],di
- jmp short parse_config_2
-pc_append_vk: mov di,VKernelBuf+vk_append ; "append" command (vkernel)
- call getline
- sub di,VKernelBuf+vk_append
- cmp di,byte 2
- jne pc_app2
- cmp byte [VKernelBuf+vk_append],'-'
- jne pc_app2
- mov di,0 ; If "append -" -> null string
-pc_app2: mov [VKernelBuf+vk_appendlen],di
- jmp short parse_config_2
-
-pc_ipappend: call getint ; "ipappend" command
- jc parse_config_2
- and bx,bx
- setnz bl
- cmp word [VKernelCtr], byte 0
- jne .vk
- mov [IPAppend],bl
- jmp short parse_config_2
-.vk: mov [VKernelBuf+vk_ipappend],bl
- jmp short parse_config_2
-
-pc_localboot: call getint ; "localboot" command
- cmp word [VKernelCtr],byte 0 ; ("label" section only)
- je parse_config_2
- mov [VKernelBuf+vk_rname], byte 0 ; Null kernel name
- mov [VKernelBuf+vk_rname+1], bx ; Return type
- jmp short parse_config_2
-
-pc_kernel: cmp word [VKernelCtr],byte 0 ; "kernel" command
- je parse_config_2 ; ("label" section only)
- mov di,trackbuf
- push di
- call getline
- pop si
- mov di,VKernelBuf+vk_rname
- call mangle_name
- jmp short parse_config_2
-
-pc_timeout: call getint ; "timeout" command
- jc parse_config_2
- mov ax,0D215h ; There are approx 1.D215h
- mul bx ; clock ticks per 1/10 s
- add bx,dx
- mov [KbdTimeOut],bx
-parse_config_2: jmp parse_config
-
-pc_display: call pc_getfile ; "display" command
- jz parse_config_2 ; File not found?
- call get_msg_file ; Load and display file
- jmp short parse_config_2
-
-pc_prompt: call getint ; "prompt" command
- jc parse_config_2
- mov [ForcePrompt],bx
- jmp short parse_config_2
-
-pc_implicit: call getint ; "implicit" command
- jc parse_config_2
- mov [AllowImplicit],bx
- jmp short parse_config_2
-
-pc_serial: call getint ; "serial" command
- jc parse_config_2
- push bx ; Serial port #
- call skipspace
- jc parse_config_2
- call ungetc
- call getint
- mov [FlowControl], word 0 ; Default to no flow control
- jc .nobaud
-.valid_baud:
- push ebx
- call skipspace
- jc .no_flow
- call ungetc
- call getint ; Hardware flow control?
- jnc .valid_flow
-.no_flow:
- xor bx,bx ; Default -> no flow control
-.valid_flow:
- and bh,0Fh ; FlowIgnore
- shl bh,4
- mov [FlowIgnore],bh
- mov bh,bl
- and bx,0F003h ; Valid bits
- mov [FlowControl],bx
- pop ebx ; Baud rate
- jmp short .parse_baud
-.nobaud:
- mov ebx,DEFAULT_BAUD ; No baud rate given
-.parse_baud:
- pop di ; Serial port #
- cmp ebx,byte 75
- jb parse_config_2 ; < 75 baud == bogus
- mov eax,BAUD_DIVISOR
- cdq
- div ebx
- push ax ; Baud rate divisor
- cmp di,3
- ja .port_is_io ; If port > 3 then port is I/O addr
- shl di,1
- mov di,[di+serial_base] ; Get the I/O port from the BIOS
-.port_is_io:
- mov [SerialPort],di
- lea dx,[di+3] ; DX -> LCR
- mov al,83h ; Enable DLAB
- call slow_out
- pop ax ; Divisor
- mov dx,di ; DX -> LS
- call slow_out
- inc dx ; DX -> MS
- mov al,ah
- call slow_out
- mov al,03h ; Disable DLAB
- add dx,byte 2 ; DX -> LCR
- call slow_out
- in al,dx ; Read back LCR (detect missing hw)
- cmp al,03h ; If nothing here we'll read 00 or FF
- jne .serial_port_bad ; Assume serial port busted
- sub dx,byte 2 ; DX -> IER
- xor al,al ; IRQ disable
- call slow_out
-
- add dx,byte 3 ; DX -> MCR
- in al,dx
- or al,[FlowOutput] ; Assert bits
- call slow_out
-
- ; Show some life
- mov si,pxelinux_banner
- call write_serial_str
- mov si,copyright_str
- call write_serial_str
-
- jmp short parse_config_3
-
-.serial_port_bad:
- mov [SerialPort], word 0
- jmp short parse_config_3
-
-pc_fkey: sub ah,'1'
- jnb pc_fkey1
- mov ah,9 ; F10
-pc_fkey1: xor cx,cx
- mov cl,ah
- push cx
- mov ax,1
- shl ax,cl
- or [FKeyMap], ax ; Mark that we have this loaded
- mov di,trackbuf
- push di
- call getline ; Get filename to display
- pop si
- pop di
- shl di,FILENAME_MAX_LG2 ; Convert to offset
- add di,FKeyName
- call mangle_name ; Mangle file name
- jmp short parse_config_3
-
-pc_label: call commit_vk ; Commit any current vkernel
- mov di,trackbuf ; Get virtual filename
- push di
- call getline
- pop si
- mov di,VKernelBuf+vk_vname
- call mangle_name ; Mangle virtual name
- inc word [VKernelCtr] ; One more vkernel
- mov si,VKernelBuf+vk_vname ; By default, rname == vname
- mov di,VKernelBuf+vk_rname
- mov cx,FILENAME_MAX
- rep movsb
- mov si,AppendBuf ; Default append==global append
- mov di,VKernelBuf+vk_append
- mov cx,[AppendLen]
- mov [VKernelBuf+vk_appendlen],cx
- rep movsb
- mov al,[IPAppend] ; Default ipappend==global ipappend
- mov [VKernelBuf+vk_ipappend],al
- jmp near parse_config_3
-
-pc_font: call pc_getfile ; "font" command
- jz parse_config_3 ; File not found?
- call loadfont ; Load and install font
- jmp short parse_config_3
-
-pc_kbd: call pc_getfile ; "kbd" command
- jz parse_config_3
- call loadkeys
-parse_config_3: jmp parse_config
-
-pc_say: mov di,trackbuf ; "say" command
- push di
- call getline
- xor al,al
- stosb ; Null-terminate
- pop si
- call writestr
- call crlf
- jmp short parse_config_3
-
-;
-; pc_getfile: For command line options that take file argument, this
-; routine decodes the file argument and runs it through searchdir
-;
-pc_getfile: mov di,trackbuf
- push di
- call getline
- pop si
- mov di,MNameBuf
- push di
- call mangle_name
- pop di
- jmp searchdir ; Tailcall
-
-;
-; commit_vk: Store the current VKernelBuf into buffer segment
-;
-commit_vk:
- cmp word [VKernelCtr],byte 0
- je cvk_ret ; No VKernel = return
- cmp word [VKernelCtr],max_vk ; Above limit?
- ja cvk_overflow
- mov di,[VKernelCtr]
- dec di
- shl di,vk_shift
- mov si,VKernelBuf
- mov cx,(vk_size >> 2)
- push es
- push word vk_seg
- pop es
- rep movsd ; Copy to buffer segment
- pop es
-cvk_ret: ret
-cvk_overflow: mov word [VKernelCtr],max_vk ; No more than max_vk, please
- ret
-
-;
-; End of configuration file
-;
-end_config_file:
- call commit_vk ; Commit any current vkernel
+ call parse_config ; Parse configuration file
no_config_file:
;
; Check whether or not we are supposed to display the boot prompt.
@@ -3668,6 +3379,8 @@ genipopt:
%include "writestr.inc" ; String output
writestr equ cwritestr
%include "writehex.inc" ; Hexadecimal output
+%include "parseconfig.inc" ; High-level config file handling
+%include "parsecmd.inc" ; Low-level config file handling
%include "font.inc" ; VGA font stuff
%include "graphics.inc" ; VGA graphics