diff options
| -rw-r--r-- | Documentation/i386/boot.txt | 101 | 
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 | ||
| 7 | On the i386 platform, the Linux kernel uses a rather complicated boot | 7 | On the i386 platform, the Linux kernel uses a rather complicated boot | 
| 8 | convention. This has evolved partially due to historical aspects, as | 8 | convention. This has evolved partially due to historical aspects, as | 
| @@ -11,7 +11,7 @@ bootable image, the complicated PC memory model and due to changed | |||
| 11 | expectations in the PC industry caused by the effective demise of | 11 | expectations in the PC industry caused by the effective demise of | 
| 12 | real-mode DOS as a mainstream operating system. | 12 | real-mode DOS as a mainstream operating system. | 
| 13 | 13 | ||
| 14 | Currently, four versions of the Linux/i386 boot protocol exist. | 14 | Currently, the following versions of the Linux/i386 boot protocol exist. | 
| 15 | 15 | ||
| 16 | Old kernels: zImage/Image support only. Some very early kernels | 16 | Old 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 | |||
| 286 | The real-mode code requires a stack/heap to be set up, as well as | ||
| 287 | memory allocated for the kernel command line. This needs to be done | ||
| 288 | in the real-mode accessible memory in bottom megabyte. | ||
| 289 | |||
| 290 | It should be noted that modern machines often have a sizable Extended | ||
| 291 | BIOS Data Area (EBDA). As a result, it is advisable to use as little | ||
| 292 | of the low megabyte as possible. | ||
| 293 | |||
| 294 | Unfortunately, under the following circumstances the 0x90000 memory | ||
| 295 | segment 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 | |||
| 305 | When loading at 0x90000, avoid using memory above 0x9a000. | ||
| 306 | |||
| 307 | For boot protocol 2.02 or higher, the command line does not have to be | ||
| 308 | located in the same 64K segment as the real-mode setup code; it is | ||
| 309 | thus permitted to give the stack/heap the full 64K segment and locate | ||
| 310 | the command line above it. | ||
| 311 | |||
| 312 | The kernel command line should not be located below the real-mode | ||
| 313 | code, nor should it be located in high memory. | ||
| 314 | |||
| 315 | |||
| 281 | **** SAMPLE BOOT CONFIGURATION | 316 | **** SAMPLE BOOT CONFIGURATION | 
| 282 | 317 | ||
| 283 | As a sample configuration, assume the following layout of the real | 318 | As a sample configuration, assume the following layout of the real | 
| 284 | mode segment (this is a typical, and recommended layout): | 319 | mode 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 | ||
| 290 | Such a boot loader should enter the following fields in the header: | 333 | Such 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. | 
