]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - Documentation/i386/boot.txt
Merge branch 'for-linus' of master.kernel.org:/home/rmk/linux-2.6-arm
[linux-2.6-omap-h63xx.git] / Documentation / i386 / boot.txt
index 6498666ea3307dea2e6e67748c5a4983f0fec590..d01b7a2a0f2eea6bdfa219fb88490fcbb6b80a0e 100644 (file)
@@ -2,7 +2,7 @@
                     ----------------------------
 
                    H. Peter Anvin <hpa@zytor.com>
-                       Last update 2007-03-06
+                       Last update 2007-05-07
 
 On the i386 platform, the Linux kernel uses a rather complicated boot
 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
 expectations in the PC industry caused by the effective demise of
 real-mode DOS as a mainstream operating system.
 
-Currently, four versions of the Linux/i386 boot protocol exist.
+Currently, the following versions of the Linux/i386 boot protocol exist.
 
 Old kernels:   zImage/Image support only.  Some very early kernels
                may not even support a command line.
@@ -183,9 +183,9 @@ filled out, however:
        a version number.  Otherwise, enter 0xFF here.
 
        Assigned boot loader ids:
-       0  LILO
+       0  LILO                 (0x00 reserved for pre-2.00 bootloader)
        1  Loadlin
-       2  bootsect-loader
+       2  bootsect-loader      (0x20, all other values reserved)
        3  SYSLINUX
        4  EtherBoot
        5  ELILO
@@ -210,6 +210,9 @@ filled out, however:
        additional data (such as the kernel command line) moved in
        addition to the real-mode kernel itself.
 
+       The unit is bytes starting with the beginning of the boot
+       sector.
+
   ramdisk_image, ramdisk_size:
        If your boot loader has loaded an initial ramdisk (initrd),
        set ramdisk_image to the 32-bit pointer to the ramdisk data
@@ -278,14 +281,54 @@ command line is entered using the following protocol:
        field.
 
 
+**** MEMORY LAYOUT OF THE REAL-MODE CODE
+
+The real-mode code requires a stack/heap to be set up, as well as
+memory allocated for the kernel command line.  This needs to be done
+in the real-mode accessible memory in bottom megabyte.
+
+It should be noted that modern machines often have a sizable Extended
+BIOS Data Area (EBDA).  As a result, it is advisable to use as little
+of the low megabyte as possible.
+
+Unfortunately, under the following circumstances the 0x90000 memory
+segment has to be used:
+
+       - When loading a zImage kernel ((loadflags & 0x01) == 0).
+       - When loading a 2.01 or earlier boot protocol kernel.
+
+         -> For the 2.00 and 2.01 boot protocols, the real-mode code
+            can be loaded at another address, but it is internally
+            relocated to 0x90000.  For the "old" protocol, the
+            real-mode code must be loaded at 0x90000.
+
+When loading at 0x90000, avoid using memory above 0x9a000.
+
+For boot protocol 2.02 or higher, the command line does not have to be
+located in the same 64K segment as the real-mode setup code; it is
+thus permitted to give the stack/heap the full 64K segment and locate
+the command line above it.
+
+The kernel command line should not be located below the real-mode
+code, nor should it be located in high memory.
+
+
 **** SAMPLE BOOT CONFIGURATION
 
 As a sample configuration, assume the following layout of the real
-mode segment (this is a typical, and recommended layout):
+mode segment:
+
+    When loading below 0x90000, use the entire segment:
+
+       0x0000-0x7fff   Real mode kernel
+       0x8000-0xdfff   Stack and heap
+       0xe000-0xffff   Kernel command line
 
-       0x0000-0x7FFF   Real mode kernel
-       0x8000-0x8FFF   Stack and heap
-       0x9000-0x90FF   Kernel command line
+    When loading at 0x90000 OR the protocol version is 2.01 or earlier:
+
+       0x0000-0x7fff   Real mode kernel
+       0x8000-0x97ff   Stack and heap
+       0x9800-0x9fff   Kernel command line
 
 Such a boot loader should enter the following fields in the header:
 
