Contents of /trunk/mkinitrd-magellan/isolinux/runkernel.inc
Parent Directory | Revision Log
Revision 1133 -
(show annotations)
(download)
Thu Aug 19 09:50:43 2010 UTC (14 years, 1 month ago) by niro
File size: 17162 byte(s)
Thu Aug 19 09:50:43 2010 UTC (14 years, 1 month ago) by niro
File size: 17162 byte(s)
-updated to isolinux-3.86
1 | ;; ----------------------------------------------------------------------- |
2 | ;; |
3 | ;; Copyright 1994-2009 H. Peter Anvin - All Rights Reserved |
4 | ;; Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin |
5 | ;; |
6 | ;; 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 |
8 | ;; the Free Software Foundation, Inc., 53 Temple Place Ste 330, |
9 | ;; Boston MA 02111-1307, USA; either version 2 of the License, or |
10 | ;; (at your option) any later version; incorporated herein by reference. |
11 | ;; |
12 | ;; ----------------------------------------------------------------------- |
13 | |
14 | ;; |
15 | ;; runkernel.inc |
16 | ;; |
17 | ;; Common code for running a Linux kernel |
18 | ;; |
19 | |
20 | ; |
21 | ; Hook macros, that may or may not be defined |
22 | ; |
23 | %ifndef HAVE_UNLOAD_PREP |
24 | %macro UNLOAD_PREP 0 |
25 | %endmacro |
26 | %endif |
27 | |
28 | ; |
29 | ; A Linux kernel consists of three parts: boot sector, setup code, and |
30 | ; kernel code. The boot sector is never executed when using an external |
31 | ; booting utility, but it contains some status bytes that are necessary. |
32 | ; |
33 | ; First check that our kernel is at least 1K, or else it isn't long |
34 | ; enough to have the appropriate headers. |
35 | ; |
36 | ; We used to require the kernel to be 64K or larger, but it has gotten |
37 | ; popular to use the Linux kernel format for other things, which may |
38 | ; not be so large. |
39 | ; |
40 | ; Additionally, we used to have a test for 8 MB or smaller. Equally |
41 | ; obsolete. |
42 | ; |
43 | is_linux_kernel: |
44 | push si ; <A> file pointer |
45 | |
46 | ; |
47 | ; Now start transferring the kernel |
48 | ; |
49 | push word real_mode_seg |
50 | pop es |
51 | |
52 | ; |
53 | ; Start by loading the bootsector/setup code, to see if we need to |
54 | ; do something funky. It should fit in the first 32K (loading 64K won't |
55 | ; work since we might have funny stuff up near the end of memory). |
56 | ; |
57 | call abort_check ; Check for abort key |
58 | mov cx,8000h >> SECTOR_SHIFT ; Half a moby (32K) |
59 | xor bx,bx |
60 | pop si ; <A> file pointer |
61 | call getfssec |
62 | cmp cx,1024 |
63 | jb kernel_corrupt |
64 | cmp word [es:bs_bootsign],0AA55h |
65 | jne kernel_corrupt ; Boot sec signature missing |
66 | |
67 | ; |
68 | ; Save the file pointer for later... |
69 | ; |
70 | push si ; <A> file pointer |
71 | |
72 | ; |
73 | ; Construct the command line (append options have already been copied) |
74 | ; |
75 | construct_cmdline: |
76 | mov di,[CmdLinePtr] |
77 | mov si,boot_image ; BOOT_IMAGE= |
78 | mov cx,boot_image_len |
79 | rep movsb |
80 | mov si,KernelCName ; Unmangled kernel name |
81 | mov cx,[KernelCNameLen] |
82 | rep movsb |
83 | mov al,' ' ; Space |
84 | stosb |
85 | |
86 | call do_ip_append ; Handle IPAppend |
87 | |
88 | mov si,[CmdOptPtr] ; Options from user input |
89 | call strcpy |
90 | |
91 | ; |
92 | ; Scan through the command line for anything that looks like we might be |
93 | ; interested in. The original version of this code automatically assumed |
94 | ; the first option was BOOT_IMAGE=, but that is no longer certain. |
95 | ; |
96 | parse_cmdline: |
97 | mov di,cmd_line_here |
98 | .skipspace: mov al,[es:di] |
99 | inc di |
100 | .skipspace_loaded: |
101 | and al,al |
102 | jz cmdline_end |
103 | cmp al,' ' |
104 | jbe .skipspace |
105 | dec di |
106 | |
107 | ; ES:DI now points to the beginning of an option |
108 | mov si,options_list |
109 | .next_opt: |
110 | movzx cx,byte [si] |
111 | jcxz .skip_opt |
112 | push di |
113 | inc si |
114 | repe cmpsb |
115 | jne .no_match |
116 | |
117 | ; This either needs to have been an option with parameter, |
118 | ; or be followed by EOL/whitespace |
119 | mov ax,[es:di-1] ; AL = last chr; AH = following |
120 | cmp al,'=' |
121 | je .is_match |
122 | cmp ah,' ' |
123 | ja .no_match |
124 | .is_match: |
125 | pop ax ; Drop option pointer on stack |
126 | call [si] |
127 | .skip_opt: |
128 | mov al,[es:di] |
129 | inc di |
130 | cmp al,' ' |
131 | ja .skip_opt |
132 | jmp .skipspace_loaded |
133 | .no_match: |
134 | pop di |
135 | add si,cx ; Skip remaining bytes |
136 | inc si ; Skip function pointer |
137 | inc si |
138 | jmp .next_opt |
139 | |
140 | opt_vga: |
141 | mov ax,[es:di-1] |
142 | mov bx,-1 |
143 | cmp ax,'=n' ; vga=normal |
144 | je .vc0 |
145 | dec bx ; bx <- -2 |
146 | cmp ax,'=e' ; vga=ext |
147 | je .vc0 |
148 | dec bx ; bx <- -3 |
149 | cmp ax,'=a' ; vga=ask |
150 | je .vc0 |
151 | mov bx,0x0f04 ; bx <- 0x0f04 (current mode) |
152 | cmp ax,'=c' ; vga=current |
153 | je .vc0 |
154 | call parseint_esdi ; vga=<number> |
155 | jc .skip ; Not an integer |
156 | .vc0: mov [es:bs_vidmode],bx ; Set video mode |
157 | .skip: |
158 | ret |
159 | |
160 | opt_mem: |
161 | call parseint_esdi |
162 | jc .skip |
163 | %if HIGHMEM_SLOP != 0 |
164 | sub ebx,HIGHMEM_SLOP |
165 | %endif |
166 | mov [MyHighMemSize],ebx |
167 | .skip: |
168 | ret |
169 | |
170 | opt_quiet: |
171 | mov byte [QuietBoot],QUIET_FLAG |
172 | ret |
173 | |
174 | %if IS_PXELINUX |
175 | opt_keeppxe: |
176 | or byte [KeepPXE],1 ; KeepPXE set by command line |
177 | ret |
178 | %endif |
179 | |
180 | opt_initrd: |
181 | mov ax,di |
182 | cmp byte [es:di],' ' |
183 | ja .have_initrd |
184 | xor ax,ax |
185 | .have_initrd: |
186 | mov [InitRDPtr],ax |
187 | ret |
188 | |
189 | ; |
190 | ; After command line parsing... |
191 | ; |
192 | cmdline_end: |
193 | sub di,cmd_line_here |
194 | mov [CmdLineLen],di ; Length including final null |
195 | |
196 | ; |
197 | ; Now check if we have a large kernel, which needs to be loaded high |
198 | ; |
199 | prepare_header: |
200 | mov dword [RamdiskMax], HIGHMEM_MAX ; Default initrd limit |
201 | cmp dword [es:su_header],HEADER_ID ; New setup code ID |
202 | jne old_kernel ; Old kernel, load low |
203 | mov ax,[es:su_version] |
204 | mov [KernelVersion],ax |
205 | cmp ax,0200h ; Setup code version 2.0 |
206 | jb old_kernel ; Old kernel, load low |
207 | cmp ax,0201h ; Version 2.01+? |
208 | jb new_kernel ; If 2.00, skip this step |
209 | ; Set up the heap (assuming loading high for now) |
210 | mov word [es:su_heapend],linux_stack-512 |
211 | or byte [es:su_loadflags],80h ; Let the kernel know we care |
212 | cmp ax,0203h ; Version 2.03+? |
213 | jb new_kernel ; Not 2.03+ |
214 | mov eax,[es:su_ramdisk_max] |
215 | mov [RamdiskMax],eax ; Set the ramdisk limit |
216 | |
217 | ; |
218 | ; We definitely have a new-style kernel. Let the kernel know who we are, |
219 | ; and that we are clueful |
220 | ; |
221 | new_kernel: |
222 | mov byte [es:su_loader],my_id ; Show some ID |
223 | xor eax,eax |
224 | mov [es:su_ramdisklen],eax ; No initrd loaded yet |
225 | |
226 | ; |
227 | ; About to load the kernel. This is a modern kernel, so use the boot flags |
228 | ; we were provided. |
229 | ; |
230 | mov al,[es:su_loadflags] |
231 | or al,[QuietBoot] ; Set QUIET_FLAG if needed |
232 | mov [es:su_loadflags],al |
233 | mov [LoadFlags],al |
234 | |
235 | any_kernel: |
236 | mov si,loading_msg |
237 | call writestr_qchk |
238 | mov si,KernelCName ; Print kernel name part of |
239 | call writestr_qchk ; "Loading" message |
240 | |
241 | ; |
242 | ; Load the kernel. We always load it at 100000h even if we're supposed to |
243 | ; load it "low"; for a "low" load we copy it down to low memory right before |
244 | ; jumping to it. |
245 | ; |
246 | read_kernel: |
247 | movzx ax,byte [es:bs_setupsecs] ; Setup sectors |
248 | and ax,ax |
249 | jnz .sects_ok |
250 | mov al,4 ; 0 = 4 setup sectors |
251 | .sects_ok: |
252 | inc ax ; Including the boot sector |
253 | mov [SetupSecs],ax |
254 | |
255 | call dot_pause |
256 | |
257 | ; |
258 | ; Move the stuff beyond the setup code to high memory at 100000h |
259 | ; |
260 | movzx esi,word [SetupSecs] ; Setup sectors |
261 | shl si,9 ; Convert to bytes |
262 | mov ecx,8000h ; 32K |
263 | sub ecx,esi ; Number of bytes to copy |
264 | add esi,(real_mode_seg << 4) ; Pointer to source |
265 | mov edi,100000h ; Copy to address 100000h |
266 | |
267 | call bcopy ; Transfer to high memory |
268 | |
269 | pop si ; <A> File pointer |
270 | and si,si ; EOF already? |
271 | jz high_load_done |
272 | |
273 | ; On exit EDI -> where to load the rest |
274 | |
275 | mov bx,dot_pause |
276 | or eax,-1 ; Load the whole file |
277 | mov dx,3 ; Pad to dword |
278 | call load_high |
279 | |
280 | high_load_done: |
281 | mov [KernelEnd],edi |
282 | mov ax,real_mode_seg ; Set to real mode seg |
283 | mov es,ax |
284 | |
285 | mov si,dot_msg |
286 | call writestr_qchk |
287 | |
288 | ; |
289 | ; Some older kernels (1.2 era) would have more than 4 setup sectors, but |
290 | ; would not rely on the boot protocol to manage that. These kernels fail |
291 | ; if they see protected-mode kernel data after the setup sectors, so |
292 | ; clear that memory. |
293 | ; |
294 | push di |
295 | mov di,[SetupSecs] |
296 | shl di,9 |
297 | xor eax,eax |
298 | mov cx,cmd_line_here |
299 | sub cx,di |
300 | shr cx,2 |
301 | rep stosd |
302 | pop di |
303 | |
304 | ; |
305 | ; Now see if we have an initial RAMdisk; if so, do requisite computation |
306 | ; We know we have a new kernel; the old_kernel code already will have objected |
307 | ; if we tried to load initrd using an old kernel |
308 | ; |
309 | load_initrd: |
310 | ; Cap the ramdisk memory range if appropriate |
311 | mov eax,[RamdiskMax] |
312 | cmp eax,[MyHighMemSize] |
313 | ja .ok |
314 | mov [MyHighMemSize],eax |
315 | .ok: |
316 | xor eax,eax |
317 | cmp [InitRDPtr],ax |
318 | jz .noinitrd |
319 | call parse_load_initrd |
320 | .noinitrd: |
321 | |
322 | ; |
323 | ; Abandon hope, ye that enter here! We do no longer permit aborts. |
324 | ; |
325 | call abort_check ; Last chance!! |
326 | |
327 | mov si,ready_msg |
328 | call writestr_qchk |
329 | |
330 | UNLOAD_PREP ; Module-specific hook |
331 | |
332 | ; |
333 | ; Now, if we were supposed to load "low", copy the kernel down to 10000h |
334 | ; and the real mode stuff to 90000h. We assume that all bzImage kernels are |
335 | ; capable of starting their setup from a different address. |
336 | ; |
337 | mov ax,real_mode_seg |
338 | mov es,ax |
339 | mov fs,ax |
340 | |
341 | ; |
342 | ; If the default root device is set to FLOPPY (0000h), change to |
343 | ; /dev/fd0 (0200h) |
344 | ; |
345 | cmp word [es:bs_rootdev],byte 0 |
346 | jne root_not_floppy |
347 | mov word [es:bs_rootdev],0200h |
348 | root_not_floppy: |
349 | |
350 | ; |
351 | ; Copy command line. Unfortunately, the old kernel boot protocol requires |
352 | ; the command line to exist in the 9xxxxh range even if the rest of the |
353 | ; setup doesn't. |
354 | ; |
355 | setup_command_line: |
356 | mov dx,[KernelVersion] |
357 | test byte [LoadFlags],LOAD_HIGH |
358 | jz .need_high_cmdline |
359 | cmp dx,0202h ; Support new cmdline protocol? |
360 | jb .need_high_cmdline |
361 | ; New cmdline protocol |
362 | ; Store 32-bit (flat) pointer to command line |
363 | ; This is the "high" location, since we have bzImage |
364 | mov dword [fs:su_cmd_line_ptr],(real_mode_seg << 4)+cmd_line_here |
365 | mov word [HeapEnd],linux_stack |
366 | mov word [fs:su_heapend],linux_stack-512 |
367 | jmp .setup_done |
368 | |
369 | .need_high_cmdline: |
370 | ; |
371 | ; Copy command line down to fit in high conventional memory |
372 | ; -- this happens if we have a zImage kernel or the protocol |
373 | ; is less than 2.02. |
374 | ; |
375 | mov si,cmd_line_here |
376 | mov di,old_cmd_line_here |
377 | mov [fs:kern_cmd_magic],word CMD_MAGIC ; Store magic |
378 | mov [fs:kern_cmd_offset],di ; Store pointer |
379 | mov word [HeapEnd],old_linux_stack |
380 | mov ax,255 ; Max cmdline limit |
381 | cmp dx,0201h |
382 | jb .adjusted |
383 | ; Protocol 2.01+ |
384 | mov word [fs:su_heapend],old_linux_stack-512 |
385 | jbe .adjusted |
386 | ; Protocol 2.02+ |
387 | ; Note that the only reason we would end up here is |
388 | ; because we have a zImage, so we anticipate the move |
389 | ; to 90000h already... |
390 | mov dword [fs:su_cmd_line_ptr],0x90000+old_cmd_line_here |
391 | mov ax,old_max_cmd_len ; 2.02+ allow a higher limit |
392 | .adjusted: |
393 | |
394 | mov cx,[CmdLineLen] |
395 | cmp cx,ax |
396 | jna .len_ok |
397 | mov cx,ax ; Truncate the command line |
398 | .len_ok: |
399 | fs rep movsb |
400 | stosb ; Final null, note AL=0 already |
401 | mov [CmdLineEnd],di |
402 | cmp dx,0200h |
403 | jb .nomovesize |
404 | mov [es:su_movesize],di ; Tell the kernel what to move |
405 | .nomovesize: |
406 | .setup_done: |
407 | |
408 | ; |
409 | ; Time to start setting up move descriptors |
410 | ; |
411 | setup_move: |
412 | mov di,trackbuf |
413 | xor cx,cx ; Number of descriptors |
414 | |
415 | mov bx,es ; real_mode_seg |
416 | mov fs,bx |
417 | push ds ; We need DS == ES == CS here |
418 | pop es |
419 | |
420 | test byte [LoadFlags],LOAD_HIGH |
421 | jnz .loading_high |
422 | |
423 | ; Loading low: move real_mode stuff to 90000h, then move the kernel down |
424 | mov eax,90000h |
425 | stosd |
426 | mov eax,real_mode_seg << 4 |
427 | stosd |
428 | movzx eax,word [CmdLineEnd] |
429 | stosd |
430 | inc cx |
431 | |
432 | mov eax,10000h ; Target address of low kernel |
433 | stosd |
434 | mov eax,100000h ; Where currently loaded |
435 | stosd |
436 | neg eax |
437 | add eax,[KernelEnd] |
438 | stosd |
439 | inc cx |
440 | |
441 | mov bx,9000h ; Revised real mode segment |
442 | |
443 | .loading_high: |
444 | |
445 | cmp word [InitRDPtr],0 ; Did we have an initrd? |
446 | je .no_initrd |
447 | |
448 | mov eax,[fs:su_ramdiskat] |
449 | stosd |
450 | mov eax,[InitRDStart] |
451 | stosd |
452 | mov eax,[fs:su_ramdisklen] |
453 | stosd |
454 | inc cx |
455 | |
456 | .no_initrd: |
457 | push dword run_linux_kernel |
458 | push cx ; Length of descriptor list |
459 | |
460 | ; BX points to the final real mode segment, and will be loaded |
461 | ; into DS. |
462 | |
463 | test byte [QuietBoot],QUIET_FLAG |
464 | jz replace_bootstrap |
465 | jmp replace_bootstrap_noclearmode |
466 | |
467 | run_linux_kernel: |
468 | ; |
469 | ; Set up segment registers and the Linux real-mode stack |
470 | ; Note: ds == the real mode segment |
471 | ; |
472 | cli |
473 | mov ax,ds |
474 | mov ss,ax |
475 | mov sp,strict word linux_stack |
476 | ; Point HeapEnd to the immediate of the instruction above |
477 | HeapEnd equ $-2 ; Self-modifying code! Fun! |
478 | mov es,ax |
479 | mov fs,ax |
480 | mov gs,ax |
481 | |
482 | ; |
483 | ; We're done... now RUN THAT KERNEL!!!! |
484 | ; Setup segment == real mode segment + 020h; we need to jump to offset |
485 | ; zero in the real mode segment. |
486 | ; |
487 | add ax,020h |
488 | push ax |
489 | push word 0h |
490 | retf |
491 | |
492 | ; |
493 | ; Load an older kernel. Older kernels always have 4 setup sectors, can't have |
494 | ; initrd, and are always loaded low. |
495 | ; |
496 | old_kernel: |
497 | xor ax,ax |
498 | cmp word [InitRDPtr],ax ; Old kernel can't have initrd |
499 | je .load |
500 | mov si,err_oldkernel |
501 | jmp abort_load |
502 | .load: |
503 | mov byte [LoadFlags],al ; Always low |
504 | mov word [KernelVersion],ax ; Version 0.00 |
505 | jmp any_kernel |
506 | |
507 | ; |
508 | ; parse_load_initrd |
509 | ; |
510 | ; Parse an initrd= option and load the initrds. This sets |
511 | ; InitRDStart and InitRDEnd with dword padding between; we then |
512 | ; do a global memory shuffle to move it to the end of memory. |
513 | ; |
514 | ; On entry, EDI points to where to start loading. |
515 | ; |
516 | parse_load_initrd: |
517 | push es |
518 | push ds |
519 | mov ax,real_mode_seg |
520 | mov ds,ax |
521 | push cs |
522 | pop es ; DS == real_mode_seg, ES == CS |
523 | |
524 | mov [cs:InitRDStart],edi |
525 | mov [cs:InitRDEnd],edi |
526 | |
527 | mov si,[cs:InitRDPtr] |
528 | |
529 | .get_chunk: |
530 | ; DS:SI points to the start of a name |
531 | |
532 | mov bx,si |
533 | .find_end: |
534 | lodsb |
535 | cmp al,',' |
536 | je .got_end |
537 | cmp al,' ' |
538 | jbe .got_end |
539 | jmp .find_end |
540 | |
541 | .got_end: |
542 | push ax ; Terminating character |
543 | push si ; Next filename (if any) |
544 | mov byte [si-1],0 ; Zero-terminate |
545 | mov si,bx ; Current filename |
546 | |
547 | push di |
548 | mov di,InitRD ; Target buffer for mangled name |
549 | call mangle_name |
550 | pop di |
551 | call loadinitrd |
552 | |
553 | pop si |
554 | pop ax |
555 | mov [si-1],al ; Restore ending byte |
556 | |
557 | cmp al,',' |
558 | je .get_chunk |
559 | |
560 | ; Compute the initrd target location |
561 | ; Note: we round to a page boundary twice here. The first |
562 | ; time it is to make sure we don't use any fractional page |
563 | ; which may be valid RAM but which will be ignored by the |
564 | ; kernel (and therefore is inaccessible.) The second time |
565 | ; it is to make sure we start out on page boundary. |
566 | mov edx,[cs:InitRDEnd] |
567 | sub edx,[cs:InitRDStart] |
568 | mov [su_ramdisklen],edx |
569 | mov eax,[cs:MyHighMemSize] |
570 | and ax,0F000h ; Round to a page boundary |
571 | sub eax,edx |
572 | and ax,0F000h ; Round to a page boundary |
573 | mov [su_ramdiskat],eax |
574 | |
575 | pop ds |
576 | pop es |
577 | ret |
578 | |
579 | ; |
580 | ; Load RAM disk into high memory |
581 | ; |
582 | ; Input: InitRD - set to the mangled name of the initrd |
583 | ; EDI - location to load |
584 | ; Output: EDI - location for next initrd |
585 | ; InitRDEnd - updated |
586 | ; |
587 | loadinitrd: |
588 | push ds |
589 | push es |
590 | mov ax,cs ; CS == DS == ES |
591 | mov ds,ax |
592 | mov es,ax |
593 | push edi |
594 | mov si,InitRD |
595 | mov di,InitRDCName |
596 | call unmangle_name ; Create human-readable name |
597 | sub di,InitRDCName |
598 | mov [InitRDCNameLen],di |
599 | mov di,InitRD |
600 | call searchdir ; Look for it in directory |
601 | pop edi |
602 | jz .notthere |
603 | |
604 | push si |
605 | mov si,crlfloading_msg ; Write "Loading " |
606 | call writestr_qchk |
607 | mov si,InitRDCName ; Write ramdisk name |
608 | call writestr_qchk |
609 | mov si,dotdot_msg ; Write dots |
610 | call writestr_qchk |
611 | pop si |
612 | |
613 | .li_skip_echo: |
614 | mov dx,3 |
615 | mov bx,dot_pause |
616 | call load_high |
617 | mov [InitRDEnd],ebx |
618 | |
619 | pop es |
620 | pop ds |
621 | ret |
622 | |
623 | .notthere: |
624 | mov si,err_noinitrd |
625 | call writestr |
626 | mov si,InitRDCName |
627 | call writestr |
628 | mov si,crlf_msg |
629 | jmp abort_load |
630 | |
631 | ; |
632 | ; writestr_qchk: writestr, except allows output to be suppressed |
633 | ; assumes CS == DS |
634 | ; |
635 | writestr_qchk: |
636 | test byte [QuietBoot],QUIET_FLAG |
637 | jz writestr |
638 | ret |
639 | |
640 | section .data |
641 | crlfloading_msg db CR, LF |
642 | loading_msg db 'Loading ', 0 |
643 | dotdot_msg db '.' |
644 | dot_msg db '.', 0 |
645 | ready_msg db 'ready.', CR, LF, 0 |
646 | err_oldkernel db 'Cannot load a ramdisk with an old kernel image.' |
647 | db CR, LF, 0 |
648 | err_noinitrd db CR, LF, 'Could not find ramdisk image: ', 0 |
649 | |
650 | boot_image db 'BOOT_IMAGE=' |
651 | boot_image_len equ $-boot_image |
652 | |
653 | ; |
654 | ; Command line options we'd like to take a look at |
655 | ; |
656 | %macro cmd_opt 2 |
657 | %strlen cmd_opt_len %1 |
658 | db cmd_opt_len |
659 | db %1 |
660 | dw %2 |
661 | %endmacro |
662 | options_list: |
663 | cmd_opt "vga=", opt_vga |
664 | cmd_opt "mem=", opt_mem |
665 | cmd_opt "quiet", opt_quiet |
666 | str_initrd equ $+1 ; Pointer to "initrd=" in memory |
667 | cmd_opt "initrd=", opt_initrd |
668 | %if IS_PXELINUX |
669 | cmd_opt "keeppxe", opt_keeppxe |
670 | %endif |
671 | db 0 |
672 | |
673 | section .bss |
674 | alignb 4 |
675 | MyHighMemSize resd 1 ; Possibly adjusted highmem size |
676 | RamdiskMax resd 1 ; Highest address for ramdisk |
677 | KernelSize resd 1 ; Size of kernel in bytes |
678 | KernelSects resd 1 ; Size of kernel in sectors |
679 | KernelEnd resd 1 ; Ending address of the kernel image |
680 | InitRDStart resd 1 ; Start of initrd (pre-relocation) |
681 | InitRDEnd resd 1 ; End of initrd (pre-relocation) |
682 | CmdLineLen resw 1 ; Length of command line including null |
683 | CmdLineEnd resw 1 ; End of the command line in real_mode_seg |
684 | SetupSecs resw 1 ; Number of setup sectors (+bootsect) |
685 | KernelVersion resw 1 ; Kernel protocol version |
686 | ; |
687 | ; These are derived from the command-line parser |
688 | ; |
689 | InitRDPtr resw 1 ; Pointer to initrd= option in command line |
690 | LoadFlags resb 1 ; Loadflags from kernel |
691 | QuietBoot resb 1 ; Set if a quiet boot is requested |