aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2007-05-08 23:37:02 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-05-08 23:47:51 -0400
commitde372ecd80a42c4fb485c7232475301a18d05184 (patch)
treee8707521df8b4d2ea97a8b2fed33a49721cd151a
parentd5f9f942c601fdebe57f7805e4b4fbad9c28ada8 (diff)
Documentation/i386/boot.txt: update and correct
In the process of rewriting the x86 setup code, I found a number of inaccuracies and outdated recommendations in the boot protocol documentation. Revamp to make it more up to date. In particular, the common use of the heap actually requires (slightly) more than 4K of heap plus stack, which is the recommended amount in the document; currently the code compensates by being smaller than specified, but we can't assume that will be true forever. Thus, recommend that if we have a modern bzImage kernel, that the bootloader maximizes the available space. Signed-off-by: H. Peter Anvin <hpa@zytor.com> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
-rw-r--r--Documentation/i386/boot.txt101
1 files changed, 78 insertions, 23 deletions
diff --git a/Documentation/i386/boot.txt b/Documentation/i386/boot.txt
index 6498666ea330..d01b7a2a0f2e 100644
--- a/Documentation/i386/boot.txt
+++ b/Documentation/i386/boot.txt
@@ -2,7 +2,7 @@
2 ---------------------------- 2 ----------------------------
3 3
4 H. Peter Anvin <hpa@zytor.com> 4 H. Peter Anvin <hpa@zytor.com>
5 Last update 2007-03-06 5 Last update 2007-05-07
6 6
7On the i386 platform, the Linux kernel uses a rather complicated boot 7On the i386 platform, the Linux kernel uses a rather complicated boot
8convention. This has evolved partially due to historical aspects, as 8convention. This has evolved partially due to historical aspects, as
@@ -11,7 +11,7 @@ bootable image, the complicated PC memory model and due to changed
11expectations in the PC industry caused by the effective demise of 11expectations in the PC industry caused by the effective demise of
12real-mode DOS as a mainstream operating system. 12real-mode DOS as a mainstream operating system.
13 13
14Currently, four versions of the Linux/i386 boot protocol exist. 14Currently, the following versions of the Linux/i386 boot protocol exist.
15 15
16Old kernels: zImage/Image support only. Some very early kernels 16Old kernels: zImage/Image support only. Some very early kernels
17 may not even support a command line. 17 may not even support a command line.
@@ -183,9 +183,9 @@ filled out, however:
183 a version number. Otherwise, enter 0xFF here. 183 a version number. Otherwise, enter 0xFF here.
184 184
185 Assigned boot loader ids: 185 Assigned boot loader ids:
186 0 LILO 186 0 LILO (0x00 reserved for pre-2.00 bootloader)
187 1 Loadlin 187 1 Loadlin
188 2 bootsect-loader 188 2 bootsect-loader (0x20, all other values reserved)
189 3 SYSLINUX 189 3 SYSLINUX
190 4 EtherBoot 190 4 EtherBoot
191 5 ELILO 191 5 ELILO
@@ -210,6 +210,9 @@ filled out, however:
210 additional data (such as the kernel command line) moved in 210 additional data (such as the kernel command line) moved in
211 addition to the real-mode kernel itself. 211 addition to the real-mode kernel itself.
212 212
213 The unit is bytes starting with the beginning of the boot
214 sector.
215
213 ramdisk_image, ramdisk_size: 216 ramdisk_image, ramdisk_size:
214 If your boot loader has loaded an initial ramdisk (initrd), 217 If your boot loader has loaded an initial ramdisk (initrd),
215 set ramdisk_image to the 32-bit pointer to the ramdisk data 218 set ramdisk_image to the 32-bit pointer to the ramdisk data
@@ -278,14 +281,54 @@ command line is entered using the following protocol:
278 field. 281 field.
279 282
280 283
284**** MEMORY LAYOUT OF THE REAL-MODE CODE
285
286The real-mode code requires a stack/heap to be set up, as well as
287memory allocated for the kernel command line. This needs to be done
288in the real-mode accessible memory in bottom megabyte.
289
290It should be noted that modern machines often have a sizable Extended
291BIOS Data Area (EBDA). As a result, it is advisable to use as little
292of the low megabyte as possible.
293
294Unfortunately, under the following circumstances the 0x90000 memory
295segment has to be used:
296
297 - When loading a zImage kernel ((loadflags & 0x01) == 0).
298 - When loading a 2.01 or earlier boot protocol kernel.
299
300 -> For the 2.00 and 2.01 boot protocols, the real-mode code
301 can be loaded at another address, but it is internally
302 relocated to 0x90000. For the "old" protocol, the
303 real-mode code must be loaded at 0x90000.
304
305When loading at 0x90000, avoid using memory above 0x9a000.
306
307For boot protocol 2.02 or higher, the command line does not have to be
308located in the same 64K segment as the real-mode setup code; it is
309thus permitted to give the stack/heap the full 64K segment and locate
310the command line above it.
311
312The kernel command line should not be located below the real-mode
313code, nor should it be located in high memory.
314
315
281**** SAMPLE BOOT CONFIGURATION 316**** SAMPLE BOOT CONFIGURATION
282 317
283As a sample configuration, assume the following layout of the real 318As a sample configuration, assume the following layout of the real
284mode segment (this is a typical, and recommended layout): 319mode segment:
320
321 When loading below 0x90000, use the entire segment:
322
323 0x0000-0x7fff Real mode kernel
324 0x8000-0xdfff Stack and heap
325 0xe000-0xffff Kernel command line
285 326
286 0x0000-0x7FFF Real mode kernel 327 When loading at 0x90000 OR the protocol version is 2.01 or earlier:
287 0x8000-0x8FFF Stack and heap 328
288 0x9000-0x90FF Kernel command line 329 0x0000-0x7fff Real mode kernel
330 0x8000-0x97ff Stack and heap
331 0x9800-0x9fff Kernel command line
289 332
290Such a boot loader should enter the following fields in the header: 333Such a boot loader should enter the following fields in the header:
291 334
@@ -301,22 +344,33 @@ Such a boot loader should enter the following fields in the header:
301 ramdisk_image = <initrd_address>; 344 ramdisk_image = <initrd_address>;
302 ramdisk_size = <initrd_size>; 345 ramdisk_size = <initrd_size>;
303 } 346 }
347
348 if ( protocol >= 0x0202 && loadflags & 0x01 )
349 heap_end = 0xe000;
350 else
351 heap_end = 0x9800;
352
304 if ( protocol >= 0x0201 ) { 353 if ( protocol >= 0x0201 ) {
305 heap_end_ptr = 0x9000 - 0x200; 354 heap_end_ptr = heap_end - 0x200;
306 loadflags |= 0x80; /* CAN_USE_HEAP */ 355 loadflags |= 0x80; /* CAN_USE_HEAP */
307 } 356 }
357
308 if ( protocol >= 0x0202 ) { 358 if ( protocol >= 0x0202 ) {
309 cmd_line_ptr = base_ptr + 0x9000; 359 cmd_line_ptr = base_ptr + heap_end;
360 strcpy(cmd_line_ptr, cmdline);
310 } else { 361 } else {
311 cmd_line_magic = 0xA33F; 362 cmd_line_magic = 0xA33F;
312 cmd_line_offset = 0x9000; 363 cmd_line_offset = heap_end;
313 setup_move_size = 0x9100; 364 setup_move_size = heap_end + strlen(cmdline)+1;
365 strcpy(base_ptr+cmd_line_offset, cmdline);
314 } 366 }
315 } else { 367 } else {
316 /* Very old kernel */ 368 /* Very old kernel */
317 369
370 heap_end = 0x9800;
371
318 cmd_line_magic = 0xA33F; 372 cmd_line_magic = 0xA33F;
319 cmd_line_offset = 0x9000; 373 cmd_line_offset = heap_end;
320 374
321 /* A very old kernel MUST have its real-mode code 375 /* A very old kernel MUST have its real-mode code
322 loaded at 0x90000 */ 376 loaded at 0x90000 */
@@ -324,12 +378,11 @@ Such a boot loader should enter the following fields in the header:
324 if ( base_ptr != 0x90000 ) { 378 if ( base_ptr != 0x90000 ) {
325 /* Copy the real-mode kernel */ 379 /* Copy the real-mode kernel */
326 memcpy(0x90000, base_ptr, (setup_sects+1)*512); 380 memcpy(0x90000, base_ptr, (setup_sects+1)*512);
327 /* Copy the command line */
328 memcpy(0x99000, base_ptr+0x9000, 256);
329
330 base_ptr = 0x90000; /* Relocated */ 381 base_ptr = 0x90000; /* Relocated */
331 } 382 }
332 383
384 strcpy(0x90000+cmd_line_offset, cmdline);
385
333 /* It is recommended to clear memory up to the 32K mark */ 386 /* It is recommended to clear memory up to the 32K mark */
334 memset(0x90000 + (setup_sects+1)*512, 0, 387 memset(0x90000 + (setup_sects+1)*512, 0,
335 (64-(setup_sects+1))*512); 388 (64-(setup_sects+1))*512);
@@ -375,10 +428,11 @@ conflict with actual kernel options now or in the future.
375 line is parsed. 428 line is parsed.
376 429
377 mem=<size> 430 mem=<size>
378 <size> is an integer in C notation optionally followed by K, M 431 <size> is an integer in C notation optionally followed by
379 or G (meaning << 10, << 20 or << 30). This specifies the end 432 (case insensitive) K, M, G, T, P or E (meaning << 10, << 20,
380 of memory to the kernel. This affects the possible placement 433 << 30, << 40, << 50 or << 60). This specifies the end of
381 of an initrd, since an initrd should be placed near end of 434 memory to the kernel. This affects the possible placement of
435 an initrd, since an initrd should be placed near end of
382 memory. Note that this is an option to *both* the kernel and 436 memory. Note that this is an option to *both* the kernel and
383 the bootloader! 437 the bootloader!
384 438
@@ -428,7 +482,7 @@ In our example from above, we would do:
428 482
429 /* Set up the real-mode kernel stack */ 483 /* Set up the real-mode kernel stack */
430 _SS = seg; 484 _SS = seg;
431 _SP = 0x9000; /* Load SP immediately after loading SS! */ 485 _SP = heap_end;
432 486
433 _DS = _ES = _FS = _GS = seg; 487 _DS = _ES = _FS = _GS = seg;
434 jmp_far(seg+0x20, 0); /* Run the kernel */ 488 jmp_far(seg+0x20, 0); /* Run the kernel */
@@ -460,8 +514,9 @@ IMPORTANT: All the hooks are required to preserve %esp, %ebp, %esi and
460 code32_start: 514 code32_start:
461 A 32-bit flat-mode routine *jumped* to immediately after the 515 A 32-bit flat-mode routine *jumped* to immediately after the
462 transition to protected mode, but before the kernel is 516 transition to protected mode, but before the kernel is
463 uncompressed. No segments, except CS, are set up; you should 517 uncompressed. No segments, except CS, are guaranteed to be
464 set them up to KERNEL_DS (0x18) yourself. 518 set up (current kernels do, but older ones do not); you should
519 set them up to BOOT_DS (0x18) yourself.
465 520
466 After completing your hook, you should jump to the address 521 After completing your hook, you should jump to the address
467 that was in this field before your boot loader overwrote it. 522 that was in this field before your boot loader overwrote it.