@@ -301,22 +344,33 @@ Such a boot loader should enter the following fields in the header:
                        ramdisk_image = <initrd_address>;
                        ramdisk_size = <initrd_size>;
                }
+
+               if ( protocol >= 0x0202 && loadflags & 0x01 )
+                       heap_end = 0xe000;
+               else
+                       heap_end = 0x9800;
+
                if ( protocol >= 0x0201 ) {
-                       heap_end_ptr = 0x9000 - 0x200;
+                       heap_end_ptr = heap_end - 0x200;
                        loadflags |= 0x80; /* CAN_USE_HEAP */
                }
+
                if ( protocol >= 0x0202 ) {
-                       cmd_line_ptr = base_ptr + 0x9000;
+                       cmd_line_ptr = base_ptr + heap_end;
+                       strcpy(cmd_line_ptr, cmdline);
                } else {
                        cmd_line_magic  = 0xA33F;
-                       cmd_line_offset = 0x9000;
-                       setup_move_size = 0x9100;
+                       cmd_line_offset = heap_end;
+                       setup_move_size = heap_end + strlen(cmdline)+1;
+                       strcpy(base_ptr+cmd_line_offset, cmdline);
                }
        } else {
                /* Very old kernel */
 
+               heap_end = 0x9800;
+
                cmd_line_magic  = 0xA33F;
-               cmd_line_offset = 0x9000;
+               cmd_line_offset = heap_end;
 
                /* A very old kernel MUST have its real-mode code
                   loaded at 0x90000 */
@@ -324,12 +378,11 @@ Such a boot loader should enter the following fields in the header:
                if ( base_ptr != 0x90000 ) {
                        /* Copy the real-mode kernel */
                        memcpy(0x90000, base_ptr, (setup_sects+1)*512);
-                       /* Copy the command line */
-                       memcpy(0x99000, base_ptr+0x9000, 256);
-
                        base_ptr = 0x90000;              /* Relocated */
                }
 
+               strcpy(0x90000+cmd_line_offset, cmdline);
+
                /* It is recommended to clear memory up to the 32K mark */
                memset(0x90000 + (setup_sects+1)*512, 0,
                       (64-(setup_sects+1))*512);
@@ -375,10 +428,11 @@ conflict with actual kernel options now or in the future.
        line is parsed.
 
   mem=<size>
-       <size> is an integer in C notation optionally followed by K, M
-       or G (meaning << 10, << 20 or << 30).  This specifies the end
-       of memory to the kernel. This affects the possible placement
-       of an initrd, since an initrd should be placed near end of
+       <size> is an integer in C notation optionally followed by
+       (case insensitive) K, M, G, T, P or E (meaning << 10, << 20,
+       << 30, << 40, << 50 or << 60).  This specifies the end of
+       memory to the kernel. This affects the possible placement of
+       an initrd, since an initrd should be placed near end of
        memory.  Note that this is an option to *both* the kernel and
        the bootloader!
 
@@ -428,7 +482,7 @@ In our example from above, we would do:
 
        /* Set up the real-mode kernel stack */
        _SS = seg;
-       _SP = 0x9000;   /* Load SP immediately after loading SS! */
+       _SP = heap_end;
 
        _DS = _ES = _FS = _GS = seg;
        jmp_far(seg+0x20, 0);   /* Run the kernel */
@@ -460,8 +514,9 @@ IMPORTANT: All the hooks are required to preserve %esp, %ebp, %esi and
   code32_start:
        A 32-bit flat-mode routine *jumped* to immediately after the
        transition to protected mode, but before the kernel is
-       uncompressed.  No segments, except CS, are set up; you should
-       set them up to KERNEL_DS (0x18) yourself.
+       uncompressed.  No segments, except CS, are guaranteed to be
+       set up (current kernels do, but older ones do not); you should
+       set them up to BOOT_DS (0x18) yourself.
 
        After completing your hook, you should jump to the address
        that was in this field before your boot loader overwrote it.