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