Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

x86, boot: Define the 2.12 bzImage boot protocol

Define the 2.12 bzImage boot protocol: add xloadflags and additional
fields to allow the command line, initramfs and struct boot_params to
live above the 4 GiB mark.

The xloadflags now communicates if this is a 64-bit kernel with the
legacy 64-bit entry point and which of the EFI handover entry points
are supported.

Avoid adding new read flags to loadflags because of claimed
bootloaders testing the whole byte for == 1 to determine bzImageness
at least until the issue can be researched further.

This is based on patches by Yinghai Lu and David Woodhouse.

Originally-by: Yinghai Lu <yinghai@kernel.org>
Originally-by: David Woodhouse <dwmw2@infradead.org>
Acked-by: Yinghai Lu <yinghai@kernel.org>
Acked-by: David Woodhouse <dwmw2@infradead.org>
Acked-by: Matt Fleming <matt.fleming@intel.com>
Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
Link: http://lkml.kernel.org/r/1359058816-7615-26-git-send-email-yinghai@kernel.org
Cc: Rob Landley <rob@landley.net>
Cc: Gokul Caushik <caushik1@gmail.com>
Cc: Josh Triplett <josh@joshtriplett.org>
Cc: Joe Millenbach <jmillenbach@gmail.com>

+106 -29
+26 -1
Documentation/x86/boot.txt
··· 57 57 Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover 58 58 protocol entry point. 59 59 60 + Protocol 2.12: (Kernel 3.9) Added the xloadflags field and extension fields 61 + to struct boot_params for for loading bzImage and ramdisk 62 + above 4G in 64bit. 63 + 60 64 **** MEMORY LAYOUT 61 65 62 66 The traditional memory map for the kernel loader, used for Image or ··· 186 182 0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel 187 183 0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not 188 184 0235/1 2.10+ min_alignment Minimum alignment, as a power of two 189 - 0236/2 N/A pad3 Unused 185 + 0236/2 2.12+ xloadflags Boot protocol option flags 190 186 0238/4 2.06+ cmdline_size Maximum size of the kernel command line 191 187 023C/4 2.07+ hardware_subarch Hardware subarchitecture 192 188 0240/8 2.07+ hardware_subarch_data Subarchitecture-specific data ··· 585 581 There may be a considerable performance cost with an excessively 586 582 misaligned kernel. Therefore, a loader should typically try each 587 583 power-of-two alignment from kernel_alignment down to this alignment. 584 + 585 + Field name: xloadflags 586 + Type: read 587 + Offset/size: 0x236/2 588 + Protocol: 2.12+ 589 + 590 + This field is a bitmask. 591 + 592 + Bit 0 (read): XLF_KERNEL_64 593 + - If 1, this kernel has the legacy 64-bit entry point at 0x200. 594 + 595 + Bit 1 (read): XLF_CAN_BE_LOADED_ABOVE_4G 596 + - If 1, kernel/boot_params/cmdline/ramdisk can be above 4G. 597 + 598 + Bit 2 (read): XLF_EFI_HANDOVER_32 599 + - If 1, the kernel supports the 32-bit EFI handoff entry point 600 + given at handover_offset. 601 + 602 + Bit 3 (read): XLF_EFI_HANDOVER_64 603 + - If 1, the kernel supports the 64-bit EFI handoff entry point 604 + given at handover_offset + 0x200. 588 605 589 606 Field name: cmdline_size 590 607 Type: read
+4
Documentation/x86/zero-page.txt
··· 19 19 090/010 ALL hd1_info hd1 disk parameter, OBSOLETE!! 20 20 0A0/010 ALL sys_desc_table System description table (struct sys_desc_table) 21 21 0B0/010 ALL olpc_ofw_header OLPC's OpenFirmware CIF and friends 22 + 0C0/004 ALL ext_ramdisk_image ramdisk_image high 32bits 23 + 0C4/004 ALL ext_ramdisk_size ramdisk_size high 32bits 24 + 0C8/004 ALL ext_cmd_line_ptr cmd_line_ptr high 32bits 22 25 140/080 ALL edid_info Video mode setup (struct edid_info) 23 26 1C0/020 ALL efi_info EFI 32 information (struct efi_info) 24 27 1E0/004 ALL alk_mem_k Alternative mem check, in KB ··· 30 27 1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below) 31 28 1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer 32 29 (below) 30 + 1EF/001 ALL sentinel Used to detect broken bootloaders 33 31 290/040 ALL edd_mbr_sig_buffer EDD MBR signatures 34 32 2D0/A00 ALL e820_map E820 memory map table 35 33 (array of struct e820entry)
+29 -10
arch/x86/boot/header.S
··· 21 21 #include <asm/e820.h> 22 22 #include <asm/page_types.h> 23 23 #include <asm/setup.h> 24 + #include <asm/bootparam.h> 24 25 #include "boot.h" 25 26 #include "voffset.h" 26 27 #include "zoffset.h" ··· 256 255 # header, from the old boot sector. 257 256 258 257 .section ".header", "a" 258 + .globl sentinel 259 + sentinel: .byte 0xff, 0xff /* Used to detect broken loaders */ 260 + 259 261 .globl hdr 260 262 hdr: 261 263 setup_sects: .byte 0 /* Filled in by build.c */ ··· 283 279 # Part 2 of the header, from the old setup.S 284 280 285 281 .ascii "HdrS" # header signature 286 - .word 0x020b # header version number (>= 0x0105) 282 + .word 0x020c # header version number (>= 0x0105) 287 283 # or else old loadlin-1.5 will fail) 288 284 .globl realmode_swtch 289 285 realmode_swtch: .word 0, 0 # default_switch, SETUPSEG ··· 301 297 302 298 # flags, unused bits must be zero (RFU) bit within loadflags 303 299 loadflags: 304 - LOADED_HIGH = 1 # If set, the kernel is loaded high 305 - CAN_USE_HEAP = 0x80 # If set, the loader also has set 306 - # heap_end_ptr to tell how much 307 - # space behind setup.S can be used for 308 - # heap purposes. 309 - # Only the loader knows what is free 310 - .byte LOADED_HIGH 300 + .byte LOADED_HIGH # The kernel is to be loaded high 311 301 312 302 setup_move_size: .word 0x8000 # size to move, when setup is not 313 303 # loaded at 0x90000. We will move setup ··· 367 369 relocatable_kernel: .byte 0 368 370 #endif 369 371 min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment 370 - pad3: .word 0 372 + 373 + xloadflags: 374 + #ifdef CONFIG_X86_64 375 + # define XLF0 XLF_KERNEL_64 /* 64-bit kernel */ 376 + #else 377 + # define XLF0 0 378 + #endif 379 + #ifdef CONFIG_EFI_STUB 380 + # ifdef CONFIG_X86_64 381 + # define XLF23 XLF_EFI_HANDOVER_64 /* 64-bit EFI handover ok */ 382 + # else 383 + # define XLF23 XLF_EFI_HANDOVER_32 /* 32-bit EFI handover ok */ 384 + # endif 385 + #else 386 + # define XLF23 0 387 + #endif 388 + .word XLF0 | XLF23 371 389 372 390 cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line, 373 391 #added with boot protocol ··· 411 397 #define INIT_SIZE VO_INIT_SIZE 412 398 #endif 413 399 init_size: .long INIT_SIZE # kernel initialization size 414 - handover_offset: .long 0x30 # offset to the handover 400 + handover_offset: 401 + #ifdef CONFIG_EFI_STUB 402 + .long 0x30 # offset to the handover 415 403 # protocol entry point 404 + #else 405 + .long 0 406 + #endif 416 407 417 408 # End of setup header ##################################################### 418 409
+1 -1
arch/x86/boot/setup.ld
··· 13 13 .bstext : { *(.bstext) } 14 14 .bsdata : { *(.bsdata) } 15 15 16 - . = 497; 16 + . = 495; 17 17 .header : { *(.header) } 18 18 .entrytext : { *(.entrytext) } 19 19 .inittext : { *(.inittext) }
+46 -17
arch/x86/include/uapi/asm/bootparam.h
··· 1 1 #ifndef _ASM_X86_BOOTPARAM_H 2 2 #define _ASM_X86_BOOTPARAM_H 3 3 4 + /* setup_data types */ 5 + #define SETUP_NONE 0 6 + #define SETUP_E820_EXT 1 7 + #define SETUP_DTB 2 8 + #define SETUP_PCI 3 9 + 10 + /* ram_size flags */ 11 + #define RAMDISK_IMAGE_START_MASK 0x07FF 12 + #define RAMDISK_PROMPT_FLAG 0x8000 13 + #define RAMDISK_LOAD_FLAG 0x4000 14 + 15 + /* loadflags */ 16 + #define LOADED_HIGH (1<<0) 17 + #define QUIET_FLAG (1<<5) 18 + #define KEEP_SEGMENTS (1<<6) 19 + #define CAN_USE_HEAP (1<<7) 20 + 21 + /* xloadflags */ 22 + #define XLF_KERNEL_64 (1<<0) 23 + #define XLF_CAN_BE_LOADED_ABOVE_4G (1<<1) 24 + #define XLF_EFI_HANDOVER_32 (1<<2) 25 + #define XLF_EFI_HANDOVER_64 (1<<3) 26 + 27 + #ifndef __ASSEMBLY__ 28 + 4 29 #include <linux/types.h> 5 30 #include <linux/screen_info.h> 6 31 #include <linux/apm_bios.h> ··· 33 8 #include <asm/e820.h> 34 9 #include <asm/ist.h> 35 10 #include <video/edid.h> 36 - 37 - /* setup data types */ 38 - #define SETUP_NONE 0 39 - #define SETUP_E820_EXT 1 40 - #define SETUP_DTB 2 41 - #define SETUP_PCI 3 42 11 43 12 /* extensible setup data list node */ 44 13 struct setup_data { ··· 47 28 __u16 root_flags; 48 29 __u32 syssize; 49 30 __u16 ram_size; 50 - #define RAMDISK_IMAGE_START_MASK 0x07FF 51 - #define RAMDISK_PROMPT_FLAG 0x8000 52 - #define RAMDISK_LOAD_FLAG 0x4000 53 31 __u16 vid_mode; 54 32 __u16 root_dev; 55 33 __u16 boot_flag; ··· 58 42 __u16 kernel_version; 59 43 __u8 type_of_loader; 60 44 __u8 loadflags; 61 - #define LOADED_HIGH (1<<0) 62 - #define QUIET_FLAG (1<<5) 63 - #define KEEP_SEGMENTS (1<<6) 64 - #define CAN_USE_HEAP (1<<7) 65 45 __u16 setup_move_size; 66 46 __u32 code32_start; 67 47 __u32 ramdisk_image; ··· 70 58 __u32 initrd_addr_max; 71 59 __u32 kernel_alignment; 72 60 __u8 relocatable_kernel; 73 - __u8 _pad2[3]; 61 + __u8 min_alignment; 62 + __u16 xloadflags; 74 63 __u32 cmdline_size; 75 64 __u32 hardware_subarch; 76 65 __u64 hardware_subarch_data; ··· 119 106 __u8 hd1_info[16]; /* obsolete! */ /* 0x090 */ 120 107 struct sys_desc_table sys_desc_table; /* 0x0a0 */ 121 108 struct olpc_ofw_header olpc_ofw_header; /* 0x0b0 */ 122 - __u8 _pad4[128]; /* 0x0c0 */ 109 + __u32 ext_ramdisk_image; /* 0x0c0 */ 110 + __u32 ext_ramdisk_size; /* 0x0c4 */ 111 + __u32 ext_cmd_line_ptr; /* 0x0c8 */ 112 + __u8 _pad4[116]; /* 0x0cc */ 123 113 struct edid_info edid_info; /* 0x140 */ 124 114 struct efi_info efi_info; /* 0x1c0 */ 125 115 __u32 alt_mem_k; /* 0x1e0 */ ··· 131 115 __u8 eddbuf_entries; /* 0x1e9 */ 132 116 __u8 edd_mbr_sig_buf_entries; /* 0x1ea */ 133 117 __u8 kbd_status; /* 0x1eb */ 134 - __u8 _pad6[5]; /* 0x1ec */ 118 + __u8 _pad5[3]; /* 0x1ec */ 119 + /* 120 + * The sentinel is set to a nonzero value (0xff) in header.S. 121 + * 122 + * A bootloader is supposed to only take setup_header and put 123 + * it into a clean boot_params buffer. If it turns out that 124 + * it is clumsy or too generous with the buffer, it most 125 + * probably will pick up the sentinel variable too. The fact 126 + * that this variable then is still 0xff will let kernel 127 + * know that some variables in boot_params are invalid and 128 + * kernel should zero out certain portions of boot_params. 129 + */ 130 + __u8 sentinel; /* 0x1ef */ 131 + __u8 _pad6[1]; /* 0x1f0 */ 135 132 struct setup_header hdr; /* setup header */ /* 0x1f1 */ 136 133 __u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)]; 137 134 __u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */ ··· 163 134 X86_NR_SUBARCHS, 164 135 }; 165 136 166 - 137 + #endif /* __ASSEMBLY__ */ 167 138 168 139 #endif /* _ASM_X86_BOOTPARAM_H */