|
;; $Id: parseconfig.inc,v 1.1 2007-09-01 22:44:05 niro Exp $ |
|
1 |
;; ----------------------------------------------------------------------- |
;; ----------------------------------------------------------------------- |
2 |
;; |
;; |
3 |
;; Copyright 1994-2004 H. Peter Anvin - All Rights Reserved |
;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved |
4 |
|
;; Copyright 2009 Intel Corporation; author: H. Peter Anvin |
5 |
;; |
;; |
6 |
;; This program is free software; you can redistribute it and/or modify |
;; 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 |
;; it under the terms of the GNU General Public License as published by |
19 |
|
|
20 |
section .text |
section .text |
21 |
; |
; |
22 |
; "default" command |
; "default" or "ui" command, with level (1 = default, 2 = ui) |
23 |
; |
; |
24 |
pc_default: mov di,default_cmd |
pc_default: cmp ax,[DefaultLevel] |
25 |
|
jb skipline ; == call skipline + ret |
26 |
|
mov [DefaultLevel],ax |
27 |
|
mov di,default_cmd |
28 |
call getline |
call getline |
29 |
mov byte [di-1],0 ; null-terminate |
mov byte [di-1],0 ; null-terminate |
30 |
ret |
ret |
55 |
mov di,AppendBuf |
mov di,AppendBuf |
56 |
call getline |
call getline |
57 |
sub di,AppendBuf |
sub di,AppendBuf |
58 |
.app1: mov [AppendLen],di |
.app1: mov [AppendLen],di |
59 |
ret |
ret |
60 |
.vk: mov di,VKernelBuf+vk_append ; "append" command (vkernel) |
.vk: mov di,VKernelBuf+vk_append ; "append" command (vkernel) |
61 |
call getline |
call getline |
83 |
%endif |
%endif |
84 |
|
|
85 |
; |
; |
86 |
; "localboot" command (PXELINUX, ISOLINUX) |
; "localboot" command |
87 |
; |
; |
88 |
%if IS_PXELINUX || IS_ISOLINUX |
%if HAS_LOCALBOOT |
89 |
|
|
90 |
pc_localboot: call getint |
pc_localboot: call getint |
91 |
cmp byte [VKernel],0 ; ("label" section only) |
cmp byte [VKernel],0 ; ("label" section only) |
92 |
je .err |
je .err |
93 |
mov di,VKernelBuf+vk_rname |
mov [VKernelBuf+vk_rname],bx |
94 |
xor ax,ax |
mov byte [VKernelBuf+vk_type],VK_LOCALBOOT |
|
mov cx,FILENAME_MAX |
|
|
rep stosb ; Null kernel name |
|
|
%if IS_PXELINUX |
|
|
; PXELINUX uses the first 4 bytes of vk_rname for the |
|
|
; mangled IP address |
|
|
mov [VKernelBuf+vk_rname+5], bx ; Return type |
|
|
%else |
|
|
mov [VKernelBuf+vk_rname+1], bx ; Return type |
|
|
%endif |
|
95 |
.err: ret |
.err: ret |
|
%endif |
|
96 |
|
|
97 |
|
%endif ; HAS_LOCALBOOT |
98 |
|
|
99 |
|
; |
100 |
|
; "kernel", "config", ... command |
101 |
; |
; |
|
; "kernel" command |
|
102 |
pc_kernel: cmp byte [VKernel],0 |
pc_kernel: cmp byte [VKernel],0 |
103 |
je .err ; ("label" section only) |
je .err ; ("label" section only) |
104 |
|
mov [VKernelBuf+vk_type],al |
105 |
call pc_getline |
call pc_getline |
106 |
mov di,VKernelBuf+vk_rname |
mov di,VKernelBuf+vk_rname |
107 |
call mangle_name |
call mangle_name |
142 |
|
|
143 |
; |
; |
144 |
; Generic file-processing commands: |
; Generic file-processing commands: |
145 |
; "display", "font", "kbdmap" |
; "font", "kbdmap", |
146 |
; |
; |
147 |
pc_filecmd: push ax ; Function to tailcall |
pc_filecmd: push ax ; Function to tailcall |
148 |
call pc_getline |
call pc_getline |
149 |
mov di,MNameBuf |
mov di,MNameBuf |
|
push di |
|
150 |
call mangle_name |
call mangle_name |
151 |
pop di |
call searchdir |
|
call searchdir ; tailcall |
|
152 |
jnz .ok |
jnz .ok |
153 |
pop ax ; Drop the successor function |
pop ax ; Drop the successor function |
154 |
.ok: ret ; Tailcall if OK, error return |
.ok: ret ; Tailcall if OK, error return |
155 |
|
|
156 |
; |
; |
157 |
|
; Commands that expect the file to be opened on top of the getc stack. |
158 |
|
; "display", "include" |
159 |
|
; |
160 |
|
pc_opencmd: push ax ; Function to tailcall |
161 |
|
call pc_getline |
162 |
|
mov di,MNameBuf |
163 |
|
call mangle_name |
164 |
|
call open |
165 |
|
jnz .ok |
166 |
|
pop ax ; Drop the successor function |
167 |
|
.ok: ret ; Tailcall if OK, error return |
168 |
|
|
169 |
|
; |
170 |
|
; "include" command (invoked from pc_opencmd) |
171 |
|
; |
172 |
|
pc_include: inc word [IncludeLevel] |
173 |
|
.err: ret |
174 |
|
|
175 |
|
; |
176 |
; "serial" command |
; "serial" command |
177 |
; |
; |
178 |
pc_serial: call getint |
pc_serial: call getint |
179 |
jc .err |
jc .err |
180 |
push bx ; Serial port # |
push bx ; Serial port # |
181 |
|
xor eax,eax |
182 |
|
mov [FlowControl],eax ; Default to no flow control |
183 |
call skipspace |
call skipspace |
184 |
jnc .ok |
jc .nobaud |
|
pop bx |
|
|
.err: ret |
|
|
.ok: |
|
185 |
call ungetc |
call ungetc |
186 |
call getint |
call getint |
|
mov [FlowControl], word 0 ; Default to no flow control |
|
187 |
jc .nobaud |
jc .nobaud |
188 |
.valid_baud: |
.valid_baud: |
189 |
push ebx |
push ebx |
190 |
call skipspace |
call skipspace |
191 |
jc .no_flow |
jc .no_flow |
199 |
shl bh,4 |
shl bh,4 |
200 |
mov [FlowIgnore],bh |
mov [FlowIgnore],bh |
201 |
mov bh,bl |
mov bh,bl |
202 |
and bx,0F003h ; Valid bits |
and bx,0F00Bh ; Valid bits |
203 |
mov [FlowControl],bx |
mov [FlowControl],bx |
204 |
pop ebx ; Baud rate |
pop ebx ; Baud rate |
205 |
jmp short .parse_baud |
jmp short .parse_baud |
224 |
; |
; |
225 |
; Begin code to actually set up the serial port |
; Begin code to actually set up the serial port |
226 |
; |
; |
227 |
|
call sirq_cleanup_nowipe ; Cleanup existing IRQ handler |
228 |
|
|
229 |
lea dx,[di+3] ; DX -> LCR |
lea dx,[di+3] ; DX -> LCR |
230 |
mov al,83h ; Enable DLAB |
mov al,83h ; Enable DLAB |
231 |
call slow_out |
slow_out dx,al |
232 |
|
|
233 |
pop ax ; Divisor |
pop ax ; Divisor |
234 |
mov dx,di ; DX -> LS |
mov dx,di ; DX -> LS |
235 |
call slow_out |
slow_out dx,al |
236 |
|
|
237 |
inc dx ; DX -> MS |
inc dx ; DX -> MS |
238 |
mov al,ah |
mov al,ah |
239 |
call slow_out |
slow_out dx,al |
240 |
|
|
241 |
mov al,03h ; Disable DLAB |
mov al,03h ; Disable DLAB |
242 |
inc dx ; DX -> LCR |
inc dx ; DX -> LCR |
243 |
inc dx |
inc dx |
244 |
call slow_out |
slow_out dx,al |
|
|
|
|
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 |
|
|
dec dx |
|
|
dec dx ; DX -> IER |
|
|
xor al,al ; IRQ disable |
|
|
call slow_out |
|
245 |
|
|
246 |
inc dx ; DX -> FCR/IIR |
in al,dx ; Read back LCR (detect missing hw) |
247 |
|
cmp al,03h ; If nothing here we'll read 00 or FF |
248 |
|
jne .err ; Assume serial port busted |
249 |
|
dec dx ; DX -> IIR/FCR |
250 |
mov al,01h |
mov al,01h |
251 |
call slow_out ; Enable FIFOs if present |
slow_out dx,al ; Enable FIFOs if present |
252 |
in al,dx |
in al,dx |
253 |
cmp al,0C0h ; FIFOs enabled and usable? |
cmp al,0C0h ; FIFOs enabled and usable? |
254 |
jae .fifo_ok |
jae .fifo_ok |
255 |
xor ax,ax ; Disable FIFO if unusable |
xor ax,ax ; Disable FIFO if unusable |
256 |
call slow_out |
slow_out dx,al |
257 |
.fifo_ok: |
.fifo_ok: |
258 |
|
|
259 |
inc dx |
inc dx |
260 |
inc dx ; DX -> MCR |
inc dx ; DX -> MCR |
261 |
in al,dx |
mov al,[FlowOutput] ; Assert bits |
262 |
or al,[FlowOutput] ; Assert bits |
slow_out dx,al |
263 |
call slow_out |
|
264 |
|
; Enable interrupts if requested |
265 |
|
test al,8 |
266 |
|
jz .noirq |
267 |
|
call sirq_install |
268 |
|
.noirq: |
269 |
|
|
270 |
; Show some life |
; Show some life |
271 |
|
cmp byte [SerialNotice],0 |
272 |
|
je .notfirst |
273 |
|
mov byte [SerialNotice],0 |
274 |
|
|
275 |
mov si,syslinux_banner |
mov si,syslinux_banner |
276 |
call write_serial_str |
call write_serial_str |
277 |
mov si,copyright_str |
mov si,copyright_str |
278 |
call write_serial_str |
call write_serial_str |
279 |
|
.notfirst: |
280 |
ret |
ret |
281 |
|
|
282 |
.serial_port_bad: |
.err: |
283 |
mov [SerialPort], word 0 |
mov [SerialPort], word 0 |
284 |
ret |
ret |
285 |
|
|
286 |
; |
; |
287 |
; "F"-key command |
; Store mangled filename command (F-keys, "initrd") |
288 |
; |
; |
289 |
pc_fkey: push ax |
pc_filename: push ax |
290 |
call pc_getline |
call pc_getline |
291 |
pop di |
pop di |
292 |
call mangle_name ; Mangle file name |
call mangle_name ; Mangle file name |
296 |
; "label" command |
; "label" command |
297 |
; |
; |
298 |
pc_label: call commit_vk ; Commit any current vkernel |
pc_label: call commit_vk ; Commit any current vkernel |
299 |
|
mov byte [InitRD+NULLOFFSET],NULLFILE ; No "initrd" statement |
300 |
mov di,VKernelBuf ; Erase the vkernelbuf for better compression |
mov di,VKernelBuf ; Erase the vkernelbuf for better compression |
301 |
mov cx,(vk_size >> 1) |
mov cx,(vk_size >> 1) |
302 |
xor ax,ax |
xor ax,ax |
303 |
rep stosw |
rep stosw |
304 |
call pc_getline |
call pc_getline |
305 |
mov di,VKernelBuf+vk_vname |
mov di,VKernelBuf+vk_vname |
306 |
call mangle_name ; Mangle virtual name |
mov cx,FILENAME_MAX-1 |
307 |
|
.loop: |
308 |
|
lodsb |
309 |
|
cmp al,' ' |
310 |
|
jna .done |
311 |
|
stosb |
312 |
|
loop .loop |
313 |
|
.done: |
314 |
mov byte [VKernel],1 ; We've seen a "label" statement |
mov byte [VKernel],1 ; We've seen a "label" statement |
315 |
mov si,VKernelBuf+vk_vname ; By default, rname == vname |
mov si,VKernelBuf+vk_vname ; By default, rname == mangled vname |
316 |
mov di,VKernelBuf+vk_rname |
mov di,VKernelBuf+vk_rname |
317 |
mov cx,FILENAME_MAX |
call mangle_name |
318 |
|
mov si,AppendBuf ; Default append==global append |
319 |
|
mov di,VKernelBuf+vk_append |
320 |
|
mov cx,[AppendLen] |
321 |
|
mov [VKernelBuf+vk_appendlen],cx |
322 |
rep movsb |
rep movsb |
|
mov si,AppendBuf ; Default append==global append |
|
|
mov di,VKernelBuf+vk_append |
|
|
mov cx,[AppendLen] |
|
|
mov [VKernelBuf+vk_appendlen],cx |
|
|
rep movsb |
|
323 |
%if IS_PXELINUX ; PXELINUX only |
%if IS_PXELINUX ; PXELINUX only |
324 |
mov al,[IPAppend] ; Default ipappend==global ipappend |
mov al,[IPAppend] ; Default ipappend==global ipappend |
325 |
mov [VKernelBuf+vk_ipappend],al |
mov [VKernelBuf+vk_ipappend],al |
334 |
jmp crlf ; tailcall |
jmp crlf ; tailcall |
335 |
|
|
336 |
; |
; |
337 |
|
; "text" command; ignore everything until we get an "endtext" line |
338 |
|
; |
339 |
|
pc_text: call skipline ; Ignore rest of line |
340 |
|
.loop: |
341 |
|
call pc_getline |
342 |
|
jc .eof |
343 |
|
|
344 |
|
; Leading spaces are already removed... |
345 |
|
lodsd |
346 |
|
and eax,0xdfdfdfdf ; Upper case |
347 |
|
cmp eax,'ENDT' |
348 |
|
jne .loop |
349 |
|
lodsd |
350 |
|
and eax,0x00dfdfdf ; Upper case and mask |
351 |
|
cmp eax,'EXT' |
352 |
|
jne .loop |
353 |
|
; If we get here we hit ENDTEXT |
354 |
|
.eof: |
355 |
|
ret |
356 |
|
|
357 |
|
; |
358 |
; Comment line |
; Comment line |
359 |
; |
; |
360 |
pc_comment: ; Fall into pc_getline |
pc_comment: ; Fall into pc_getline |
361 |
|
|
362 |
; |
; |
363 |
; Common subroutine: load line into trackbuf; returns with SI -> trackbuf |
; Common subroutine: load line into trackbuf; returns with SI -> trackbuf |
364 |
|
; CF is set on EOF. |
365 |
; |
; |
366 |
pc_getline: mov di,trackbuf |
pc_getline: mov di,trackbuf |
367 |
push di |
push di |
368 |
call getline |
call getline |
369 |
xor al,al |
mov byte [di],0 ; Null-terminate |
|
stosb ; Null-terminate |
|
370 |
pop si |
pop si |
371 |
ret |
ret |
372 |
|
|
378 |
xor ax,ax |
xor ax,ax |
379 |
mov cx,vk_size |
mov cx,vk_size |
380 |
rep stosb |
rep stosb |
381 |
|
|
382 |
.again: |
.again: |
383 |
call getcommand |
call getcommand ; Parse one command |
384 |
jnc .again ; If not EOF do it again |
jnc .again ; If not EOF... |
385 |
|
call close |
386 |
|
dec word [IncludeLevel] ; Still parsing? |
387 |
|
jnz .again |
388 |
|
|
389 |
; |
; |
390 |
; The fall through to commit_vk to commit any final |
; The fall through to commit_vk to commit any final |
391 |
; VKernel being read |
; VKernel being read |
394 |
; commit_vk: Store the current VKernelBuf into buffer segment |
; commit_vk: Store the current VKernelBuf into buffer segment |
395 |
; |
; |
396 |
commit_vk: |
commit_vk: |
397 |
; For better compression, clean up the append field |
cmp byte [VKernel],0 |
398 |
mov ax,[VKernelBuf+vk_appendlen] |
jz .nolabel ; Nothing to commit... |
399 |
|
|
400 |
mov di,VKernelBuf+vk_append |
mov di,VKernelBuf+vk_append |
401 |
add di,ax |
add di,[VKernelBuf+vk_appendlen] |
402 |
|
|
403 |
|
; If we have an initrd statement, append it to the |
404 |
|
; append statement |
405 |
|
cmp byte [InitRD+NULLOFFSET],NULLFILE |
406 |
|
je .noinitrd |
407 |
|
|
408 |
|
mov si,str_initrd |
409 |
|
mov cx,7 ; "initrd=" |
410 |
|
rep movsb |
411 |
|
mov si,InitRD |
412 |
|
call unmangle_name |
413 |
|
mov al,' ' |
414 |
|
stosb |
415 |
|
|
416 |
|
; For better compression, clean up the append field |
417 |
|
.noinitrd: |
418 |
|
mov ax,di |
419 |
|
sub ax,VKernelBuf+vk_append |
420 |
|
mov [VKernelBuf+vk_appendlen],ax |
421 |
mov cx,max_cmd_len+1 |
mov cx,max_cmd_len+1 |
422 |
sub cx,ax |
sub cx,ax |
423 |
xor ax,ax |
xor ax,ax |
424 |
rep stosb |
rep stosb |
425 |
|
|
426 |
; Pack temporarily into trackbuf |
; Pack into high memory |
427 |
mov si,VKernelBuf |
mov esi,VKernelBuf |
428 |
mov di,trackbuf |
mov edi,[VKernelEnd] |
429 |
mov cx,vk_size |
mov ecx,vk_size |
430 |
call rllpack |
call rllpack |
431 |
; Now DX = number of bytes |
mov [VKernelEnd],edi |
432 |
mov di,[VKernelBytes] |
.nolabel: |
|
mov cx,dx |
|
|
add dx,di |
|
|
jc .overflow ; If > 1 segment |
|
|
mov [VKernelBytes],dx |
|
|
mov si,trackbuf |
|
|
push es |
|
|
push word vk_seg |
|
|
pop es |
|
|
rep movsb |
|
|
pop es |
|
433 |
ret |
ret |
434 |
.overflow: |
.overflow: |
435 |
mov si,vk_overflow_msg |
mov si,vk_overflow_msg |
438 |
|
|
439 |
section .data |
section .data |
440 |
vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0 |
vk_overflow_msg db 'Out of memory parsing config file', CR, LF, 0 |
441 |
|
SerialNotice db 1 ; Only print this once |
442 |
|
|
443 |
|
section .bss |
444 |
|
alignb 4 |
445 |
|
VKernelEnd resd 1 ; Lowest high memory address used |
446 |
|
|
447 |
align 4, db 0 |
; This symbol should be used by loaders to indicate |
448 |
|
; the highest address *they* are allowed to use. |
449 |
|
HighMemRsvd equ VKernelEnd |
450 |
|
; by vkernels |
451 |
|
section .config |
452 |
|
alignz 4 |
453 |
KbdTimeout dd 0 ; Keyboard timeout (if any) |
KbdTimeout dd 0 ; Keyboard timeout (if any) |
454 |
TotalTimeout dd 0 ; Total timeout (if any) |
TotalTimeout dd 0 ; Total timeout (if any) |
455 |
AppendLen dw 0 ; Bytes in append= command |
AppendLen dw 0 ; Bytes in append= command |
458 |
CmdLinePtr dw cmd_line_here ; Command line advancing pointer |
CmdLinePtr dw cmd_line_here ; Command line advancing pointer |
459 |
ForcePrompt dw 0 ; Force prompt |
ForcePrompt dw 0 ; Force prompt |
460 |
NoEscape dw 0 ; No escape |
NoEscape dw 0 ; No escape |
461 |
|
NoComplete dw 0 ; No label completion on TAB key |
462 |
AllowImplicit dw 1 ; Allow implicit kernels |
AllowImplicit dw 1 ; Allow implicit kernels |
463 |
AllowOptions dw 1 ; User-specified options allowed |
AllowOptions dw 1 ; User-specified options allowed |
464 |
SerialPort dw 0 ; Serial port base (or 0 for no serial port) |
IncludeLevel dw 1 ; Nesting level |
465 |
VKernelBytes dw 0 ; Number of bytes used by vkernels |
DefaultLevel dw 0 ; The current level of default |
466 |
VKernel db 0 ; Have we seen any "label" statements? |
VKernel db 0 ; Have we seen any "label" statements? |
467 |
|
|
468 |
section .latebss |
%if IS_PXELINUX |
469 |
|
IPAppend db 0 ; Default IPAPPEND option |
470 |
|
%endif |
471 |
|
|
472 |
|
section .uibss |
473 |
alignb 4 ; For the good of REP MOVSD |
alignb 4 ; For the good of REP MOVSD |
474 |
command_line resb max_cmd_len+2 ; Command line buffer |
command_line resb max_cmd_len+2 ; Command line buffer |
475 |
alignb 4 |
alignb 4 |