Allow the initrd to be specified on a separate line
[people/xl0/syslinux-lua.git] / core / parseconfig.inc
1 ;; -----------------------------------------------------------------------
2 ;;
3 ;;   Copyright 1994-2008 H. Peter Anvin - All Rights Reserved
4 ;;
5 ;;   This program is free software; you can redistribute it and/or modify
6 ;;   it under the terms of the GNU General Public License as published by
7 ;;   the Free Software Foundation, Inc., 53 Temple Place Ste 330,
8 ;;   Boston MA 02111-1307, USA; either version 2 of the License, or
9 ;;   (at your option) any later version; incorporated herein by reference.
10 ;;
11 ;; -----------------------------------------------------------------------
12
13 ;;
14 ;; parseconfig.inc
15 ;;
16 ;; Configuration file operations
17 ;;
18
19                 section .text
20 ;
21 ; "default" command
22 ;
23 pc_default:     mov di,default_cmd
24                 call getline
25                 mov byte [di-1],0               ; null-terminate
26                 ret
27
28 ;
29 ; "ontimeout" command
30 ;
31 pc_ontimeout:   mov di,Ontimeout
32                 call getline
33                 sub di,Ontimeout+1              ; Don't need final space
34                 mov [OntimeoutLen],di
35                 ret
36
37 ;
38 ; "onerror" command
39 ;
40 pc_onerror:     mov di,Onerror
41                 call getline
42                 sub di,Onerror
43                 mov [OnerrorLen],di
44                 ret
45
46 ;
47 ; "append" command
48 ;
49 pc_append:      cmp byte [VKernel],0
50                 ja .vk
51                 mov di,AppendBuf
52                 call getline
53                 sub di,AppendBuf
54 .app1:          mov [AppendLen],di
55                 ret
56 .vk:            mov di,VKernelBuf+vk_append     ; "append" command (vkernel)
57                 call getline
58                 sub di,VKernelBuf+vk_append
59                 cmp di,byte 2
60                 jne .app2
61                 cmp byte [VKernelBuf+vk_append],'-'
62                 jne .app2
63                 xor di,di                       ; If "append -" -> null string
64 .app2:          mov [VKernelBuf+vk_appendlen],di
65                 ret
66
67 ;
68 ; "ipappend" command (PXELINUX only)
69 ;
70 %if IS_PXELINUX
71 pc_ipappend:    call getint
72                 jc .err
73                 cmp byte [VKernel],0
74                 jne .vk
75                 mov [IPAppend],bl
76 .err:           ret
77 .vk:            mov [VKernelBuf+vk_ipappend],bl
78                 ret
79 %endif
80
81 ;
82 ; "localboot" command (PXELINUX, ISOLINUX)
83 ;
84 %if HAS_LOCALBOOT
85
86 pc_localboot:   call getint
87                 cmp byte [VKernel],0            ; ("label" section only)
88                 je .err
89                 mov di,VKernelBuf+vk_rname
90                 xor ax,ax
91                 mov cx,FILENAME_MAX
92                 rep stosb                       ; Null kernel name
93 %if IS_PXELINUX
94                 ; PXELINUX uses the first 4 bytes of vk_rname for the
95                 ; mangled IP address
96                 mov [VKernelBuf+vk_rname+5], bx ; Return type
97 %else
98                 mov [VKernelBuf+vk_rname+1], bx ; Return type
99 %endif
100 .err:           ret
101
102 %endif ; HAS_LOCALBOOT
103
104 ;
105 ; "kernel", "config", ... command
106 ;
107 pc_kernel:      cmp byte [VKernel],0
108                 je .err                         ; ("label" section only)
109                 mov [VKernelBuf+vk_type],al
110                 call pc_getline
111                 mov di,VKernelBuf+vk_rname
112                 call mangle_name
113 .err:           ret
114
115 ;
116 ; "timeout", "totaltimeout" command
117 ;
118 ; N.B. 1/10 s ~ 1.D2162AABh clock ticks
119 ;
120 pc_timeout:     push ax
121                 call getint
122                 pop si
123                 jc .err
124                 mov eax,0D2162AABh
125                 mul ebx                         ; clock ticks per 1/10 s
126                 add ebx,edx
127                 mov [si],ebx
128 .err:           ret
129
130
131 ;
132 ; "totaltimeout" command
133 ;
134 pc_totaltimeout:
135
136 ;
137 ; Generic integer variable setting commands:
138 ; "prompt", "implicit"
139 ;
140 pc_setint16:
141                 push ax
142                 call getint
143                 pop si
144                 jc .err
145                 mov [si],bx
146 .err:           ret
147
148 ;
149 ; Generic file-processing commands:
150 ; "font", "kbdmap",
151 ;
152 pc_filecmd:     push ax                         ; Function to tailcall
153                 call pc_getline
154                 mov di,MNameBuf
155                 call mangle_name
156                 call searchdir
157                 jnz .ok
158                 pop ax                          ; Drop the successor function
159 .ok:            ret                             ; Tailcall if OK, error return
160
161 ;
162 ; Commands that expect the file to be opened on top of the getc stack.
163 ; "display", "include"
164 ;
165 pc_opencmd:     push ax                         ; Function to tailcall
166                 call pc_getline
167                 mov di,MNameBuf
168                 call mangle_name
169                 call open
170                 jnz .ok
171                 pop ax                          ; Drop the successor function
172 .ok:            ret                             ; Tailcall if OK, error return
173
174 ;
175 ; "include" command (invoked from pc_opencmd)
176 ;
177 pc_include:     inc word [IncludeLevel]
178 .err:           ret
179
180 ;
181 ; "serial" command
182 ;
183 pc_serial:      call getint
184                 jc .err
185                 push bx                         ; Serial port #
186                 call skipspace
187                 jnc .ok
188                 pop bx
189 .err:           ret
190 .ok:
191                 call ungetc
192                 call getint
193                 mov [FlowControl], word 0       ; Default to no flow control
194                 jc .nobaud
195 .valid_baud:
196                 push ebx
197                 call skipspace
198                 jc .no_flow
199                 call ungetc
200                 call getint                     ; Hardware flow control?
201                 jnc .valid_flow
202 .no_flow:
203                 xor bx,bx                       ; Default -> no flow control
204 .valid_flow:
205                 and bh,0Fh                      ; FlowIgnore
206                 shl bh,4
207                 mov [FlowIgnore],bh
208                 mov bh,bl
209                 and bx,0F003h                   ; Valid bits
210                 mov [FlowControl],bx
211                 pop ebx                         ; Baud rate
212                 jmp short .parse_baud
213 .nobaud:
214                 mov ebx,DEFAULT_BAUD            ; No baud rate given
215 .parse_baud:
216                 pop di                          ; Serial port #
217                 cmp ebx,byte 75
218                 jb .err                         ; < 75 baud == bogus
219                 mov eax,BAUD_DIVISOR
220                 cdq
221                 div ebx
222                 mov [BaudDivisor],ax
223                 push ax                         ; Baud rate divisor
224                 cmp di,3
225                 ja .port_is_io                  ; If port > 3 then port is I/O addr
226                 shl di,1
227                 mov di,[di+serial_base]         ; Get the I/O port from the BIOS
228 .port_is_io:
229                 mov [SerialPort],di
230
231                 ;
232                 ; Begin code to actually set up the serial port
233                 ;
234                 lea dx,[di+3]                   ; DX -> LCR
235                 mov al,83h                      ; Enable DLAB
236                 call slow_out
237
238                 pop ax                          ; Divisor
239                 mov dx,di                       ; DX -> LS
240                 call slow_out
241
242                 inc dx                          ; DX -> MS
243                 mov al,ah
244                 call slow_out
245
246                 mov al,03h                      ; Disable DLAB
247                 inc dx                          ; DX -> LCR
248                 inc dx
249                 call slow_out
250
251                 in al,dx                        ; Read back LCR (detect missing hw)
252                 cmp al,03h                      ; If nothing here we'll read 00 or FF
253                 jne .serial_port_bad            ; Assume serial port busted
254                 dec dx
255                 dec dx                          ; DX -> IER
256                 xor al,al                       ; IRQ disable
257                 call slow_out
258
259                 inc dx                          ; DX -> FCR/IIR
260                 mov al,01h
261                 call slow_out                   ; Enable FIFOs if present
262                 in al,dx
263                 cmp al,0C0h                     ; FIFOs enabled and usable?
264                 jae .fifo_ok
265                 xor ax,ax                       ; Disable FIFO if unusable
266                 call slow_out
267 .fifo_ok:
268
269                 inc dx
270                 inc dx                          ; DX -> MCR
271                 in al,dx
272                 or al,[FlowOutput]              ; Assert bits
273                 call slow_out
274
275                 ; Show some life
276                 cmp byte [SerialNotice],0
277                 je .notfirst
278                 mov byte [SerialNotice],0
279
280                 mov si,syslinux_banner
281                 call write_serial_str
282                 mov si,copyright_str
283                 call write_serial_str
284 .notfirst:
285                 ret
286
287 .serial_port_bad:
288                 mov [SerialPort], word 0
289                 ret
290
291 ;
292 ; Store mangled filename command
293 ;
294 pc_filename:    push ax
295                 call pc_getline
296                 pop di
297                 call mangle_name                ; Mangle file name
298                 ret
299
300 ;
301 ; "label" command
302 ;
303 pc_label:       call commit_vk                  ; Commit any current vkernel
304                 mov byte [InitRD+NULLOFFSET],NULLFILE   ; No "initrd" statement
305                 mov di,VKernelBuf               ; Erase the vkernelbuf for better compression
306                 mov cx,(vk_size >> 1)
307                 xor ax,ax
308                 rep stosw
309                 call pc_getline
310                 mov di,VKernelBuf+vk_vname
311                 call mangle_name                ; Mangle virtual name
312                 mov byte [VKernel],1            ; We've seen a "label" statement
313                 mov si,VKernelBuf+vk_vname      ; By default, rname == vname
314                 ; mov di,VKernelBuf+vk_rname    ; -- already set
315                 mov cx,FILENAME_MAX
316                 rep movsb
317                 mov si,AppendBuf                ; Default append==global append
318                 mov di,VKernelBuf+vk_append
319                 mov cx,[AppendLen]
320                 mov [VKernelBuf+vk_appendlen],cx
321                 rep movsb
322 %if IS_PXELINUX                                 ; PXELINUX only
323                 mov al,[IPAppend]               ; Default ipappend==global ipappend
324                 mov [VKernelBuf+vk_ipappend],al
325 %endif
326                 ret
327
328 ;
329 ; "say" command
330 ;
331 pc_say:         call pc_getline                 ; "say" command
332                 call writestr
333                 jmp crlf                        ; tailcall
334
335 ;
336 ; "text" command; ignore everything until we get an "endtext" line
337 ;
338 pc_text:        call pc_getline                 ; Ignore rest of line
339 .loop:
340                 call pc_getline
341                 jc .eof
342
343                 ; Leading spaces are already removed...
344                 lodsd
345                 and eax,0xdfdfdfdf              ; Upper case
346                 cmp eax,'ENDT'
347                 jne .loop
348                 lodsd
349                 and eax,0x00dfdfdf              ; Upper case and mask
350                 cmp eax,'EXT'
351                 jne .loop
352                 ; If we get here we hit ENDTEXT
353 .eof:
354                 ret
355
356 ;
357 ; Comment line
358 ;
359 pc_comment:     ; Fall into pc_getline
360
361 ;
362 ; Common subroutine: load line into trackbuf; returns with SI -> trackbuf
363 ; CF is set on EOF.
364 ;
365 pc_getline:     mov di,trackbuf
366                 push di
367                 call getline
368                 mov byte [di],0                 ; Null-terminate
369                 pop si
370                 ret
371
372 ;
373 ; Main loop for configuration file parsing
374 ;
375 parse_config:
376                 mov di,VKernelBuf               ; Clear VKernelBuf at start
377                 xor ax,ax
378                 mov cx,vk_size
379                 rep stosb
380
381 .again:
382                 call getcommand                 ; Parse one command
383                 jnc .again                      ; If not EOF...
384                 call close
385                 dec word [IncludeLevel]         ; Still parsing?
386                 jnz .again
387
388                 ;
389                 ; The fall through to commit_vk to commit any final
390                 ; VKernel being read
391                 ;
392 ;
393 ; commit_vk: Store the current VKernelBuf into buffer segment
394 ;
395 commit_vk:
396                 cmp byte [VKernel],0
397                 jz .nolabel                     ; Nothing to commit...
398
399                 mov di,VKernelBuf+vk_append
400                 add di,[VKernelBuf+vk_appendlen]
401
402                 ; If we have an initrd statement, append it to the
403                 ; append statement
404                 cmp byte [InitRD+NULLOFFSET],NULLFILE
405                 je .noinitrd
406                 
407                 mov si,initrd_cmd
408                 mov cx,initrd_cmd_len
409                 rep movsb
410                 mov si,InitRD
411                 call unmangle_name
412                 mov al,' '
413                 stosb
414
415                 ; For better compression, clean up the append field
416 .noinitrd:
417                 mov ax,di
418                 sub ax,VKernelBuf+vk_append
419                 mov [VKernelBuf+vk_appendlen],ax
420                 mov cx,max_cmd_len+1
421                 sub cx,ax
422                 xor ax,ax
423                 rep stosb
424
425                 ; Pack into high memory
426                 mov si,VKernelBuf
427                 mov edi,[VKernelEnd]
428                 mov cx,vk_size
429                 call rllpack
430                 mov [VKernelEnd],edi
431 .nolabel:
432                 ret
433 .overflow:
434                 mov si,vk_overflow_msg
435                 call writestr
436                 ret
437
438                 section .data
439 vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0
440 SerialNotice    db 1                    ; Only print this once
441
442                 section .bss
443                 alignb 4
444 VKernelEnd      resd 1                  ; Lowest high memory address used
445
446                 ; This symbol should be used by loaders to indicate
447                 ; the highest address *they* are allowed to use.
448 HighMemRsvd     equ VKernelEnd
449                                         ; by vkernels
450                 section .config
451                 align 4, db 0
452 KbdTimeout      dd 0                    ; Keyboard timeout (if any)
453 TotalTimeout    dd 0                    ; Total timeout (if any)
454 AppendLen       dw 0                    ; Bytes in append= command
455 OntimeoutLen    dw 0                    ; Bytes in ontimeout command
456 OnerrorLen      dw 0                    ; Bytes in onerror command
457 CmdLinePtr      dw cmd_line_here        ; Command line advancing pointer
458 ForcePrompt     dw 0                    ; Force prompt
459 NoEscape        dw 0                    ; No escape
460 AllowImplicit   dw 1                    ; Allow implicit kernels
461 AllowOptions    dw 1                    ; User-specified options allowed
462 IncludeLevel    dw 1                    ; Nesting level
463 SerialPort      dw 0                    ; Serial port base (or 0 for no serial port)
464 VKernel         db 0                    ; Have we seen any "label" statements?
465
466 %if IS_PXELINUX
467 IPAppend        db 0                    ; Default IPAPPEND option
468 %endif
469
470                 section .uibss
471                 alignb 4                ; For the good of REP MOVSD
472 command_line    resb max_cmd_len+2      ; Command line buffer
473                 alignb 4
474 default_cmd     resb max_cmd_len+1      ; "default" command line
475
476 %include "rllpack.inc"