diff options
Diffstat (limited to 'Documentation')
-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. |