1*ff61f079SJonathan Corbet.. SPDX-License-Identifier: GPL-2.0 2*ff61f079SJonathan Corbet 3*ff61f079SJonathan Corbet=========================== 4*ff61f079SJonathan CorbetThe Linux/x86 Boot Protocol 5*ff61f079SJonathan Corbet=========================== 6*ff61f079SJonathan Corbet 7*ff61f079SJonathan CorbetOn the x86 platform, the Linux kernel uses a rather complicated boot 8*ff61f079SJonathan Corbetconvention. This has evolved partially due to historical aspects, as 9*ff61f079SJonathan Corbetwell as the desire in the early days to have the kernel itself be a 10*ff61f079SJonathan Corbetbootable image, the complicated PC memory model and due to changed 11*ff61f079SJonathan Corbetexpectations in the PC industry caused by the effective demise of 12*ff61f079SJonathan Corbetreal-mode DOS as a mainstream operating system. 13*ff61f079SJonathan Corbet 14*ff61f079SJonathan CorbetCurrently, the following versions of the Linux/x86 boot protocol exist. 15*ff61f079SJonathan Corbet 16*ff61f079SJonathan Corbet============= ============================================================ 17*ff61f079SJonathan CorbetOld kernels zImage/Image support only. Some very early kernels 18*ff61f079SJonathan Corbet may not even support a command line. 19*ff61f079SJonathan Corbet 20*ff61f079SJonathan CorbetProtocol 2.00 (Kernel 1.3.73) Added bzImage and initrd support, as 21*ff61f079SJonathan Corbet well as a formalized way to communicate between the 22*ff61f079SJonathan Corbet boot loader and the kernel. setup.S made relocatable, 23*ff61f079SJonathan Corbet although the traditional setup area still assumed 24*ff61f079SJonathan Corbet writable. 25*ff61f079SJonathan Corbet 26*ff61f079SJonathan CorbetProtocol 2.01 (Kernel 1.3.76) Added a heap overrun warning. 27*ff61f079SJonathan Corbet 28*ff61f079SJonathan CorbetProtocol 2.02 (Kernel 2.4.0-test3-pre3) New command line protocol. 29*ff61f079SJonathan Corbet Lower the conventional memory ceiling. No overwrite 30*ff61f079SJonathan Corbet of the traditional setup area, thus making booting 31*ff61f079SJonathan Corbet safe for systems which use the EBDA from SMM or 32-bit 32*ff61f079SJonathan Corbet BIOS entry points. zImage deprecated but still 33*ff61f079SJonathan Corbet supported. 34*ff61f079SJonathan Corbet 35*ff61f079SJonathan CorbetProtocol 2.03 (Kernel 2.4.18-pre1) Explicitly makes the highest possible 36*ff61f079SJonathan Corbet initrd address available to the bootloader. 37*ff61f079SJonathan Corbet 38*ff61f079SJonathan CorbetProtocol 2.04 (Kernel 2.6.14) Extend the syssize field to four bytes. 39*ff61f079SJonathan Corbet 40*ff61f079SJonathan CorbetProtocol 2.05 (Kernel 2.6.20) Make protected mode kernel relocatable. 41*ff61f079SJonathan Corbet Introduce relocatable_kernel and kernel_alignment fields. 42*ff61f079SJonathan Corbet 43*ff61f079SJonathan CorbetProtocol 2.06 (Kernel 2.6.22) Added a field that contains the size of 44*ff61f079SJonathan Corbet the boot command line. 45*ff61f079SJonathan Corbet 46*ff61f079SJonathan CorbetProtocol 2.07 (Kernel 2.6.24) Added paravirtualised boot protocol. 47*ff61f079SJonathan Corbet Introduced hardware_subarch and hardware_subarch_data 48*ff61f079SJonathan Corbet and KEEP_SEGMENTS flag in load_flags. 49*ff61f079SJonathan Corbet 50*ff61f079SJonathan CorbetProtocol 2.08 (Kernel 2.6.26) Added crc32 checksum and ELF format 51*ff61f079SJonathan Corbet payload. Introduced payload_offset and payload_length 52*ff61f079SJonathan Corbet fields to aid in locating the payload. 53*ff61f079SJonathan Corbet 54*ff61f079SJonathan CorbetProtocol 2.09 (Kernel 2.6.26) Added a field of 64-bit physical 55*ff61f079SJonathan Corbet pointer to single linked list of struct setup_data. 56*ff61f079SJonathan Corbet 57*ff61f079SJonathan CorbetProtocol 2.10 (Kernel 2.6.31) Added a protocol for relaxed alignment 58*ff61f079SJonathan Corbet beyond the kernel_alignment added, new init_size and 59*ff61f079SJonathan Corbet pref_address fields. Added extended boot loader IDs. 60*ff61f079SJonathan Corbet 61*ff61f079SJonathan CorbetProtocol 2.11 (Kernel 3.6) Added a field for offset of EFI handover 62*ff61f079SJonathan Corbet protocol entry point. 63*ff61f079SJonathan Corbet 64*ff61f079SJonathan CorbetProtocol 2.12 (Kernel 3.8) Added the xloadflags field and extension fields 65*ff61f079SJonathan Corbet to struct boot_params for loading bzImage and ramdisk 66*ff61f079SJonathan Corbet above 4G in 64bit. 67*ff61f079SJonathan Corbet 68*ff61f079SJonathan CorbetProtocol 2.13 (Kernel 3.14) Support 32- and 64-bit flags being set in 69*ff61f079SJonathan Corbet xloadflags to support booting a 64-bit kernel from 32-bit 70*ff61f079SJonathan Corbet EFI 71*ff61f079SJonathan Corbet 72*ff61f079SJonathan CorbetProtocol 2.14 BURNT BY INCORRECT COMMIT 73*ff61f079SJonathan Corbet ae7e1238e68f2a472a125673ab506d49158c1889 74*ff61f079SJonathan Corbet (x86/boot: Add ACPI RSDP address to setup_header) 75*ff61f079SJonathan Corbet DO NOT USE!!! ASSUME SAME AS 2.13. 76*ff61f079SJonathan Corbet 77*ff61f079SJonathan CorbetProtocol 2.15 (Kernel 5.5) Added the kernel_info and kernel_info.setup_type_max. 78*ff61f079SJonathan Corbet============= ============================================================ 79*ff61f079SJonathan Corbet 80*ff61f079SJonathan Corbet.. note:: 81*ff61f079SJonathan Corbet The protocol version number should be changed only if the setup header 82*ff61f079SJonathan Corbet is changed. There is no need to update the version number if boot_params 83*ff61f079SJonathan Corbet or kernel_info are changed. Additionally, it is recommended to use 84*ff61f079SJonathan Corbet xloadflags (in this case the protocol version number should not be 85*ff61f079SJonathan Corbet updated either) or kernel_info to communicate supported Linux kernel 86*ff61f079SJonathan Corbet features to the boot loader. Due to very limited space available in 87*ff61f079SJonathan Corbet the original setup header every update to it should be considered 88*ff61f079SJonathan Corbet with great care. Starting from the protocol 2.15 the primary way to 89*ff61f079SJonathan Corbet communicate things to the boot loader is the kernel_info. 90*ff61f079SJonathan Corbet 91*ff61f079SJonathan Corbet 92*ff61f079SJonathan CorbetMemory Layout 93*ff61f079SJonathan Corbet============= 94*ff61f079SJonathan Corbet 95*ff61f079SJonathan CorbetThe traditional memory map for the kernel loader, used for Image or 96*ff61f079SJonathan CorbetzImage kernels, typically looks like:: 97*ff61f079SJonathan Corbet 98*ff61f079SJonathan Corbet | | 99*ff61f079SJonathan Corbet 0A0000 +------------------------+ 100*ff61f079SJonathan Corbet | Reserved for BIOS | Do not use. Reserved for BIOS EBDA. 101*ff61f079SJonathan Corbet 09A000 +------------------------+ 102*ff61f079SJonathan Corbet | Command line | 103*ff61f079SJonathan Corbet | Stack/heap | For use by the kernel real-mode code. 104*ff61f079SJonathan Corbet 098000 +------------------------+ 105*ff61f079SJonathan Corbet | Kernel setup | The kernel real-mode code. 106*ff61f079SJonathan Corbet 090200 +------------------------+ 107*ff61f079SJonathan Corbet | Kernel boot sector | The kernel legacy boot sector. 108*ff61f079SJonathan Corbet 090000 +------------------------+ 109*ff61f079SJonathan Corbet | Protected-mode kernel | The bulk of the kernel image. 110*ff61f079SJonathan Corbet 010000 +------------------------+ 111*ff61f079SJonathan Corbet | Boot loader | <- Boot sector entry point 0000:7C00 112*ff61f079SJonathan Corbet 001000 +------------------------+ 113*ff61f079SJonathan Corbet | Reserved for MBR/BIOS | 114*ff61f079SJonathan Corbet 000800 +------------------------+ 115*ff61f079SJonathan Corbet | Typically used by MBR | 116*ff61f079SJonathan Corbet 000600 +------------------------+ 117*ff61f079SJonathan Corbet | BIOS use only | 118*ff61f079SJonathan Corbet 000000 +------------------------+ 119*ff61f079SJonathan Corbet 120*ff61f079SJonathan CorbetWhen using bzImage, the protected-mode kernel was relocated to 121*ff61f079SJonathan Corbet0x100000 ("high memory"), and the kernel real-mode block (boot sector, 122*ff61f079SJonathan Corbetsetup, and stack/heap) was made relocatable to any address between 123*ff61f079SJonathan Corbet0x10000 and end of low memory. Unfortunately, in protocols 2.00 and 124*ff61f079SJonathan Corbet2.01 the 0x90000+ memory range is still used internally by the kernel; 125*ff61f079SJonathan Corbetthe 2.02 protocol resolves that problem. 126*ff61f079SJonathan Corbet 127*ff61f079SJonathan CorbetIt is desirable to keep the "memory ceiling" -- the highest point in 128*ff61f079SJonathan Corbetlow memory touched by the boot loader -- as low as possible, since 129*ff61f079SJonathan Corbetsome newer BIOSes have begun to allocate some rather large amounts of 130*ff61f079SJonathan Corbetmemory, called the Extended BIOS Data Area, near the top of low 131*ff61f079SJonathan Corbetmemory. The boot loader should use the "INT 12h" BIOS call to verify 132*ff61f079SJonathan Corbethow much low memory is available. 133*ff61f079SJonathan Corbet 134*ff61f079SJonathan CorbetUnfortunately, if INT 12h reports that the amount of memory is too 135*ff61f079SJonathan Corbetlow, there is usually nothing the boot loader can do but to report an 136*ff61f079SJonathan Corbeterror to the user. The boot loader should therefore be designed to 137*ff61f079SJonathan Corbettake up as little space in low memory as it reasonably can. For 138*ff61f079SJonathan CorbetzImage or old bzImage kernels, which need data written into the 139*ff61f079SJonathan Corbet0x90000 segment, the boot loader should make sure not to use memory 140*ff61f079SJonathan Corbetabove the 0x9A000 point; too many BIOSes will break above that point. 141*ff61f079SJonathan Corbet 142*ff61f079SJonathan CorbetFor a modern bzImage kernel with boot protocol version >= 2.02, a 143*ff61f079SJonathan Corbetmemory layout like the following is suggested:: 144*ff61f079SJonathan Corbet 145*ff61f079SJonathan Corbet ~ ~ 146*ff61f079SJonathan Corbet | Protected-mode kernel | 147*ff61f079SJonathan Corbet 100000 +------------------------+ 148*ff61f079SJonathan Corbet | I/O memory hole | 149*ff61f079SJonathan Corbet 0A0000 +------------------------+ 150*ff61f079SJonathan Corbet | Reserved for BIOS | Leave as much as possible unused 151*ff61f079SJonathan Corbet ~ ~ 152*ff61f079SJonathan Corbet | Command line | (Can also be below the X+10000 mark) 153*ff61f079SJonathan Corbet X+10000 +------------------------+ 154*ff61f079SJonathan Corbet | Stack/heap | For use by the kernel real-mode code. 155*ff61f079SJonathan Corbet X+08000 +------------------------+ 156*ff61f079SJonathan Corbet | Kernel setup | The kernel real-mode code. 157*ff61f079SJonathan Corbet | Kernel boot sector | The kernel legacy boot sector. 158*ff61f079SJonathan Corbet X +------------------------+ 159*ff61f079SJonathan Corbet | Boot loader | <- Boot sector entry point 0000:7C00 160*ff61f079SJonathan Corbet 001000 +------------------------+ 161*ff61f079SJonathan Corbet | Reserved for MBR/BIOS | 162*ff61f079SJonathan Corbet 000800 +------------------------+ 163*ff61f079SJonathan Corbet | Typically used by MBR | 164*ff61f079SJonathan Corbet 000600 +------------------------+ 165*ff61f079SJonathan Corbet | BIOS use only | 166*ff61f079SJonathan Corbet 000000 +------------------------+ 167*ff61f079SJonathan Corbet 168*ff61f079SJonathan Corbet ... where the address X is as low as the design of the boot loader permits. 169*ff61f079SJonathan Corbet 170*ff61f079SJonathan Corbet 171*ff61f079SJonathan CorbetThe Real-Mode Kernel Header 172*ff61f079SJonathan Corbet=========================== 173*ff61f079SJonathan Corbet 174*ff61f079SJonathan CorbetIn the following text, and anywhere in the kernel boot sequence, "a 175*ff61f079SJonathan Corbetsector" refers to 512 bytes. It is independent of the actual sector 176*ff61f079SJonathan Corbetsize of the underlying medium. 177*ff61f079SJonathan Corbet 178*ff61f079SJonathan CorbetThe first step in loading a Linux kernel should be to load the 179*ff61f079SJonathan Corbetreal-mode code (boot sector and setup code) and then examine the 180*ff61f079SJonathan Corbetfollowing header at offset 0x01f1. The real-mode code can total up to 181*ff61f079SJonathan Corbet32K, although the boot loader may choose to load only the first two 182*ff61f079SJonathan Corbetsectors (1K) and then examine the bootup sector size. 183*ff61f079SJonathan Corbet 184*ff61f079SJonathan CorbetThe header looks like: 185*ff61f079SJonathan Corbet 186*ff61f079SJonathan Corbet=========== ======== ===================== ============================================ 187*ff61f079SJonathan CorbetOffset/Size Proto Name Meaning 188*ff61f079SJonathan Corbet=========== ======== ===================== ============================================ 189*ff61f079SJonathan Corbet01F1/1 ALL(1) setup_sects The size of the setup in sectors 190*ff61f079SJonathan Corbet01F2/2 ALL root_flags If set, the root is mounted readonly 191*ff61f079SJonathan Corbet01F4/4 2.04+(2) syssize The size of the 32-bit code in 16-byte paras 192*ff61f079SJonathan Corbet01F8/2 ALL ram_size DO NOT USE - for bootsect.S use only 193*ff61f079SJonathan Corbet01FA/2 ALL vid_mode Video mode control 194*ff61f079SJonathan Corbet01FC/2 ALL root_dev Default root device number 195*ff61f079SJonathan Corbet01FE/2 ALL boot_flag 0xAA55 magic number 196*ff61f079SJonathan Corbet0200/2 2.00+ jump Jump instruction 197*ff61f079SJonathan Corbet0202/4 2.00+ header Magic signature "HdrS" 198*ff61f079SJonathan Corbet0206/2 2.00+ version Boot protocol version supported 199*ff61f079SJonathan Corbet0208/4 2.00+ realmode_swtch Boot loader hook (see below) 200*ff61f079SJonathan Corbet020C/2 2.00+ start_sys_seg The load-low segment (0x1000) (obsolete) 201*ff61f079SJonathan Corbet020E/2 2.00+ kernel_version Pointer to kernel version string 202*ff61f079SJonathan Corbet0210/1 2.00+ type_of_loader Boot loader identifier 203*ff61f079SJonathan Corbet0211/1 2.00+ loadflags Boot protocol option flags 204*ff61f079SJonathan Corbet0212/2 2.00+ setup_move_size Move to high memory size (used with hooks) 205*ff61f079SJonathan Corbet0214/4 2.00+ code32_start Boot loader hook (see below) 206*ff61f079SJonathan Corbet0218/4 2.00+ ramdisk_image initrd load address (set by boot loader) 207*ff61f079SJonathan Corbet021C/4 2.00+ ramdisk_size initrd size (set by boot loader) 208*ff61f079SJonathan Corbet0220/4 2.00+ bootsect_kludge DO NOT USE - for bootsect.S use only 209*ff61f079SJonathan Corbet0224/2 2.01+ heap_end_ptr Free memory after setup end 210*ff61f079SJonathan Corbet0226/1 2.02+(3) ext_loader_ver Extended boot loader version 211*ff61f079SJonathan Corbet0227/1 2.02+(3) ext_loader_type Extended boot loader ID 212*ff61f079SJonathan Corbet0228/4 2.02+ cmd_line_ptr 32-bit pointer to the kernel command line 213*ff61f079SJonathan Corbet022C/4 2.03+ initrd_addr_max Highest legal initrd address 214*ff61f079SJonathan Corbet0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel 215*ff61f079SJonathan Corbet0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not 216*ff61f079SJonathan Corbet0235/1 2.10+ min_alignment Minimum alignment, as a power of two 217*ff61f079SJonathan Corbet0236/2 2.12+ xloadflags Boot protocol option flags 218*ff61f079SJonathan Corbet0238/4 2.06+ cmdline_size Maximum size of the kernel command line 219*ff61f079SJonathan Corbet023C/4 2.07+ hardware_subarch Hardware subarchitecture 220*ff61f079SJonathan Corbet0240/8 2.07+ hardware_subarch_data Subarchitecture-specific data 221*ff61f079SJonathan Corbet0248/4 2.08+ payload_offset Offset of kernel payload 222*ff61f079SJonathan Corbet024C/4 2.08+ payload_length Length of kernel payload 223*ff61f079SJonathan Corbet0250/8 2.09+ setup_data 64-bit physical pointer to linked list 224*ff61f079SJonathan Corbet of struct setup_data 225*ff61f079SJonathan Corbet0258/8 2.10+ pref_address Preferred loading address 226*ff61f079SJonathan Corbet0260/4 2.10+ init_size Linear memory required during initialization 227*ff61f079SJonathan Corbet0264/4 2.11+ handover_offset Offset of handover entry point 228*ff61f079SJonathan Corbet0268/4 2.15+ kernel_info_offset Offset of the kernel_info 229*ff61f079SJonathan Corbet=========== ======== ===================== ============================================ 230*ff61f079SJonathan Corbet 231*ff61f079SJonathan Corbet.. note:: 232*ff61f079SJonathan Corbet (1) For backwards compatibility, if the setup_sects field contains 0, the 233*ff61f079SJonathan Corbet real value is 4. 234*ff61f079SJonathan Corbet 235*ff61f079SJonathan Corbet (2) For boot protocol prior to 2.04, the upper two bytes of the syssize 236*ff61f079SJonathan Corbet field are unusable, which means the size of a bzImage kernel 237*ff61f079SJonathan Corbet cannot be determined. 238*ff61f079SJonathan Corbet 239*ff61f079SJonathan Corbet (3) Ignored, but safe to set, for boot protocols 2.02-2.09. 240*ff61f079SJonathan Corbet 241*ff61f079SJonathan CorbetIf the "HdrS" (0x53726448) magic number is not found at offset 0x202, 242*ff61f079SJonathan Corbetthe boot protocol version is "old". Loading an old kernel, the 243*ff61f079SJonathan Corbetfollowing parameters should be assumed:: 244*ff61f079SJonathan Corbet 245*ff61f079SJonathan Corbet Image type = zImage 246*ff61f079SJonathan Corbet initrd not supported 247*ff61f079SJonathan Corbet Real-mode kernel must be located at 0x90000. 248*ff61f079SJonathan Corbet 249*ff61f079SJonathan CorbetOtherwise, the "version" field contains the protocol version, 250*ff61f079SJonathan Corbete.g. protocol version 2.01 will contain 0x0201 in this field. When 251*ff61f079SJonathan Corbetsetting fields in the header, you must make sure only to set fields 252*ff61f079SJonathan Corbetsupported by the protocol version in use. 253*ff61f079SJonathan Corbet 254*ff61f079SJonathan Corbet 255*ff61f079SJonathan CorbetDetails of Header Fields 256*ff61f079SJonathan Corbet======================== 257*ff61f079SJonathan Corbet 258*ff61f079SJonathan CorbetFor each field, some are information from the kernel to the bootloader 259*ff61f079SJonathan Corbet("read"), some are expected to be filled out by the bootloader 260*ff61f079SJonathan Corbet("write"), and some are expected to be read and modified by the 261*ff61f079SJonathan Corbetbootloader ("modify"). 262*ff61f079SJonathan Corbet 263*ff61f079SJonathan CorbetAll general purpose boot loaders should write the fields marked 264*ff61f079SJonathan Corbet(obligatory). Boot loaders who want to load the kernel at a 265*ff61f079SJonathan Corbetnonstandard address should fill in the fields marked (reloc); other 266*ff61f079SJonathan Corbetboot loaders can ignore those fields. 267*ff61f079SJonathan Corbet 268*ff61f079SJonathan CorbetThe byte order of all fields is littleendian (this is x86, after all.) 269*ff61f079SJonathan Corbet 270*ff61f079SJonathan Corbet============ =========== 271*ff61f079SJonathan CorbetField name: setup_sects 272*ff61f079SJonathan CorbetType: read 273*ff61f079SJonathan CorbetOffset/size: 0x1f1/1 274*ff61f079SJonathan CorbetProtocol: ALL 275*ff61f079SJonathan Corbet============ =========== 276*ff61f079SJonathan Corbet 277*ff61f079SJonathan Corbet The size of the setup code in 512-byte sectors. If this field is 278*ff61f079SJonathan Corbet 0, the real value is 4. The real-mode code consists of the boot 279*ff61f079SJonathan Corbet sector (always one 512-byte sector) plus the setup code. 280*ff61f079SJonathan Corbet 281*ff61f079SJonathan Corbet============ ================= 282*ff61f079SJonathan CorbetField name: root_flags 283*ff61f079SJonathan CorbetType: modify (optional) 284*ff61f079SJonathan CorbetOffset/size: 0x1f2/2 285*ff61f079SJonathan CorbetProtocol: ALL 286*ff61f079SJonathan Corbet============ ================= 287*ff61f079SJonathan Corbet 288*ff61f079SJonathan Corbet If this field is nonzero, the root defaults to readonly. The use of 289*ff61f079SJonathan Corbet this field is deprecated; use the "ro" or "rw" options on the 290*ff61f079SJonathan Corbet command line instead. 291*ff61f079SJonathan Corbet 292*ff61f079SJonathan Corbet============ =============================================== 293*ff61f079SJonathan CorbetField name: syssize 294*ff61f079SJonathan CorbetType: read 295*ff61f079SJonathan CorbetOffset/size: 0x1f4/4 (protocol 2.04+) 0x1f4/2 (protocol ALL) 296*ff61f079SJonathan CorbetProtocol: 2.04+ 297*ff61f079SJonathan Corbet============ =============================================== 298*ff61f079SJonathan Corbet 299*ff61f079SJonathan Corbet The size of the protected-mode code in units of 16-byte paragraphs. 300*ff61f079SJonathan Corbet For protocol versions older than 2.04 this field is only two bytes 301*ff61f079SJonathan Corbet wide, and therefore cannot be trusted for the size of a kernel if 302*ff61f079SJonathan Corbet the LOAD_HIGH flag is set. 303*ff61f079SJonathan Corbet 304*ff61f079SJonathan Corbet============ =============== 305*ff61f079SJonathan CorbetField name: ram_size 306*ff61f079SJonathan CorbetType: kernel internal 307*ff61f079SJonathan CorbetOffset/size: 0x1f8/2 308*ff61f079SJonathan CorbetProtocol: ALL 309*ff61f079SJonathan Corbet============ =============== 310*ff61f079SJonathan Corbet 311*ff61f079SJonathan Corbet This field is obsolete. 312*ff61f079SJonathan Corbet 313*ff61f079SJonathan Corbet============ =================== 314*ff61f079SJonathan CorbetField name: vid_mode 315*ff61f079SJonathan CorbetType: modify (obligatory) 316*ff61f079SJonathan CorbetOffset/size: 0x1fa/2 317*ff61f079SJonathan Corbet============ =================== 318*ff61f079SJonathan Corbet 319*ff61f079SJonathan Corbet Please see the section on SPECIAL COMMAND LINE OPTIONS. 320*ff61f079SJonathan Corbet 321*ff61f079SJonathan Corbet============ ================= 322*ff61f079SJonathan CorbetField name: root_dev 323*ff61f079SJonathan CorbetType: modify (optional) 324*ff61f079SJonathan CorbetOffset/size: 0x1fc/2 325*ff61f079SJonathan CorbetProtocol: ALL 326*ff61f079SJonathan Corbet============ ================= 327*ff61f079SJonathan Corbet 328*ff61f079SJonathan Corbet The default root device device number. The use of this field is 329*ff61f079SJonathan Corbet deprecated, use the "root=" option on the command line instead. 330*ff61f079SJonathan Corbet 331*ff61f079SJonathan Corbet============ ========= 332*ff61f079SJonathan CorbetField name: boot_flag 333*ff61f079SJonathan CorbetType: read 334*ff61f079SJonathan CorbetOffset/size: 0x1fe/2 335*ff61f079SJonathan CorbetProtocol: ALL 336*ff61f079SJonathan Corbet============ ========= 337*ff61f079SJonathan Corbet 338*ff61f079SJonathan Corbet Contains 0xAA55. This is the closest thing old Linux kernels have 339*ff61f079SJonathan Corbet to a magic number. 340*ff61f079SJonathan Corbet 341*ff61f079SJonathan Corbet============ ======= 342*ff61f079SJonathan CorbetField name: jump 343*ff61f079SJonathan CorbetType: read 344*ff61f079SJonathan CorbetOffset/size: 0x200/2 345*ff61f079SJonathan CorbetProtocol: 2.00+ 346*ff61f079SJonathan Corbet============ ======= 347*ff61f079SJonathan Corbet 348*ff61f079SJonathan Corbet Contains an x86 jump instruction, 0xEB followed by a signed offset 349*ff61f079SJonathan Corbet relative to byte 0x202. This can be used to determine the size of 350*ff61f079SJonathan Corbet the header. 351*ff61f079SJonathan Corbet 352*ff61f079SJonathan Corbet============ ======= 353*ff61f079SJonathan CorbetField name: header 354*ff61f079SJonathan CorbetType: read 355*ff61f079SJonathan CorbetOffset/size: 0x202/4 356*ff61f079SJonathan CorbetProtocol: 2.00+ 357*ff61f079SJonathan Corbet============ ======= 358*ff61f079SJonathan Corbet 359*ff61f079SJonathan Corbet Contains the magic number "HdrS" (0x53726448). 360*ff61f079SJonathan Corbet 361*ff61f079SJonathan Corbet============ ======= 362*ff61f079SJonathan CorbetField name: version 363*ff61f079SJonathan CorbetType: read 364*ff61f079SJonathan CorbetOffset/size: 0x206/2 365*ff61f079SJonathan CorbetProtocol: 2.00+ 366*ff61f079SJonathan Corbet============ ======= 367*ff61f079SJonathan Corbet 368*ff61f079SJonathan Corbet Contains the boot protocol version, in (major << 8)+minor format, 369*ff61f079SJonathan Corbet e.g. 0x0204 for version 2.04, and 0x0a11 for a hypothetical version 370*ff61f079SJonathan Corbet 10.17. 371*ff61f079SJonathan Corbet 372*ff61f079SJonathan Corbet============ ================= 373*ff61f079SJonathan CorbetField name: realmode_swtch 374*ff61f079SJonathan CorbetType: modify (optional) 375*ff61f079SJonathan CorbetOffset/size: 0x208/4 376*ff61f079SJonathan CorbetProtocol: 2.00+ 377*ff61f079SJonathan Corbet============ ================= 378*ff61f079SJonathan Corbet 379*ff61f079SJonathan Corbet Boot loader hook (see ADVANCED BOOT LOADER HOOKS below.) 380*ff61f079SJonathan Corbet 381*ff61f079SJonathan Corbet============ ============= 382*ff61f079SJonathan CorbetField name: start_sys_seg 383*ff61f079SJonathan CorbetType: read 384*ff61f079SJonathan CorbetOffset/size: 0x20c/2 385*ff61f079SJonathan CorbetProtocol: 2.00+ 386*ff61f079SJonathan Corbet============ ============= 387*ff61f079SJonathan Corbet 388*ff61f079SJonathan Corbet The load low segment (0x1000). Obsolete. 389*ff61f079SJonathan Corbet 390*ff61f079SJonathan Corbet============ ============== 391*ff61f079SJonathan CorbetField name: kernel_version 392*ff61f079SJonathan CorbetType: read 393*ff61f079SJonathan CorbetOffset/size: 0x20e/2 394*ff61f079SJonathan CorbetProtocol: 2.00+ 395*ff61f079SJonathan Corbet============ ============== 396*ff61f079SJonathan Corbet 397*ff61f079SJonathan Corbet If set to a nonzero value, contains a pointer to a NUL-terminated 398*ff61f079SJonathan Corbet human-readable kernel version number string, less 0x200. This can 399*ff61f079SJonathan Corbet be used to display the kernel version to the user. This value 400*ff61f079SJonathan Corbet should be less than (0x200*setup_sects). 401*ff61f079SJonathan Corbet 402*ff61f079SJonathan Corbet For example, if this value is set to 0x1c00, the kernel version 403*ff61f079SJonathan Corbet number string can be found at offset 0x1e00 in the kernel file. 404*ff61f079SJonathan Corbet This is a valid value if and only if the "setup_sects" field 405*ff61f079SJonathan Corbet contains the value 15 or higher, as:: 406*ff61f079SJonathan Corbet 407*ff61f079SJonathan Corbet 0x1c00 < 15*0x200 (= 0x1e00) but 408*ff61f079SJonathan Corbet 0x1c00 >= 14*0x200 (= 0x1c00) 409*ff61f079SJonathan Corbet 410*ff61f079SJonathan Corbet 0x1c00 >> 9 = 14, So the minimum value for setup_secs is 15. 411*ff61f079SJonathan Corbet 412*ff61f079SJonathan Corbet============ ================== 413*ff61f079SJonathan CorbetField name: type_of_loader 414*ff61f079SJonathan CorbetType: write (obligatory) 415*ff61f079SJonathan CorbetOffset/size: 0x210/1 416*ff61f079SJonathan CorbetProtocol: 2.00+ 417*ff61f079SJonathan Corbet============ ================== 418*ff61f079SJonathan Corbet 419*ff61f079SJonathan Corbet If your boot loader has an assigned id (see table below), enter 420*ff61f079SJonathan Corbet 0xTV here, where T is an identifier for the boot loader and V is 421*ff61f079SJonathan Corbet a version number. Otherwise, enter 0xFF here. 422*ff61f079SJonathan Corbet 423*ff61f079SJonathan Corbet For boot loader IDs above T = 0xD, write T = 0xE to this field and 424*ff61f079SJonathan Corbet write the extended ID minus 0x10 to the ext_loader_type field. 425*ff61f079SJonathan Corbet Similarly, the ext_loader_ver field can be used to provide more than 426*ff61f079SJonathan Corbet four bits for the bootloader version. 427*ff61f079SJonathan Corbet 428*ff61f079SJonathan Corbet For example, for T = 0x15, V = 0x234, write:: 429*ff61f079SJonathan Corbet 430*ff61f079SJonathan Corbet type_of_loader <- 0xE4 431*ff61f079SJonathan Corbet ext_loader_type <- 0x05 432*ff61f079SJonathan Corbet ext_loader_ver <- 0x23 433*ff61f079SJonathan Corbet 434*ff61f079SJonathan Corbet Assigned boot loader ids (hexadecimal): 435*ff61f079SJonathan Corbet 436*ff61f079SJonathan Corbet == ======================================= 437*ff61f079SJonathan Corbet 0 LILO 438*ff61f079SJonathan Corbet (0x00 reserved for pre-2.00 bootloader) 439*ff61f079SJonathan Corbet 1 Loadlin 440*ff61f079SJonathan Corbet 2 bootsect-loader 441*ff61f079SJonathan Corbet (0x20, all other values reserved) 442*ff61f079SJonathan Corbet 3 Syslinux 443*ff61f079SJonathan Corbet 4 Etherboot/gPXE/iPXE 444*ff61f079SJonathan Corbet 5 ELILO 445*ff61f079SJonathan Corbet 7 GRUB 446*ff61f079SJonathan Corbet 8 U-Boot 447*ff61f079SJonathan Corbet 9 Xen 448*ff61f079SJonathan Corbet A Gujin 449*ff61f079SJonathan Corbet B Qemu 450*ff61f079SJonathan Corbet C Arcturus Networks uCbootloader 451*ff61f079SJonathan Corbet D kexec-tools 452*ff61f079SJonathan Corbet E Extended (see ext_loader_type) 453*ff61f079SJonathan Corbet F Special (0xFF = undefined) 454*ff61f079SJonathan Corbet 10 Reserved 455*ff61f079SJonathan Corbet 11 Minimal Linux Bootloader 456*ff61f079SJonathan Corbet <http://sebastian-plotz.blogspot.de> 457*ff61f079SJonathan Corbet 12 OVMF UEFI virtualization stack 458*ff61f079SJonathan Corbet 13 barebox 459*ff61f079SJonathan Corbet == ======================================= 460*ff61f079SJonathan Corbet 461*ff61f079SJonathan Corbet Please contact <hpa@zytor.com> if you need a bootloader ID value assigned. 462*ff61f079SJonathan Corbet 463*ff61f079SJonathan Corbet============ =================== 464*ff61f079SJonathan CorbetField name: loadflags 465*ff61f079SJonathan CorbetType: modify (obligatory) 466*ff61f079SJonathan CorbetOffset/size: 0x211/1 467*ff61f079SJonathan CorbetProtocol: 2.00+ 468*ff61f079SJonathan Corbet============ =================== 469*ff61f079SJonathan Corbet 470*ff61f079SJonathan Corbet This field is a bitmask. 471*ff61f079SJonathan Corbet 472*ff61f079SJonathan Corbet Bit 0 (read): LOADED_HIGH 473*ff61f079SJonathan Corbet 474*ff61f079SJonathan Corbet - If 0, the protected-mode code is loaded at 0x10000. 475*ff61f079SJonathan Corbet - If 1, the protected-mode code is loaded at 0x100000. 476*ff61f079SJonathan Corbet 477*ff61f079SJonathan Corbet Bit 1 (kernel internal): KASLR_FLAG 478*ff61f079SJonathan Corbet 479*ff61f079SJonathan Corbet - Used internally by the compressed kernel to communicate 480*ff61f079SJonathan Corbet KASLR status to kernel proper. 481*ff61f079SJonathan Corbet 482*ff61f079SJonathan Corbet - If 1, KASLR enabled. 483*ff61f079SJonathan Corbet - If 0, KASLR disabled. 484*ff61f079SJonathan Corbet 485*ff61f079SJonathan Corbet Bit 5 (write): QUIET_FLAG 486*ff61f079SJonathan Corbet 487*ff61f079SJonathan Corbet - If 0, print early messages. 488*ff61f079SJonathan Corbet - If 1, suppress early messages. 489*ff61f079SJonathan Corbet 490*ff61f079SJonathan Corbet This requests to the kernel (decompressor and early 491*ff61f079SJonathan Corbet kernel) to not write early messages that require 492*ff61f079SJonathan Corbet accessing the display hardware directly. 493*ff61f079SJonathan Corbet 494*ff61f079SJonathan Corbet Bit 6 (obsolete): KEEP_SEGMENTS 495*ff61f079SJonathan Corbet 496*ff61f079SJonathan Corbet Protocol: 2.07+ 497*ff61f079SJonathan Corbet 498*ff61f079SJonathan Corbet - This flag is obsolete. 499*ff61f079SJonathan Corbet 500*ff61f079SJonathan Corbet Bit 7 (write): CAN_USE_HEAP 501*ff61f079SJonathan Corbet 502*ff61f079SJonathan Corbet Set this bit to 1 to indicate that the value entered in the 503*ff61f079SJonathan Corbet heap_end_ptr is valid. If this field is clear, some setup code 504*ff61f079SJonathan Corbet functionality will be disabled. 505*ff61f079SJonathan Corbet 506*ff61f079SJonathan Corbet 507*ff61f079SJonathan Corbet============ =================== 508*ff61f079SJonathan CorbetField name: setup_move_size 509*ff61f079SJonathan CorbetType: modify (obligatory) 510*ff61f079SJonathan CorbetOffset/size: 0x212/2 511*ff61f079SJonathan CorbetProtocol: 2.00-2.01 512*ff61f079SJonathan Corbet============ =================== 513*ff61f079SJonathan Corbet 514*ff61f079SJonathan Corbet When using protocol 2.00 or 2.01, if the real mode kernel is not 515*ff61f079SJonathan Corbet loaded at 0x90000, it gets moved there later in the loading 516*ff61f079SJonathan Corbet sequence. Fill in this field if you want additional data (such as 517*ff61f079SJonathan Corbet the kernel command line) moved in addition to the real-mode kernel 518*ff61f079SJonathan Corbet itself. 519*ff61f079SJonathan Corbet 520*ff61f079SJonathan Corbet The unit is bytes starting with the beginning of the boot sector. 521*ff61f079SJonathan Corbet 522*ff61f079SJonathan Corbet This field is can be ignored when the protocol is 2.02 or higher, or 523*ff61f079SJonathan Corbet if the real-mode code is loaded at 0x90000. 524*ff61f079SJonathan Corbet 525*ff61f079SJonathan Corbet============ ======================== 526*ff61f079SJonathan CorbetField name: code32_start 527*ff61f079SJonathan CorbetType: modify (optional, reloc) 528*ff61f079SJonathan CorbetOffset/size: 0x214/4 529*ff61f079SJonathan CorbetProtocol: 2.00+ 530*ff61f079SJonathan Corbet============ ======================== 531*ff61f079SJonathan Corbet 532*ff61f079SJonathan Corbet The address to jump to in protected mode. This defaults to the load 533*ff61f079SJonathan Corbet address of the kernel, and can be used by the boot loader to 534*ff61f079SJonathan Corbet determine the proper load address. 535*ff61f079SJonathan Corbet 536*ff61f079SJonathan Corbet This field can be modified for two purposes: 537*ff61f079SJonathan Corbet 538*ff61f079SJonathan Corbet 1. as a boot loader hook (see Advanced Boot Loader Hooks below.) 539*ff61f079SJonathan Corbet 540*ff61f079SJonathan Corbet 2. if a bootloader which does not install a hook loads a 541*ff61f079SJonathan Corbet relocatable kernel at a nonstandard address it will have to modify 542*ff61f079SJonathan Corbet this field to point to the load address. 543*ff61f079SJonathan Corbet 544*ff61f079SJonathan Corbet============ ================== 545*ff61f079SJonathan CorbetField name: ramdisk_image 546*ff61f079SJonathan CorbetType: write (obligatory) 547*ff61f079SJonathan CorbetOffset/size: 0x218/4 548*ff61f079SJonathan CorbetProtocol: 2.00+ 549*ff61f079SJonathan Corbet============ ================== 550*ff61f079SJonathan Corbet 551*ff61f079SJonathan Corbet The 32-bit linear address of the initial ramdisk or ramfs. Leave at 552*ff61f079SJonathan Corbet zero if there is no initial ramdisk/ramfs. 553*ff61f079SJonathan Corbet 554*ff61f079SJonathan Corbet============ ================== 555*ff61f079SJonathan CorbetField name: ramdisk_size 556*ff61f079SJonathan CorbetType: write (obligatory) 557*ff61f079SJonathan CorbetOffset/size: 0x21c/4 558*ff61f079SJonathan CorbetProtocol: 2.00+ 559*ff61f079SJonathan Corbet============ ================== 560*ff61f079SJonathan Corbet 561*ff61f079SJonathan Corbet Size of the initial ramdisk or ramfs. Leave at zero if there is no 562*ff61f079SJonathan Corbet initial ramdisk/ramfs. 563*ff61f079SJonathan Corbet 564*ff61f079SJonathan Corbet============ =============== 565*ff61f079SJonathan CorbetField name: bootsect_kludge 566*ff61f079SJonathan CorbetType: kernel internal 567*ff61f079SJonathan CorbetOffset/size: 0x220/4 568*ff61f079SJonathan CorbetProtocol: 2.00+ 569*ff61f079SJonathan Corbet============ =============== 570*ff61f079SJonathan Corbet 571*ff61f079SJonathan Corbet This field is obsolete. 572*ff61f079SJonathan Corbet 573*ff61f079SJonathan Corbet============ ================== 574*ff61f079SJonathan CorbetField name: heap_end_ptr 575*ff61f079SJonathan CorbetType: write (obligatory) 576*ff61f079SJonathan CorbetOffset/size: 0x224/2 577*ff61f079SJonathan CorbetProtocol: 2.01+ 578*ff61f079SJonathan Corbet============ ================== 579*ff61f079SJonathan Corbet 580*ff61f079SJonathan Corbet Set this field to the offset (from the beginning of the real-mode 581*ff61f079SJonathan Corbet code) of the end of the setup stack/heap, minus 0x0200. 582*ff61f079SJonathan Corbet 583*ff61f079SJonathan Corbet============ ================ 584*ff61f079SJonathan CorbetField name: ext_loader_ver 585*ff61f079SJonathan CorbetType: write (optional) 586*ff61f079SJonathan CorbetOffset/size: 0x226/1 587*ff61f079SJonathan CorbetProtocol: 2.02+ 588*ff61f079SJonathan Corbet============ ================ 589*ff61f079SJonathan Corbet 590*ff61f079SJonathan Corbet This field is used as an extension of the version number in the 591*ff61f079SJonathan Corbet type_of_loader field. The total version number is considered to be 592*ff61f079SJonathan Corbet (type_of_loader & 0x0f) + (ext_loader_ver << 4). 593*ff61f079SJonathan Corbet 594*ff61f079SJonathan Corbet The use of this field is boot loader specific. If not written, it 595*ff61f079SJonathan Corbet is zero. 596*ff61f079SJonathan Corbet 597*ff61f079SJonathan Corbet Kernels prior to 2.6.31 did not recognize this field, but it is safe 598*ff61f079SJonathan Corbet to write for protocol version 2.02 or higher. 599*ff61f079SJonathan Corbet 600*ff61f079SJonathan Corbet============ ===================================================== 601*ff61f079SJonathan CorbetField name: ext_loader_type 602*ff61f079SJonathan CorbetType: write (obligatory if (type_of_loader & 0xf0) == 0xe0) 603*ff61f079SJonathan CorbetOffset/size: 0x227/1 604*ff61f079SJonathan CorbetProtocol: 2.02+ 605*ff61f079SJonathan Corbet============ ===================================================== 606*ff61f079SJonathan Corbet 607*ff61f079SJonathan Corbet This field is used as an extension of the type number in 608*ff61f079SJonathan Corbet type_of_loader field. If the type in type_of_loader is 0xE, then 609*ff61f079SJonathan Corbet the actual type is (ext_loader_type + 0x10). 610*ff61f079SJonathan Corbet 611*ff61f079SJonathan Corbet This field is ignored if the type in type_of_loader is not 0xE. 612*ff61f079SJonathan Corbet 613*ff61f079SJonathan Corbet Kernels prior to 2.6.31 did not recognize this field, but it is safe 614*ff61f079SJonathan Corbet to write for protocol version 2.02 or higher. 615*ff61f079SJonathan Corbet 616*ff61f079SJonathan Corbet============ ================== 617*ff61f079SJonathan CorbetField name: cmd_line_ptr 618*ff61f079SJonathan CorbetType: write (obligatory) 619*ff61f079SJonathan CorbetOffset/size: 0x228/4 620*ff61f079SJonathan CorbetProtocol: 2.02+ 621*ff61f079SJonathan Corbet============ ================== 622*ff61f079SJonathan Corbet 623*ff61f079SJonathan Corbet Set this field to the linear address of the kernel command line. 624*ff61f079SJonathan Corbet The kernel command line can be located anywhere between the end of 625*ff61f079SJonathan Corbet the setup heap and 0xA0000; it does not have to be located in the 626*ff61f079SJonathan Corbet same 64K segment as the real-mode code itself. 627*ff61f079SJonathan Corbet 628*ff61f079SJonathan Corbet Fill in this field even if your boot loader does not support a 629*ff61f079SJonathan Corbet command line, in which case you can point this to an empty string 630*ff61f079SJonathan Corbet (or better yet, to the string "auto".) If this field is left at 631*ff61f079SJonathan Corbet zero, the kernel will assume that your boot loader does not support 632*ff61f079SJonathan Corbet the 2.02+ protocol. 633*ff61f079SJonathan Corbet 634*ff61f079SJonathan Corbet============ =============== 635*ff61f079SJonathan CorbetField name: initrd_addr_max 636*ff61f079SJonathan CorbetType: read 637*ff61f079SJonathan CorbetOffset/size: 0x22c/4 638*ff61f079SJonathan CorbetProtocol: 2.03+ 639*ff61f079SJonathan Corbet============ =============== 640*ff61f079SJonathan Corbet 641*ff61f079SJonathan Corbet The maximum address that may be occupied by the initial 642*ff61f079SJonathan Corbet ramdisk/ramfs contents. For boot protocols 2.02 or earlier, this 643*ff61f079SJonathan Corbet field is not present, and the maximum address is 0x37FFFFFF. (This 644*ff61f079SJonathan Corbet address is defined as the address of the highest safe byte, so if 645*ff61f079SJonathan Corbet your ramdisk is exactly 131072 bytes long and this field is 646*ff61f079SJonathan Corbet 0x37FFFFFF, you can start your ramdisk at 0x37FE0000.) 647*ff61f079SJonathan Corbet 648*ff61f079SJonathan Corbet============ ============================ 649*ff61f079SJonathan CorbetField name: kernel_alignment 650*ff61f079SJonathan CorbetType: read/modify (reloc) 651*ff61f079SJonathan CorbetOffset/size: 0x230/4 652*ff61f079SJonathan CorbetProtocol: 2.05+ (read), 2.10+ (modify) 653*ff61f079SJonathan Corbet============ ============================ 654*ff61f079SJonathan Corbet 655*ff61f079SJonathan Corbet Alignment unit required by the kernel (if relocatable_kernel is 656*ff61f079SJonathan Corbet true.) A relocatable kernel that is loaded at an alignment 657*ff61f079SJonathan Corbet incompatible with the value in this field will be realigned during 658*ff61f079SJonathan Corbet kernel initialization. 659*ff61f079SJonathan Corbet 660*ff61f079SJonathan Corbet Starting with protocol version 2.10, this reflects the kernel 661*ff61f079SJonathan Corbet alignment preferred for optimal performance; it is possible for the 662*ff61f079SJonathan Corbet loader to modify this field to permit a lesser alignment. See the 663*ff61f079SJonathan Corbet min_alignment and pref_address field below. 664*ff61f079SJonathan Corbet 665*ff61f079SJonathan Corbet============ ================== 666*ff61f079SJonathan CorbetField name: relocatable_kernel 667*ff61f079SJonathan CorbetType: read (reloc) 668*ff61f079SJonathan CorbetOffset/size: 0x234/1 669*ff61f079SJonathan CorbetProtocol: 2.05+ 670*ff61f079SJonathan Corbet============ ================== 671*ff61f079SJonathan Corbet 672*ff61f079SJonathan Corbet If this field is nonzero, the protected-mode part of the kernel can 673*ff61f079SJonathan Corbet be loaded at any address that satisfies the kernel_alignment field. 674*ff61f079SJonathan Corbet After loading, the boot loader must set the code32_start field to 675*ff61f079SJonathan Corbet point to the loaded code, or to a boot loader hook. 676*ff61f079SJonathan Corbet 677*ff61f079SJonathan Corbet============ ============= 678*ff61f079SJonathan CorbetField name: min_alignment 679*ff61f079SJonathan CorbetType: read (reloc) 680*ff61f079SJonathan CorbetOffset/size: 0x235/1 681*ff61f079SJonathan CorbetProtocol: 2.10+ 682*ff61f079SJonathan Corbet============ ============= 683*ff61f079SJonathan Corbet 684*ff61f079SJonathan Corbet This field, if nonzero, indicates as a power of two the minimum 685*ff61f079SJonathan Corbet alignment required, as opposed to preferred, by the kernel to boot. 686*ff61f079SJonathan Corbet If a boot loader makes use of this field, it should update the 687*ff61f079SJonathan Corbet kernel_alignment field with the alignment unit desired; typically:: 688*ff61f079SJonathan Corbet 689*ff61f079SJonathan Corbet kernel_alignment = 1 << min_alignment 690*ff61f079SJonathan Corbet 691*ff61f079SJonathan Corbet There may be a considerable performance cost with an excessively 692*ff61f079SJonathan Corbet misaligned kernel. Therefore, a loader should typically try each 693*ff61f079SJonathan Corbet power-of-two alignment from kernel_alignment down to this alignment. 694*ff61f079SJonathan Corbet 695*ff61f079SJonathan Corbet============ ========== 696*ff61f079SJonathan CorbetField name: xloadflags 697*ff61f079SJonathan CorbetType: read 698*ff61f079SJonathan CorbetOffset/size: 0x236/2 699*ff61f079SJonathan CorbetProtocol: 2.12+ 700*ff61f079SJonathan Corbet============ ========== 701*ff61f079SJonathan Corbet 702*ff61f079SJonathan Corbet This field is a bitmask. 703*ff61f079SJonathan Corbet 704*ff61f079SJonathan Corbet Bit 0 (read): XLF_KERNEL_64 705*ff61f079SJonathan Corbet 706*ff61f079SJonathan Corbet - If 1, this kernel has the legacy 64-bit entry point at 0x200. 707*ff61f079SJonathan Corbet 708*ff61f079SJonathan Corbet Bit 1 (read): XLF_CAN_BE_LOADED_ABOVE_4G 709*ff61f079SJonathan Corbet 710*ff61f079SJonathan Corbet - If 1, kernel/boot_params/cmdline/ramdisk can be above 4G. 711*ff61f079SJonathan Corbet 712*ff61f079SJonathan Corbet Bit 2 (read): XLF_EFI_HANDOVER_32 713*ff61f079SJonathan Corbet 714*ff61f079SJonathan Corbet - If 1, the kernel supports the 32-bit EFI handoff entry point 715*ff61f079SJonathan Corbet given at handover_offset. 716*ff61f079SJonathan Corbet 717*ff61f079SJonathan Corbet Bit 3 (read): XLF_EFI_HANDOVER_64 718*ff61f079SJonathan Corbet 719*ff61f079SJonathan Corbet - If 1, the kernel supports the 64-bit EFI handoff entry point 720*ff61f079SJonathan Corbet given at handover_offset + 0x200. 721*ff61f079SJonathan Corbet 722*ff61f079SJonathan Corbet Bit 4 (read): XLF_EFI_KEXEC 723*ff61f079SJonathan Corbet 724*ff61f079SJonathan Corbet - If 1, the kernel supports kexec EFI boot with EFI runtime support. 725*ff61f079SJonathan Corbet 726*ff61f079SJonathan Corbet 727*ff61f079SJonathan Corbet============ ============ 728*ff61f079SJonathan CorbetField name: cmdline_size 729*ff61f079SJonathan CorbetType: read 730*ff61f079SJonathan CorbetOffset/size: 0x238/4 731*ff61f079SJonathan CorbetProtocol: 2.06+ 732*ff61f079SJonathan Corbet============ ============ 733*ff61f079SJonathan Corbet 734*ff61f079SJonathan Corbet The maximum size of the command line without the terminating 735*ff61f079SJonathan Corbet zero. This means that the command line can contain at most 736*ff61f079SJonathan Corbet cmdline_size characters. With protocol version 2.05 and earlier, the 737*ff61f079SJonathan Corbet maximum size was 255. 738*ff61f079SJonathan Corbet 739*ff61f079SJonathan Corbet============ ==================================== 740*ff61f079SJonathan CorbetField name: hardware_subarch 741*ff61f079SJonathan CorbetType: write (optional, defaults to x86/PC) 742*ff61f079SJonathan CorbetOffset/size: 0x23c/4 743*ff61f079SJonathan CorbetProtocol: 2.07+ 744*ff61f079SJonathan Corbet============ ==================================== 745*ff61f079SJonathan Corbet 746*ff61f079SJonathan Corbet In a paravirtualized environment the hardware low level architectural 747*ff61f079SJonathan Corbet pieces such as interrupt handling, page table handling, and 748*ff61f079SJonathan Corbet accessing process control registers needs to be done differently. 749*ff61f079SJonathan Corbet 750*ff61f079SJonathan Corbet This field allows the bootloader to inform the kernel we are in one 751*ff61f079SJonathan Corbet one of those environments. 752*ff61f079SJonathan Corbet 753*ff61f079SJonathan Corbet ========== ============================== 754*ff61f079SJonathan Corbet 0x00000000 The default x86/PC environment 755*ff61f079SJonathan Corbet 0x00000001 lguest 756*ff61f079SJonathan Corbet 0x00000002 Xen 757*ff61f079SJonathan Corbet 0x00000003 Moorestown MID 758*ff61f079SJonathan Corbet 0x00000004 CE4100 TV Platform 759*ff61f079SJonathan Corbet ========== ============================== 760*ff61f079SJonathan Corbet 761*ff61f079SJonathan Corbet============ ========================= 762*ff61f079SJonathan CorbetField name: hardware_subarch_data 763*ff61f079SJonathan CorbetType: write (subarch-dependent) 764*ff61f079SJonathan CorbetOffset/size: 0x240/8 765*ff61f079SJonathan CorbetProtocol: 2.07+ 766*ff61f079SJonathan Corbet============ ========================= 767*ff61f079SJonathan Corbet 768*ff61f079SJonathan Corbet A pointer to data that is specific to hardware subarch 769*ff61f079SJonathan Corbet This field is currently unused for the default x86/PC environment, 770*ff61f079SJonathan Corbet do not modify. 771*ff61f079SJonathan Corbet 772*ff61f079SJonathan Corbet============ ============== 773*ff61f079SJonathan CorbetField name: payload_offset 774*ff61f079SJonathan CorbetType: read 775*ff61f079SJonathan CorbetOffset/size: 0x248/4 776*ff61f079SJonathan CorbetProtocol: 2.08+ 777*ff61f079SJonathan Corbet============ ============== 778*ff61f079SJonathan Corbet 779*ff61f079SJonathan Corbet If non-zero then this field contains the offset from the beginning 780*ff61f079SJonathan Corbet of the protected-mode code to the payload. 781*ff61f079SJonathan Corbet 782*ff61f079SJonathan Corbet The payload may be compressed. The format of both the compressed and 783*ff61f079SJonathan Corbet uncompressed data should be determined using the standard magic 784*ff61f079SJonathan Corbet numbers. The currently supported compression formats are gzip 785*ff61f079SJonathan Corbet (magic numbers 1F 8B or 1F 9E), bzip2 (magic number 42 5A), LZMA 786*ff61f079SJonathan Corbet (magic number 5D 00), XZ (magic number FD 37), LZ4 (magic number 787*ff61f079SJonathan Corbet 02 21) and ZSTD (magic number 28 B5). The uncompressed payload is 788*ff61f079SJonathan Corbet currently always ELF (magic number 7F 45 4C 46). 789*ff61f079SJonathan Corbet 790*ff61f079SJonathan Corbet============ ============== 791*ff61f079SJonathan CorbetField name: payload_length 792*ff61f079SJonathan CorbetType: read 793*ff61f079SJonathan CorbetOffset/size: 0x24c/4 794*ff61f079SJonathan CorbetProtocol: 2.08+ 795*ff61f079SJonathan Corbet============ ============== 796*ff61f079SJonathan Corbet 797*ff61f079SJonathan Corbet The length of the payload. 798*ff61f079SJonathan Corbet 799*ff61f079SJonathan Corbet============ =============== 800*ff61f079SJonathan CorbetField name: setup_data 801*ff61f079SJonathan CorbetType: write (special) 802*ff61f079SJonathan CorbetOffset/size: 0x250/8 803*ff61f079SJonathan CorbetProtocol: 2.09+ 804*ff61f079SJonathan Corbet============ =============== 805*ff61f079SJonathan Corbet 806*ff61f079SJonathan Corbet The 64-bit physical pointer to NULL terminated single linked list of 807*ff61f079SJonathan Corbet struct setup_data. This is used to define a more extensible boot 808*ff61f079SJonathan Corbet parameters passing mechanism. The definition of struct setup_data is 809*ff61f079SJonathan Corbet as follow:: 810*ff61f079SJonathan Corbet 811*ff61f079SJonathan Corbet struct setup_data { 812*ff61f079SJonathan Corbet u64 next; 813*ff61f079SJonathan Corbet u32 type; 814*ff61f079SJonathan Corbet u32 len; 815*ff61f079SJonathan Corbet u8 data[0]; 816*ff61f079SJonathan Corbet }; 817*ff61f079SJonathan Corbet 818*ff61f079SJonathan Corbet Where, the next is a 64-bit physical pointer to the next node of 819*ff61f079SJonathan Corbet linked list, the next field of the last node is 0; the type is used 820*ff61f079SJonathan Corbet to identify the contents of data; the len is the length of data 821*ff61f079SJonathan Corbet field; the data holds the real payload. 822*ff61f079SJonathan Corbet 823*ff61f079SJonathan Corbet This list may be modified at a number of points during the bootup 824*ff61f079SJonathan Corbet process. Therefore, when modifying this list one should always make 825*ff61f079SJonathan Corbet sure to consider the case where the linked list already contains 826*ff61f079SJonathan Corbet entries. 827*ff61f079SJonathan Corbet 828*ff61f079SJonathan Corbet The setup_data is a bit awkward to use for extremely large data objects, 829*ff61f079SJonathan Corbet both because the setup_data header has to be adjacent to the data object 830*ff61f079SJonathan Corbet and because it has a 32-bit length field. However, it is important that 831*ff61f079SJonathan Corbet intermediate stages of the boot process have a way to identify which 832*ff61f079SJonathan Corbet chunks of memory are occupied by kernel data. 833*ff61f079SJonathan Corbet 834*ff61f079SJonathan Corbet Thus setup_indirect struct and SETUP_INDIRECT type were introduced in 835*ff61f079SJonathan Corbet protocol 2.15:: 836*ff61f079SJonathan Corbet 837*ff61f079SJonathan Corbet struct setup_indirect { 838*ff61f079SJonathan Corbet __u32 type; 839*ff61f079SJonathan Corbet __u32 reserved; /* Reserved, must be set to zero. */ 840*ff61f079SJonathan Corbet __u64 len; 841*ff61f079SJonathan Corbet __u64 addr; 842*ff61f079SJonathan Corbet }; 843*ff61f079SJonathan Corbet 844*ff61f079SJonathan Corbet The type member is a SETUP_INDIRECT | SETUP_* type. However, it cannot be 845*ff61f079SJonathan Corbet SETUP_INDIRECT itself since making the setup_indirect a tree structure 846*ff61f079SJonathan Corbet could require a lot of stack space in something that needs to parse it 847*ff61f079SJonathan Corbet and stack space can be limited in boot contexts. 848*ff61f079SJonathan Corbet 849*ff61f079SJonathan Corbet Let's give an example how to point to SETUP_E820_EXT data using setup_indirect. 850*ff61f079SJonathan Corbet In this case setup_data and setup_indirect will look like this:: 851*ff61f079SJonathan Corbet 852*ff61f079SJonathan Corbet struct setup_data { 853*ff61f079SJonathan Corbet __u64 next = 0 or <addr_of_next_setup_data_struct>; 854*ff61f079SJonathan Corbet __u32 type = SETUP_INDIRECT; 855*ff61f079SJonathan Corbet __u32 len = sizeof(setup_indirect); 856*ff61f079SJonathan Corbet __u8 data[sizeof(setup_indirect)] = struct setup_indirect { 857*ff61f079SJonathan Corbet __u32 type = SETUP_INDIRECT | SETUP_E820_EXT; 858*ff61f079SJonathan Corbet __u32 reserved = 0; 859*ff61f079SJonathan Corbet __u64 len = <len_of_SETUP_E820_EXT_data>; 860*ff61f079SJonathan Corbet __u64 addr = <addr_of_SETUP_E820_EXT_data>; 861*ff61f079SJonathan Corbet } 862*ff61f079SJonathan Corbet } 863*ff61f079SJonathan Corbet 864*ff61f079SJonathan Corbet.. note:: 865*ff61f079SJonathan Corbet SETUP_INDIRECT | SETUP_NONE objects cannot be properly distinguished 866*ff61f079SJonathan Corbet from SETUP_INDIRECT itself. So, this kind of objects cannot be provided 867*ff61f079SJonathan Corbet by the bootloaders. 868*ff61f079SJonathan Corbet 869*ff61f079SJonathan Corbet============ ============ 870*ff61f079SJonathan CorbetField name: pref_address 871*ff61f079SJonathan CorbetType: read (reloc) 872*ff61f079SJonathan CorbetOffset/size: 0x258/8 873*ff61f079SJonathan CorbetProtocol: 2.10+ 874*ff61f079SJonathan Corbet============ ============ 875*ff61f079SJonathan Corbet 876*ff61f079SJonathan Corbet This field, if nonzero, represents a preferred load address for the 877*ff61f079SJonathan Corbet kernel. A relocating bootloader should attempt to load at this 878*ff61f079SJonathan Corbet address if possible. 879*ff61f079SJonathan Corbet 880*ff61f079SJonathan Corbet A non-relocatable kernel will unconditionally move itself and to run 881*ff61f079SJonathan Corbet at this address. 882*ff61f079SJonathan Corbet 883*ff61f079SJonathan Corbet============ ======= 884*ff61f079SJonathan CorbetField name: init_size 885*ff61f079SJonathan CorbetType: read 886*ff61f079SJonathan CorbetOffset/size: 0x260/4 887*ff61f079SJonathan Corbet============ ======= 888*ff61f079SJonathan Corbet 889*ff61f079SJonathan Corbet This field indicates the amount of linear contiguous memory starting 890*ff61f079SJonathan Corbet at the kernel runtime start address that the kernel needs before it 891*ff61f079SJonathan Corbet is capable of examining its memory map. This is not the same thing 892*ff61f079SJonathan Corbet as the total amount of memory the kernel needs to boot, but it can 893*ff61f079SJonathan Corbet be used by a relocating boot loader to help select a safe load 894*ff61f079SJonathan Corbet address for the kernel. 895*ff61f079SJonathan Corbet 896*ff61f079SJonathan Corbet The kernel runtime start address is determined by the following algorithm:: 897*ff61f079SJonathan Corbet 898*ff61f079SJonathan Corbet if (relocatable_kernel) 899*ff61f079SJonathan Corbet runtime_start = align_up(load_address, kernel_alignment) 900*ff61f079SJonathan Corbet else 901*ff61f079SJonathan Corbet runtime_start = pref_address 902*ff61f079SJonathan Corbet 903*ff61f079SJonathan Corbet============ =============== 904*ff61f079SJonathan CorbetField name: handover_offset 905*ff61f079SJonathan CorbetType: read 906*ff61f079SJonathan CorbetOffset/size: 0x264/4 907*ff61f079SJonathan Corbet============ =============== 908*ff61f079SJonathan Corbet 909*ff61f079SJonathan Corbet This field is the offset from the beginning of the kernel image to 910*ff61f079SJonathan Corbet the EFI handover protocol entry point. Boot loaders using the EFI 911*ff61f079SJonathan Corbet handover protocol to boot the kernel should jump to this offset. 912*ff61f079SJonathan Corbet 913*ff61f079SJonathan Corbet See EFI HANDOVER PROTOCOL below for more details. 914*ff61f079SJonathan Corbet 915*ff61f079SJonathan Corbet============ ================== 916*ff61f079SJonathan CorbetField name: kernel_info_offset 917*ff61f079SJonathan CorbetType: read 918*ff61f079SJonathan CorbetOffset/size: 0x268/4 919*ff61f079SJonathan CorbetProtocol: 2.15+ 920*ff61f079SJonathan Corbet============ ================== 921*ff61f079SJonathan Corbet 922*ff61f079SJonathan Corbet This field is the offset from the beginning of the kernel image to the 923*ff61f079SJonathan Corbet kernel_info. The kernel_info structure is embedded in the Linux image 924*ff61f079SJonathan Corbet in the uncompressed protected mode region. 925*ff61f079SJonathan Corbet 926*ff61f079SJonathan Corbet 927*ff61f079SJonathan CorbetThe kernel_info 928*ff61f079SJonathan Corbet=============== 929*ff61f079SJonathan Corbet 930*ff61f079SJonathan CorbetThe relationships between the headers are analogous to the various data 931*ff61f079SJonathan Corbetsections: 932*ff61f079SJonathan Corbet 933*ff61f079SJonathan Corbet setup_header = .data 934*ff61f079SJonathan Corbet boot_params/setup_data = .bss 935*ff61f079SJonathan Corbet 936*ff61f079SJonathan CorbetWhat is missing from the above list? That's right: 937*ff61f079SJonathan Corbet 938*ff61f079SJonathan Corbet kernel_info = .rodata 939*ff61f079SJonathan Corbet 940*ff61f079SJonathan CorbetWe have been (ab)using .data for things that could go into .rodata or .bss for 941*ff61f079SJonathan Corbeta long time, for lack of alternatives and -- especially early on -- inertia. 942*ff61f079SJonathan CorbetAlso, the BIOS stub is responsible for creating boot_params, so it isn't 943*ff61f079SJonathan Corbetavailable to a BIOS-based loader (setup_data is, though). 944*ff61f079SJonathan Corbet 945*ff61f079SJonathan Corbetsetup_header is permanently limited to 144 bytes due to the reach of the 946*ff61f079SJonathan Corbet2-byte jump field, which doubles as a length field for the structure, combined 947*ff61f079SJonathan Corbetwith the size of the "hole" in struct boot_params that a protected-mode loader 948*ff61f079SJonathan Corbetor the BIOS stub has to copy it into. It is currently 119 bytes long, which 949*ff61f079SJonathan Corbetleaves us with 25 very precious bytes. This isn't something that can be fixed 950*ff61f079SJonathan Corbetwithout revising the boot protocol entirely, breaking backwards compatibility. 951*ff61f079SJonathan Corbet 952*ff61f079SJonathan Corbetboot_params proper is limited to 4096 bytes, but can be arbitrarily extended 953*ff61f079SJonathan Corbetby adding setup_data entries. It cannot be used to communicate properties of 954*ff61f079SJonathan Corbetthe kernel image, because it is .bss and has no image-provided content. 955*ff61f079SJonathan Corbet 956*ff61f079SJonathan Corbetkernel_info solves this by providing an extensible place for information about 957*ff61f079SJonathan Corbetthe kernel image. It is readonly, because the kernel cannot rely on a 958*ff61f079SJonathan Corbetbootloader copying its contents anywhere, but that is OK; if it becomes 959*ff61f079SJonathan Corbetnecessary it can still contain data items that an enabled bootloader would be 960*ff61f079SJonathan Corbetexpected to copy into a setup_data chunk. 961*ff61f079SJonathan Corbet 962*ff61f079SJonathan CorbetAll kernel_info data should be part of this structure. Fixed size data have to 963*ff61f079SJonathan Corbetbe put before kernel_info_var_len_data label. Variable size data have to be put 964*ff61f079SJonathan Corbetafter kernel_info_var_len_data label. Each chunk of variable size data has to 965*ff61f079SJonathan Corbetbe prefixed with header/magic and its size, e.g.:: 966*ff61f079SJonathan Corbet 967*ff61f079SJonathan Corbet kernel_info: 968*ff61f079SJonathan Corbet .ascii "LToP" /* Header, Linux top (structure). */ 969*ff61f079SJonathan Corbet .long kernel_info_var_len_data - kernel_info 970*ff61f079SJonathan Corbet .long kernel_info_end - kernel_info 971*ff61f079SJonathan Corbet .long 0x01234567 /* Some fixed size data for the bootloaders. */ 972*ff61f079SJonathan Corbet kernel_info_var_len_data: 973*ff61f079SJonathan Corbet example_struct: /* Some variable size data for the bootloaders. */ 974*ff61f079SJonathan Corbet .ascii "0123" /* Header/Magic. */ 975*ff61f079SJonathan Corbet .long example_struct_end - example_struct 976*ff61f079SJonathan Corbet .ascii "Struct" 977*ff61f079SJonathan Corbet .long 0x89012345 978*ff61f079SJonathan Corbet example_struct_end: 979*ff61f079SJonathan Corbet example_strings: /* Some variable size data for the bootloaders. */ 980*ff61f079SJonathan Corbet .ascii "ABCD" /* Header/Magic. */ 981*ff61f079SJonathan Corbet .long example_strings_end - example_strings 982*ff61f079SJonathan Corbet .asciz "String_0" 983*ff61f079SJonathan Corbet .asciz "String_1" 984*ff61f079SJonathan Corbet example_strings_end: 985*ff61f079SJonathan Corbet kernel_info_end: 986*ff61f079SJonathan Corbet 987*ff61f079SJonathan CorbetThis way the kernel_info is self-contained blob. 988*ff61f079SJonathan Corbet 989*ff61f079SJonathan Corbet.. note:: 990*ff61f079SJonathan Corbet Each variable size data header/magic can be any 4-character string, 991*ff61f079SJonathan Corbet without \0 at the end of the string, which does not collide with 992*ff61f079SJonathan Corbet existing variable length data headers/magics. 993*ff61f079SJonathan Corbet 994*ff61f079SJonathan Corbet 995*ff61f079SJonathan CorbetDetails of the kernel_info Fields 996*ff61f079SJonathan Corbet================================= 997*ff61f079SJonathan Corbet 998*ff61f079SJonathan Corbet============ ======== 999*ff61f079SJonathan CorbetField name: header 1000*ff61f079SJonathan CorbetOffset/size: 0x0000/4 1001*ff61f079SJonathan Corbet============ ======== 1002*ff61f079SJonathan Corbet 1003*ff61f079SJonathan Corbet Contains the magic number "LToP" (0x506f544c). 1004*ff61f079SJonathan Corbet 1005*ff61f079SJonathan Corbet============ ======== 1006*ff61f079SJonathan CorbetField name: size 1007*ff61f079SJonathan CorbetOffset/size: 0x0004/4 1008*ff61f079SJonathan Corbet============ ======== 1009*ff61f079SJonathan Corbet 1010*ff61f079SJonathan Corbet This field contains the size of the kernel_info including kernel_info.header. 1011*ff61f079SJonathan Corbet It does not count kernel_info.kernel_info_var_len_data size. This field should be 1012*ff61f079SJonathan Corbet used by the bootloaders to detect supported fixed size fields in the kernel_info 1013*ff61f079SJonathan Corbet and beginning of kernel_info.kernel_info_var_len_data. 1014*ff61f079SJonathan Corbet 1015*ff61f079SJonathan Corbet============ ======== 1016*ff61f079SJonathan CorbetField name: size_total 1017*ff61f079SJonathan CorbetOffset/size: 0x0008/4 1018*ff61f079SJonathan Corbet============ ======== 1019*ff61f079SJonathan Corbet 1020*ff61f079SJonathan Corbet This field contains the size of the kernel_info including kernel_info.header 1021*ff61f079SJonathan Corbet and kernel_info.kernel_info_var_len_data. 1022*ff61f079SJonathan Corbet 1023*ff61f079SJonathan Corbet============ ============== 1024*ff61f079SJonathan CorbetField name: setup_type_max 1025*ff61f079SJonathan CorbetOffset/size: 0x000c/4 1026*ff61f079SJonathan Corbet============ ============== 1027*ff61f079SJonathan Corbet 1028*ff61f079SJonathan Corbet This field contains maximal allowed type for setup_data and setup_indirect structs. 1029*ff61f079SJonathan Corbet 1030*ff61f079SJonathan Corbet 1031*ff61f079SJonathan CorbetThe Image Checksum 1032*ff61f079SJonathan Corbet================== 1033*ff61f079SJonathan Corbet 1034*ff61f079SJonathan CorbetFrom boot protocol version 2.08 onwards the CRC-32 is calculated over 1035*ff61f079SJonathan Corbetthe entire file using the characteristic polynomial 0x04C11DB7 and an 1036*ff61f079SJonathan Corbetinitial remainder of 0xffffffff. The checksum is appended to the 1037*ff61f079SJonathan Corbetfile; therefore the CRC of the file up to the limit specified in the 1038*ff61f079SJonathan Corbetsyssize field of the header is always 0. 1039*ff61f079SJonathan Corbet 1040*ff61f079SJonathan Corbet 1041*ff61f079SJonathan CorbetThe Kernel Command Line 1042*ff61f079SJonathan Corbet======================= 1043*ff61f079SJonathan Corbet 1044*ff61f079SJonathan CorbetThe kernel command line has become an important way for the boot 1045*ff61f079SJonathan Corbetloader to communicate with the kernel. Some of its options are also 1046*ff61f079SJonathan Corbetrelevant to the boot loader itself, see "special command line options" 1047*ff61f079SJonathan Corbetbelow. 1048*ff61f079SJonathan Corbet 1049*ff61f079SJonathan CorbetThe kernel command line is a null-terminated string. The maximum 1050*ff61f079SJonathan Corbetlength can be retrieved from the field cmdline_size. Before protocol 1051*ff61f079SJonathan Corbetversion 2.06, the maximum was 255 characters. A string that is too 1052*ff61f079SJonathan Corbetlong will be automatically truncated by the kernel. 1053*ff61f079SJonathan Corbet 1054*ff61f079SJonathan CorbetIf the boot protocol version is 2.02 or later, the address of the 1055*ff61f079SJonathan Corbetkernel command line is given by the header field cmd_line_ptr (see 1056*ff61f079SJonathan Corbetabove.) This address can be anywhere between the end of the setup 1057*ff61f079SJonathan Corbetheap and 0xA0000. 1058*ff61f079SJonathan Corbet 1059*ff61f079SJonathan CorbetIf the protocol version is *not* 2.02 or higher, the kernel 1060*ff61f079SJonathan Corbetcommand line is entered using the following protocol: 1061*ff61f079SJonathan Corbet 1062*ff61f079SJonathan Corbet - At offset 0x0020 (word), "cmd_line_magic", enter the magic 1063*ff61f079SJonathan Corbet number 0xA33F. 1064*ff61f079SJonathan Corbet 1065*ff61f079SJonathan Corbet - At offset 0x0022 (word), "cmd_line_offset", enter the offset 1066*ff61f079SJonathan Corbet of the kernel command line (relative to the start of the 1067*ff61f079SJonathan Corbet real-mode kernel). 1068*ff61f079SJonathan Corbet 1069*ff61f079SJonathan Corbet - The kernel command line *must* be within the memory region 1070*ff61f079SJonathan Corbet covered by setup_move_size, so you may need to adjust this 1071*ff61f079SJonathan Corbet field. 1072*ff61f079SJonathan Corbet 1073*ff61f079SJonathan Corbet 1074*ff61f079SJonathan CorbetMemory Layout of The Real-Mode Code 1075*ff61f079SJonathan Corbet=================================== 1076*ff61f079SJonathan Corbet 1077*ff61f079SJonathan CorbetThe real-mode code requires a stack/heap to be set up, as well as 1078*ff61f079SJonathan Corbetmemory allocated for the kernel command line. This needs to be done 1079*ff61f079SJonathan Corbetin the real-mode accessible memory in bottom megabyte. 1080*ff61f079SJonathan Corbet 1081*ff61f079SJonathan CorbetIt should be noted that modern machines often have a sizable Extended 1082*ff61f079SJonathan CorbetBIOS Data Area (EBDA). As a result, it is advisable to use as little 1083*ff61f079SJonathan Corbetof the low megabyte as possible. 1084*ff61f079SJonathan Corbet 1085*ff61f079SJonathan CorbetUnfortunately, under the following circumstances the 0x90000 memory 1086*ff61f079SJonathan Corbetsegment has to be used: 1087*ff61f079SJonathan Corbet 1088*ff61f079SJonathan Corbet - When loading a zImage kernel ((loadflags & 0x01) == 0). 1089*ff61f079SJonathan Corbet - When loading a 2.01 or earlier boot protocol kernel. 1090*ff61f079SJonathan Corbet 1091*ff61f079SJonathan Corbet.. note:: 1092*ff61f079SJonathan Corbet For the 2.00 and 2.01 boot protocols, the real-mode code 1093*ff61f079SJonathan Corbet can be loaded at another address, but it is internally 1094*ff61f079SJonathan Corbet relocated to 0x90000. For the "old" protocol, the 1095*ff61f079SJonathan Corbet real-mode code must be loaded at 0x90000. 1096*ff61f079SJonathan Corbet 1097*ff61f079SJonathan CorbetWhen loading at 0x90000, avoid using memory above 0x9a000. 1098*ff61f079SJonathan Corbet 1099*ff61f079SJonathan CorbetFor boot protocol 2.02 or higher, the command line does not have to be 1100*ff61f079SJonathan Corbetlocated in the same 64K segment as the real-mode setup code; it is 1101*ff61f079SJonathan Corbetthus permitted to give the stack/heap the full 64K segment and locate 1102*ff61f079SJonathan Corbetthe command line above it. 1103*ff61f079SJonathan Corbet 1104*ff61f079SJonathan CorbetThe kernel command line should not be located below the real-mode 1105*ff61f079SJonathan Corbetcode, nor should it be located in high memory. 1106*ff61f079SJonathan Corbet 1107*ff61f079SJonathan Corbet 1108*ff61f079SJonathan CorbetSample Boot Configuartion 1109*ff61f079SJonathan Corbet========================= 1110*ff61f079SJonathan Corbet 1111*ff61f079SJonathan CorbetAs a sample configuration, assume the following layout of the real 1112*ff61f079SJonathan Corbetmode segment. 1113*ff61f079SJonathan Corbet 1114*ff61f079SJonathan Corbet When loading below 0x90000, use the entire segment: 1115*ff61f079SJonathan Corbet 1116*ff61f079SJonathan Corbet ============= =================== 1117*ff61f079SJonathan Corbet 0x0000-0x7fff Real mode kernel 1118*ff61f079SJonathan Corbet 0x8000-0xdfff Stack and heap 1119*ff61f079SJonathan Corbet 0xe000-0xffff Kernel command line 1120*ff61f079SJonathan Corbet ============= =================== 1121*ff61f079SJonathan Corbet 1122*ff61f079SJonathan Corbet When loading at 0x90000 OR the protocol version is 2.01 or earlier: 1123*ff61f079SJonathan Corbet 1124*ff61f079SJonathan Corbet ============= =================== 1125*ff61f079SJonathan Corbet 0x0000-0x7fff Real mode kernel 1126*ff61f079SJonathan Corbet 0x8000-0x97ff Stack and heap 1127*ff61f079SJonathan Corbet 0x9800-0x9fff Kernel command line 1128*ff61f079SJonathan Corbet ============= =================== 1129*ff61f079SJonathan Corbet 1130*ff61f079SJonathan CorbetSuch a boot loader should enter the following fields in the header:: 1131*ff61f079SJonathan Corbet 1132*ff61f079SJonathan Corbet unsigned long base_ptr; /* base address for real-mode segment */ 1133*ff61f079SJonathan Corbet 1134*ff61f079SJonathan Corbet if ( setup_sects == 0 ) { 1135*ff61f079SJonathan Corbet setup_sects = 4; 1136*ff61f079SJonathan Corbet } 1137*ff61f079SJonathan Corbet 1138*ff61f079SJonathan Corbet if ( protocol >= 0x0200 ) { 1139*ff61f079SJonathan Corbet type_of_loader = <type code>; 1140*ff61f079SJonathan Corbet if ( loading_initrd ) { 1141*ff61f079SJonathan Corbet ramdisk_image = <initrd_address>; 1142*ff61f079SJonathan Corbet ramdisk_size = <initrd_size>; 1143*ff61f079SJonathan Corbet } 1144*ff61f079SJonathan Corbet 1145*ff61f079SJonathan Corbet if ( protocol >= 0x0202 && loadflags & 0x01 ) 1146*ff61f079SJonathan Corbet heap_end = 0xe000; 1147*ff61f079SJonathan Corbet else 1148*ff61f079SJonathan Corbet heap_end = 0x9800; 1149*ff61f079SJonathan Corbet 1150*ff61f079SJonathan Corbet if ( protocol >= 0x0201 ) { 1151*ff61f079SJonathan Corbet heap_end_ptr = heap_end - 0x200; 1152*ff61f079SJonathan Corbet loadflags |= 0x80; /* CAN_USE_HEAP */ 1153*ff61f079SJonathan Corbet } 1154*ff61f079SJonathan Corbet 1155*ff61f079SJonathan Corbet if ( protocol >= 0x0202 ) { 1156*ff61f079SJonathan Corbet cmd_line_ptr = base_ptr + heap_end; 1157*ff61f079SJonathan Corbet strcpy(cmd_line_ptr, cmdline); 1158*ff61f079SJonathan Corbet } else { 1159*ff61f079SJonathan Corbet cmd_line_magic = 0xA33F; 1160*ff61f079SJonathan Corbet cmd_line_offset = heap_end; 1161*ff61f079SJonathan Corbet setup_move_size = heap_end + strlen(cmdline)+1; 1162*ff61f079SJonathan Corbet strcpy(base_ptr+cmd_line_offset, cmdline); 1163*ff61f079SJonathan Corbet } 1164*ff61f079SJonathan Corbet } else { 1165*ff61f079SJonathan Corbet /* Very old kernel */ 1166*ff61f079SJonathan Corbet 1167*ff61f079SJonathan Corbet heap_end = 0x9800; 1168*ff61f079SJonathan Corbet 1169*ff61f079SJonathan Corbet cmd_line_magic = 0xA33F; 1170*ff61f079SJonathan Corbet cmd_line_offset = heap_end; 1171*ff61f079SJonathan Corbet 1172*ff61f079SJonathan Corbet /* A very old kernel MUST have its real-mode code 1173*ff61f079SJonathan Corbet loaded at 0x90000 */ 1174*ff61f079SJonathan Corbet 1175*ff61f079SJonathan Corbet if ( base_ptr != 0x90000 ) { 1176*ff61f079SJonathan Corbet /* Copy the real-mode kernel */ 1177*ff61f079SJonathan Corbet memcpy(0x90000, base_ptr, (setup_sects+1)*512); 1178*ff61f079SJonathan Corbet base_ptr = 0x90000; /* Relocated */ 1179*ff61f079SJonathan Corbet } 1180*ff61f079SJonathan Corbet 1181*ff61f079SJonathan Corbet strcpy(0x90000+cmd_line_offset, cmdline); 1182*ff61f079SJonathan Corbet 1183*ff61f079SJonathan Corbet /* It is recommended to clear memory up to the 32K mark */ 1184*ff61f079SJonathan Corbet memset(0x90000 + (setup_sects+1)*512, 0, 1185*ff61f079SJonathan Corbet (64-(setup_sects+1))*512); 1186*ff61f079SJonathan Corbet } 1187*ff61f079SJonathan Corbet 1188*ff61f079SJonathan Corbet 1189*ff61f079SJonathan CorbetLoading The Rest of The Kernel 1190*ff61f079SJonathan Corbet============================== 1191*ff61f079SJonathan Corbet 1192*ff61f079SJonathan CorbetThe 32-bit (non-real-mode) kernel starts at offset (setup_sects+1)*512 1193*ff61f079SJonathan Corbetin the kernel file (again, if setup_sects == 0 the real value is 4.) 1194*ff61f079SJonathan CorbetIt should be loaded at address 0x10000 for Image/zImage kernels and 1195*ff61f079SJonathan Corbet0x100000 for bzImage kernels. 1196*ff61f079SJonathan Corbet 1197*ff61f079SJonathan CorbetThe kernel is a bzImage kernel if the protocol >= 2.00 and the 0x01 1198*ff61f079SJonathan Corbetbit (LOAD_HIGH) in the loadflags field is set:: 1199*ff61f079SJonathan Corbet 1200*ff61f079SJonathan Corbet is_bzImage = (protocol >= 0x0200) && (loadflags & 0x01); 1201*ff61f079SJonathan Corbet load_address = is_bzImage ? 0x100000 : 0x10000; 1202*ff61f079SJonathan Corbet 1203*ff61f079SJonathan CorbetNote that Image/zImage kernels can be up to 512K in size, and thus use 1204*ff61f079SJonathan Corbetthe entire 0x10000-0x90000 range of memory. This means it is pretty 1205*ff61f079SJonathan Corbetmuch a requirement for these kernels to load the real-mode part at 1206*ff61f079SJonathan Corbet0x90000. bzImage kernels allow much more flexibility. 1207*ff61f079SJonathan Corbet 1208*ff61f079SJonathan CorbetSpecial Command Line Options 1209*ff61f079SJonathan Corbet============================ 1210*ff61f079SJonathan Corbet 1211*ff61f079SJonathan CorbetIf the command line provided by the boot loader is entered by the 1212*ff61f079SJonathan Corbetuser, the user may expect the following command line options to work. 1213*ff61f079SJonathan CorbetThey should normally not be deleted from the kernel command line even 1214*ff61f079SJonathan Corbetthough not all of them are actually meaningful to the kernel. Boot 1215*ff61f079SJonathan Corbetloader authors who need additional command line options for the boot 1216*ff61f079SJonathan Corbetloader itself should get them registered in 1217*ff61f079SJonathan CorbetDocumentation/admin-guide/kernel-parameters.rst to make sure they will not 1218*ff61f079SJonathan Corbetconflict with actual kernel options now or in the future. 1219*ff61f079SJonathan Corbet 1220*ff61f079SJonathan Corbet vga=<mode> 1221*ff61f079SJonathan Corbet <mode> here is either an integer (in C notation, either 1222*ff61f079SJonathan Corbet decimal, octal, or hexadecimal) or one of the strings 1223*ff61f079SJonathan Corbet "normal" (meaning 0xFFFF), "ext" (meaning 0xFFFE) or "ask" 1224*ff61f079SJonathan Corbet (meaning 0xFFFD). This value should be entered into the 1225*ff61f079SJonathan Corbet vid_mode field, as it is used by the kernel before the command 1226*ff61f079SJonathan Corbet line is parsed. 1227*ff61f079SJonathan Corbet 1228*ff61f079SJonathan Corbet mem=<size> 1229*ff61f079SJonathan Corbet <size> is an integer in C notation optionally followed by 1230*ff61f079SJonathan Corbet (case insensitive) K, M, G, T, P or E (meaning << 10, << 20, 1231*ff61f079SJonathan Corbet << 30, << 40, << 50 or << 60). This specifies the end of 1232*ff61f079SJonathan Corbet memory to the kernel. This affects the possible placement of 1233*ff61f079SJonathan Corbet an initrd, since an initrd should be placed near end of 1234*ff61f079SJonathan Corbet memory. Note that this is an option to *both* the kernel and 1235*ff61f079SJonathan Corbet the bootloader! 1236*ff61f079SJonathan Corbet 1237*ff61f079SJonathan Corbet initrd=<file> 1238*ff61f079SJonathan Corbet An initrd should be loaded. The meaning of <file> is 1239*ff61f079SJonathan Corbet obviously bootloader-dependent, and some boot loaders 1240*ff61f079SJonathan Corbet (e.g. LILO) do not have such a command. 1241*ff61f079SJonathan Corbet 1242*ff61f079SJonathan CorbetIn addition, some boot loaders add the following options to the 1243*ff61f079SJonathan Corbetuser-specified command line: 1244*ff61f079SJonathan Corbet 1245*ff61f079SJonathan Corbet BOOT_IMAGE=<file> 1246*ff61f079SJonathan Corbet The boot image which was loaded. Again, the meaning of <file> 1247*ff61f079SJonathan Corbet is obviously bootloader-dependent. 1248*ff61f079SJonathan Corbet 1249*ff61f079SJonathan Corbet auto 1250*ff61f079SJonathan Corbet The kernel was booted without explicit user intervention. 1251*ff61f079SJonathan Corbet 1252*ff61f079SJonathan CorbetIf these options are added by the boot loader, it is highly 1253*ff61f079SJonathan Corbetrecommended that they are located *first*, before the user-specified 1254*ff61f079SJonathan Corbetor configuration-specified command line. Otherwise, "init=/bin/sh" 1255*ff61f079SJonathan Corbetgets confused by the "auto" option. 1256*ff61f079SJonathan Corbet 1257*ff61f079SJonathan Corbet 1258*ff61f079SJonathan CorbetRunning the Kernel 1259*ff61f079SJonathan Corbet================== 1260*ff61f079SJonathan Corbet 1261*ff61f079SJonathan CorbetThe kernel is started by jumping to the kernel entry point, which is 1262*ff61f079SJonathan Corbetlocated at *segment* offset 0x20 from the start of the real mode 1263*ff61f079SJonathan Corbetkernel. This means that if you loaded your real-mode kernel code at 1264*ff61f079SJonathan Corbet0x90000, the kernel entry point is 9020:0000. 1265*ff61f079SJonathan Corbet 1266*ff61f079SJonathan CorbetAt entry, ds = es = ss should point to the start of the real-mode 1267*ff61f079SJonathan Corbetkernel code (0x9000 if the code is loaded at 0x90000), sp should be 1268*ff61f079SJonathan Corbetset up properly, normally pointing to the top of the heap, and 1269*ff61f079SJonathan Corbetinterrupts should be disabled. Furthermore, to guard against bugs in 1270*ff61f079SJonathan Corbetthe kernel, it is recommended that the boot loader sets fs = gs = ds = 1271*ff61f079SJonathan Corbetes = ss. 1272*ff61f079SJonathan Corbet 1273*ff61f079SJonathan CorbetIn our example from above, we would do:: 1274*ff61f079SJonathan Corbet 1275*ff61f079SJonathan Corbet /* Note: in the case of the "old" kernel protocol, base_ptr must 1276*ff61f079SJonathan Corbet be == 0x90000 at this point; see the previous sample code */ 1277*ff61f079SJonathan Corbet 1278*ff61f079SJonathan Corbet seg = base_ptr >> 4; 1279*ff61f079SJonathan Corbet 1280*ff61f079SJonathan Corbet cli(); /* Enter with interrupts disabled! */ 1281*ff61f079SJonathan Corbet 1282*ff61f079SJonathan Corbet /* Set up the real-mode kernel stack */ 1283*ff61f079SJonathan Corbet _SS = seg; 1284*ff61f079SJonathan Corbet _SP = heap_end; 1285*ff61f079SJonathan Corbet 1286*ff61f079SJonathan Corbet _DS = _ES = _FS = _GS = seg; 1287*ff61f079SJonathan Corbet jmp_far(seg+0x20, 0); /* Run the kernel */ 1288*ff61f079SJonathan Corbet 1289*ff61f079SJonathan CorbetIf your boot sector accesses a floppy drive, it is recommended to 1290*ff61f079SJonathan Corbetswitch off the floppy motor before running the kernel, since the 1291*ff61f079SJonathan Corbetkernel boot leaves interrupts off and thus the motor will not be 1292*ff61f079SJonathan Corbetswitched off, especially if the loaded kernel has the floppy driver as 1293*ff61f079SJonathan Corbeta demand-loaded module! 1294*ff61f079SJonathan Corbet 1295*ff61f079SJonathan Corbet 1296*ff61f079SJonathan CorbetAdvanced Boot Loader Hooks 1297*ff61f079SJonathan Corbet========================== 1298*ff61f079SJonathan Corbet 1299*ff61f079SJonathan CorbetIf the boot loader runs in a particularly hostile environment (such as 1300*ff61f079SJonathan CorbetLOADLIN, which runs under DOS) it may be impossible to follow the 1301*ff61f079SJonathan Corbetstandard memory location requirements. Such a boot loader may use the 1302*ff61f079SJonathan Corbetfollowing hooks that, if set, are invoked by the kernel at the 1303*ff61f079SJonathan Corbetappropriate time. The use of these hooks should probably be 1304*ff61f079SJonathan Corbetconsidered an absolutely last resort! 1305*ff61f079SJonathan Corbet 1306*ff61f079SJonathan CorbetIMPORTANT: All the hooks are required to preserve %esp, %ebp, %esi and 1307*ff61f079SJonathan Corbet%edi across invocation. 1308*ff61f079SJonathan Corbet 1309*ff61f079SJonathan Corbet realmode_swtch: 1310*ff61f079SJonathan Corbet A 16-bit real mode far subroutine invoked immediately before 1311*ff61f079SJonathan Corbet entering protected mode. The default routine disables NMI, so 1312*ff61f079SJonathan Corbet your routine should probably do so, too. 1313*ff61f079SJonathan Corbet 1314*ff61f079SJonathan Corbet code32_start: 1315*ff61f079SJonathan Corbet A 32-bit flat-mode routine *jumped* to immediately after the 1316*ff61f079SJonathan Corbet transition to protected mode, but before the kernel is 1317*ff61f079SJonathan Corbet uncompressed. No segments, except CS, are guaranteed to be 1318*ff61f079SJonathan Corbet set up (current kernels do, but older ones do not); you should 1319*ff61f079SJonathan Corbet set them up to BOOT_DS (0x18) yourself. 1320*ff61f079SJonathan Corbet 1321*ff61f079SJonathan Corbet After completing your hook, you should jump to the address 1322*ff61f079SJonathan Corbet that was in this field before your boot loader overwrote it 1323*ff61f079SJonathan Corbet (relocated, if appropriate.) 1324*ff61f079SJonathan Corbet 1325*ff61f079SJonathan Corbet 1326*ff61f079SJonathan Corbet32-bit Boot Protocol 1327*ff61f079SJonathan Corbet==================== 1328*ff61f079SJonathan Corbet 1329*ff61f079SJonathan CorbetFor machine with some new BIOS other than legacy BIOS, such as EFI, 1330*ff61f079SJonathan CorbetLinuxBIOS, etc, and kexec, the 16-bit real mode setup code in kernel 1331*ff61f079SJonathan Corbetbased on legacy BIOS can not be used, so a 32-bit boot protocol needs 1332*ff61f079SJonathan Corbetto be defined. 1333*ff61f079SJonathan Corbet 1334*ff61f079SJonathan CorbetIn 32-bit boot protocol, the first step in loading a Linux kernel 1335*ff61f079SJonathan Corbetshould be to setup the boot parameters (struct boot_params, 1336*ff61f079SJonathan Corbettraditionally known as "zero page"). The memory for struct boot_params 1337*ff61f079SJonathan Corbetshould be allocated and initialized to all zero. Then the setup header 1338*ff61f079SJonathan Corbetfrom offset 0x01f1 of kernel image on should be loaded into struct 1339*ff61f079SJonathan Corbetboot_params and examined. The end of setup header can be calculated as 1340*ff61f079SJonathan Corbetfollow:: 1341*ff61f079SJonathan Corbet 1342*ff61f079SJonathan Corbet 0x0202 + byte value at offset 0x0201 1343*ff61f079SJonathan Corbet 1344*ff61f079SJonathan CorbetIn addition to read/modify/write the setup header of the struct 1345*ff61f079SJonathan Corbetboot_params as that of 16-bit boot protocol, the boot loader should 1346*ff61f079SJonathan Corbetalso fill the additional fields of the struct boot_params as 1347*ff61f079SJonathan Corbetdescribed in chapter Documentation/arch/x86/zero-page.rst. 1348*ff61f079SJonathan Corbet 1349*ff61f079SJonathan CorbetAfter setting up the struct boot_params, the boot loader can load the 1350*ff61f079SJonathan Corbet32/64-bit kernel in the same way as that of 16-bit boot protocol. 1351*ff61f079SJonathan Corbet 1352*ff61f079SJonathan CorbetIn 32-bit boot protocol, the kernel is started by jumping to the 1353*ff61f079SJonathan Corbet32-bit kernel entry point, which is the start address of loaded 1354*ff61f079SJonathan Corbet32/64-bit kernel. 1355*ff61f079SJonathan Corbet 1356*ff61f079SJonathan CorbetAt entry, the CPU must be in 32-bit protected mode with paging 1357*ff61f079SJonathan Corbetdisabled; a GDT must be loaded with the descriptors for selectors 1358*ff61f079SJonathan Corbet__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat 1359*ff61f079SJonathan Corbetsegment; __BOOT_CS must have execute/read permission, and __BOOT_DS 1360*ff61f079SJonathan Corbetmust have read/write permission; CS must be __BOOT_CS and DS, ES, SS 1361*ff61f079SJonathan Corbetmust be __BOOT_DS; interrupt must be disabled; %esi must hold the base 1362*ff61f079SJonathan Corbetaddress of the struct boot_params; %ebp, %edi and %ebx must be zero. 1363*ff61f079SJonathan Corbet 1364*ff61f079SJonathan Corbet64-bit Boot Protocol 1365*ff61f079SJonathan Corbet==================== 1366*ff61f079SJonathan Corbet 1367*ff61f079SJonathan CorbetFor machine with 64bit cpus and 64bit kernel, we could use 64bit bootloader 1368*ff61f079SJonathan Corbetand we need a 64-bit boot protocol. 1369*ff61f079SJonathan Corbet 1370*ff61f079SJonathan CorbetIn 64-bit boot protocol, the first step in loading a Linux kernel 1371*ff61f079SJonathan Corbetshould be to setup the boot parameters (struct boot_params, 1372*ff61f079SJonathan Corbettraditionally known as "zero page"). The memory for struct boot_params 1373*ff61f079SJonathan Corbetcould be allocated anywhere (even above 4G) and initialized to all zero. 1374*ff61f079SJonathan CorbetThen, the setup header at offset 0x01f1 of kernel image on should be 1375*ff61f079SJonathan Corbetloaded into struct boot_params and examined. The end of setup header 1376*ff61f079SJonathan Corbetcan be calculated as follows:: 1377*ff61f079SJonathan Corbet 1378*ff61f079SJonathan Corbet 0x0202 + byte value at offset 0x0201 1379*ff61f079SJonathan Corbet 1380*ff61f079SJonathan CorbetIn addition to read/modify/write the setup header of the struct 1381*ff61f079SJonathan Corbetboot_params as that of 16-bit boot protocol, the boot loader should 1382*ff61f079SJonathan Corbetalso fill the additional fields of the struct boot_params as described 1383*ff61f079SJonathan Corbetin chapter Documentation/arch/x86/zero-page.rst. 1384*ff61f079SJonathan Corbet 1385*ff61f079SJonathan CorbetAfter setting up the struct boot_params, the boot loader can load 1386*ff61f079SJonathan Corbet64-bit kernel in the same way as that of 16-bit boot protocol, but 1387*ff61f079SJonathan Corbetkernel could be loaded above 4G. 1388*ff61f079SJonathan Corbet 1389*ff61f079SJonathan CorbetIn 64-bit boot protocol, the kernel is started by jumping to the 1390*ff61f079SJonathan Corbet64-bit kernel entry point, which is the start address of loaded 1391*ff61f079SJonathan Corbet64-bit kernel plus 0x200. 1392*ff61f079SJonathan Corbet 1393*ff61f079SJonathan CorbetAt entry, the CPU must be in 64-bit mode with paging enabled. 1394*ff61f079SJonathan CorbetThe range with setup_header.init_size from start address of loaded 1395*ff61f079SJonathan Corbetkernel and zero page and command line buffer get ident mapping; 1396*ff61f079SJonathan Corbeta GDT must be loaded with the descriptors for selectors 1397*ff61f079SJonathan Corbet__BOOT_CS(0x10) and __BOOT_DS(0x18); both descriptors must be 4G flat 1398*ff61f079SJonathan Corbetsegment; __BOOT_CS must have execute/read permission, and __BOOT_DS 1399*ff61f079SJonathan Corbetmust have read/write permission; CS must be __BOOT_CS and DS, ES, SS 1400*ff61f079SJonathan Corbetmust be __BOOT_DS; interrupt must be disabled; %rsi must hold the base 1401*ff61f079SJonathan Corbetaddress of the struct boot_params. 1402*ff61f079SJonathan Corbet 1403*ff61f079SJonathan CorbetEFI Handover Protocol (deprecated) 1404*ff61f079SJonathan Corbet================================== 1405*ff61f079SJonathan Corbet 1406*ff61f079SJonathan CorbetThis protocol allows boot loaders to defer initialisation to the EFI 1407*ff61f079SJonathan Corbetboot stub. The boot loader is required to load the kernel/initrd(s) 1408*ff61f079SJonathan Corbetfrom the boot media and jump to the EFI handover protocol entry point 1409*ff61f079SJonathan Corbetwhich is hdr->handover_offset bytes from the beginning of 1410*ff61f079SJonathan Corbetstartup_{32,64}. 1411*ff61f079SJonathan Corbet 1412*ff61f079SJonathan CorbetThe boot loader MUST respect the kernel's PE/COFF metadata when it comes 1413*ff61f079SJonathan Corbetto section alignment, the memory footprint of the executable image beyond 1414*ff61f079SJonathan Corbetthe size of the file itself, and any other aspect of the PE/COFF header 1415*ff61f079SJonathan Corbetthat may affect correct operation of the image as a PE/COFF binary in the 1416*ff61f079SJonathan Corbetexecution context provided by the EFI firmware. 1417*ff61f079SJonathan Corbet 1418*ff61f079SJonathan CorbetThe function prototype for the handover entry point looks like this:: 1419*ff61f079SJonathan Corbet 1420*ff61f079SJonathan Corbet efi_main(void *handle, efi_system_table_t *table, struct boot_params *bp) 1421*ff61f079SJonathan Corbet 1422*ff61f079SJonathan Corbet'handle' is the EFI image handle passed to the boot loader by the EFI 1423*ff61f079SJonathan Corbetfirmware, 'table' is the EFI system table - these are the first two 1424*ff61f079SJonathan Corbetarguments of the "handoff state" as described in section 2.3 of the 1425*ff61f079SJonathan CorbetUEFI specification. 'bp' is the boot loader-allocated boot params. 1426*ff61f079SJonathan Corbet 1427*ff61f079SJonathan CorbetThe boot loader *must* fill out the following fields in bp:: 1428*ff61f079SJonathan Corbet 1429*ff61f079SJonathan Corbet - hdr.cmd_line_ptr 1430*ff61f079SJonathan Corbet - hdr.ramdisk_image (if applicable) 1431*ff61f079SJonathan Corbet - hdr.ramdisk_size (if applicable) 1432*ff61f079SJonathan Corbet 1433*ff61f079SJonathan CorbetAll other fields should be zero. 1434*ff61f079SJonathan Corbet 1435*ff61f079SJonathan CorbetNOTE: The EFI Handover Protocol is deprecated in favour of the ordinary PE/COFF 1436*ff61f079SJonathan Corbet entry point, combined with the LINUX_EFI_INITRD_MEDIA_GUID based initrd 1437*ff61f079SJonathan Corbet loading protocol (refer to [0] for an example of the bootloader side of 1438*ff61f079SJonathan Corbet this), which removes the need for any knowledge on the part of the EFI 1439*ff61f079SJonathan Corbet bootloader regarding the internal representation of boot_params or any 1440*ff61f079SJonathan Corbet requirements/limitations regarding the placement of the command line 1441*ff61f079SJonathan Corbet and ramdisk in memory, or the placement of the kernel image itself. 1442*ff61f079SJonathan Corbet 1443*ff61f079SJonathan Corbet[0] https://github.com/u-boot/u-boot/commit/ec80b4735a593961fe701cc3a5d717d4739b0fd0 1444