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>
This commit is contained in:
parent
65315d4889
commit
09c205afde
|
@ -57,6 +57,10 @@ Protocol 2.10: (Kernel 2.6.31) Added a protocol for relaxed alignment
|
||||||
Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover
|
Protocol 2.11: (Kernel 3.6) Added a field for offset of EFI handover
|
||||||
protocol entry point.
|
protocol entry point.
|
||||||
|
|
||||||
|
Protocol 2.12: (Kernel 3.9) Added the xloadflags field and extension fields
|
||||||
|
to struct boot_params for for loading bzImage and ramdisk
|
||||||
|
above 4G in 64bit.
|
||||||
|
|
||||||
**** MEMORY LAYOUT
|
**** MEMORY LAYOUT
|
||||||
|
|
||||||
The traditional memory map for the kernel loader, used for Image or
|
The traditional memory map for the kernel loader, used for Image or
|
||||||
|
@ -182,7 +186,7 @@ Offset Proto Name Meaning
|
||||||
0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel
|
0230/4 2.05+ kernel_alignment Physical addr alignment required for kernel
|
||||||
0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not
|
0234/1 2.05+ relocatable_kernel Whether kernel is relocatable or not
|
||||||
0235/1 2.10+ min_alignment Minimum alignment, as a power of two
|
0235/1 2.10+ min_alignment Minimum alignment, as a power of two
|
||||||
0236/2 N/A pad3 Unused
|
0236/2 2.12+ xloadflags Boot protocol option flags
|
||||||
0238/4 2.06+ cmdline_size Maximum size of the kernel command line
|
0238/4 2.06+ cmdline_size Maximum size of the kernel command line
|
||||||
023C/4 2.07+ hardware_subarch Hardware subarchitecture
|
023C/4 2.07+ hardware_subarch Hardware subarchitecture
|
||||||
0240/8 2.07+ hardware_subarch_data Subarchitecture-specific data
|
0240/8 2.07+ hardware_subarch_data Subarchitecture-specific data
|
||||||
|
@ -582,6 +586,27 @@ Protocol: 2.10+
|
||||||
misaligned kernel. Therefore, a loader should typically try each
|
misaligned kernel. Therefore, a loader should typically try each
|
||||||
power-of-two alignment from kernel_alignment down to this alignment.
|
power-of-two alignment from kernel_alignment down to this alignment.
|
||||||
|
|
||||||
|
Field name: xloadflags
|
||||||
|
Type: read
|
||||||
|
Offset/size: 0x236/2
|
||||||
|
Protocol: 2.12+
|
||||||
|
|
||||||
|
This field is a bitmask.
|
||||||
|
|
||||||
|
Bit 0 (read): XLF_KERNEL_64
|
||||||
|
- If 1, this kernel has the legacy 64-bit entry point at 0x200.
|
||||||
|
|
||||||
|
Bit 1 (read): XLF_CAN_BE_LOADED_ABOVE_4G
|
||||||
|
- If 1, kernel/boot_params/cmdline/ramdisk can be above 4G.
|
||||||
|
|
||||||
|
Bit 2 (read): XLF_EFI_HANDOVER_32
|
||||||
|
- If 1, the kernel supports the 32-bit EFI handoff entry point
|
||||||
|
given at handover_offset.
|
||||||
|
|
||||||
|
Bit 3 (read): XLF_EFI_HANDOVER_64
|
||||||
|
- If 1, the kernel supports the 64-bit EFI handoff entry point
|
||||||
|
given at handover_offset + 0x200.
|
||||||
|
|
||||||
Field name: cmdline_size
|
Field name: cmdline_size
|
||||||
Type: read
|
Type: read
|
||||||
Offset/size: 0x238/4
|
Offset/size: 0x238/4
|
||||||
|
|
|
@ -19,6 +19,9 @@ Offset Proto Name Meaning
|
||||||
090/010 ALL hd1_info hd1 disk parameter, OBSOLETE!!
|
090/010 ALL hd1_info hd1 disk parameter, OBSOLETE!!
|
||||||
0A0/010 ALL sys_desc_table System description table (struct sys_desc_table)
|
0A0/010 ALL sys_desc_table System description table (struct sys_desc_table)
|
||||||
0B0/010 ALL olpc_ofw_header OLPC's OpenFirmware CIF and friends
|
0B0/010 ALL olpc_ofw_header OLPC's OpenFirmware CIF and friends
|
||||||
|
0C0/004 ALL ext_ramdisk_image ramdisk_image high 32bits
|
||||||
|
0C4/004 ALL ext_ramdisk_size ramdisk_size high 32bits
|
||||||
|
0C8/004 ALL ext_cmd_line_ptr cmd_line_ptr high 32bits
|
||||||
140/080 ALL edid_info Video mode setup (struct edid_info)
|
140/080 ALL edid_info Video mode setup (struct edid_info)
|
||||||
1C0/020 ALL efi_info EFI 32 information (struct efi_info)
|
1C0/020 ALL efi_info EFI 32 information (struct efi_info)
|
||||||
1E0/004 ALL alk_mem_k Alternative mem check, in KB
|
1E0/004 ALL alk_mem_k Alternative mem check, in KB
|
||||||
|
@ -27,6 +30,7 @@ Offset Proto Name Meaning
|
||||||
1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below)
|
1E9/001 ALL eddbuf_entries Number of entries in eddbuf (below)
|
||||||
1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
|
1EA/001 ALL edd_mbr_sig_buf_entries Number of entries in edd_mbr_sig_buffer
|
||||||
(below)
|
(below)
|
||||||
|
1EF/001 ALL sentinel Used to detect broken bootloaders
|
||||||
290/040 ALL edd_mbr_sig_buffer EDD MBR signatures
|
290/040 ALL edd_mbr_sig_buffer EDD MBR signatures
|
||||||
2D0/A00 ALL e820_map E820 memory map table
|
2D0/A00 ALL e820_map E820 memory map table
|
||||||
(array of struct e820entry)
|
(array of struct e820entry)
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include <asm/e820.h>
|
#include <asm/e820.h>
|
||||||
#include <asm/page_types.h>
|
#include <asm/page_types.h>
|
||||||
#include <asm/setup.h>
|
#include <asm/setup.h>
|
||||||
|
#include <asm/bootparam.h>
|
||||||
#include "boot.h"
|
#include "boot.h"
|
||||||
#include "voffset.h"
|
#include "voffset.h"
|
||||||
#include "zoffset.h"
|
#include "zoffset.h"
|
||||||
|
@ -255,6 +256,9 @@ section_table:
|
||||||
# header, from the old boot sector.
|
# header, from the old boot sector.
|
||||||
|
|
||||||
.section ".header", "a"
|
.section ".header", "a"
|
||||||
|
.globl sentinel
|
||||||
|
sentinel: .byte 0xff, 0xff /* Used to detect broken loaders */
|
||||||
|
|
||||||
.globl hdr
|
.globl hdr
|
||||||
hdr:
|
hdr:
|
||||||
setup_sects: .byte 0 /* Filled in by build.c */
|
setup_sects: .byte 0 /* Filled in by build.c */
|
||||||
|
@ -279,7 +283,7 @@ _start:
|
||||||
# Part 2 of the header, from the old setup.S
|
# Part 2 of the header, from the old setup.S
|
||||||
|
|
||||||
.ascii "HdrS" # header signature
|
.ascii "HdrS" # header signature
|
||||||
.word 0x020b # header version number (>= 0x0105)
|
.word 0x020c # header version number (>= 0x0105)
|
||||||
# or else old loadlin-1.5 will fail)
|
# or else old loadlin-1.5 will fail)
|
||||||
.globl realmode_swtch
|
.globl realmode_swtch
|
||||||
realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
|
realmode_swtch: .word 0, 0 # default_switch, SETUPSEG
|
||||||
|
@ -297,13 +301,7 @@ type_of_loader: .byte 0 # 0 means ancient bootloader, newer
|
||||||
|
|
||||||
# flags, unused bits must be zero (RFU) bit within loadflags
|
# flags, unused bits must be zero (RFU) bit within loadflags
|
||||||
loadflags:
|
loadflags:
|
||||||
LOADED_HIGH = 1 # If set, the kernel is loaded high
|
.byte LOADED_HIGH # The kernel is to be loaded high
|
||||||
CAN_USE_HEAP = 0x80 # If set, the loader also has set
|
|
||||||
# heap_end_ptr to tell how much
|
|
||||||
# space behind setup.S can be used for
|
|
||||||
# heap purposes.
|
|
||||||
# Only the loader knows what is free
|
|
||||||
.byte LOADED_HIGH
|
|
||||||
|
|
||||||
setup_move_size: .word 0x8000 # size to move, when setup is not
|
setup_move_size: .word 0x8000 # size to move, when setup is not
|
||||||
# loaded at 0x90000. We will move setup
|
# loaded at 0x90000. We will move setup
|
||||||
|
@ -369,7 +367,23 @@ relocatable_kernel: .byte 1
|
||||||
relocatable_kernel: .byte 0
|
relocatable_kernel: .byte 0
|
||||||
#endif
|
#endif
|
||||||
min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment
|
min_alignment: .byte MIN_KERNEL_ALIGN_LG2 # minimum alignment
|
||||||
pad3: .word 0
|
|
||||||
|
xloadflags:
|
||||||
|
#ifdef CONFIG_X86_64
|
||||||
|
# define XLF0 XLF_KERNEL_64 /* 64-bit kernel */
|
||||||
|
#else
|
||||||
|
# define XLF0 0
|
||||||
|
#endif
|
||||||
|
#ifdef CONFIG_EFI_STUB
|
||||||
|
# ifdef CONFIG_X86_64
|
||||||
|
# define XLF23 XLF_EFI_HANDOVER_64 /* 64-bit EFI handover ok */
|
||||||
|
# else
|
||||||
|
# define XLF23 XLF_EFI_HANDOVER_32 /* 32-bit EFI handover ok */
|
||||||
|
# endif
|
||||||
|
#else
|
||||||
|
# define XLF23 0
|
||||||
|
#endif
|
||||||
|
.word XLF0 | XLF23
|
||||||
|
|
||||||
cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
|
cmdline_size: .long COMMAND_LINE_SIZE-1 #length of the command line,
|
||||||
#added with boot protocol
|
#added with boot protocol
|
||||||
|
@ -397,8 +411,13 @@ pref_address: .quad LOAD_PHYSICAL_ADDR # preferred load addr
|
||||||
#define INIT_SIZE VO_INIT_SIZE
|
#define INIT_SIZE VO_INIT_SIZE
|
||||||
#endif
|
#endif
|
||||||
init_size: .long INIT_SIZE # kernel initialization size
|
init_size: .long INIT_SIZE # kernel initialization size
|
||||||
handover_offset: .long 0x30 # offset to the handover
|
handover_offset:
|
||||||
|
#ifdef CONFIG_EFI_STUB
|
||||||
|
.long 0x30 # offset to the handover
|
||||||
# protocol entry point
|
# protocol entry point
|
||||||
|
#else
|
||||||
|
.long 0
|
||||||
|
#endif
|
||||||
|
|
||||||
# End of setup header #####################################################
|
# End of setup header #####################################################
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ SECTIONS
|
||||||
.bstext : { *(.bstext) }
|
.bstext : { *(.bstext) }
|
||||||
.bsdata : { *(.bsdata) }
|
.bsdata : { *(.bsdata) }
|
||||||
|
|
||||||
. = 497;
|
. = 495;
|
||||||
.header : { *(.header) }
|
.header : { *(.header) }
|
||||||
.entrytext : { *(.entrytext) }
|
.entrytext : { *(.entrytext) }
|
||||||
.inittext : { *(.inittext) }
|
.inittext : { *(.inittext) }
|
||||||
|
|
|
@ -1,6 +1,31 @@
|
||||||
#ifndef _ASM_X86_BOOTPARAM_H
|
#ifndef _ASM_X86_BOOTPARAM_H
|
||||||
#define _ASM_X86_BOOTPARAM_H
|
#define _ASM_X86_BOOTPARAM_H
|
||||||
|
|
||||||
|
/* setup_data types */
|
||||||
|
#define SETUP_NONE 0
|
||||||
|
#define SETUP_E820_EXT 1
|
||||||
|
#define SETUP_DTB 2
|
||||||
|
#define SETUP_PCI 3
|
||||||
|
|
||||||
|
/* ram_size flags */
|
||||||
|
#define RAMDISK_IMAGE_START_MASK 0x07FF
|
||||||
|
#define RAMDISK_PROMPT_FLAG 0x8000
|
||||||
|
#define RAMDISK_LOAD_FLAG 0x4000
|
||||||
|
|
||||||
|
/* loadflags */
|
||||||
|
#define LOADED_HIGH (1<<0)
|
||||||
|
#define QUIET_FLAG (1<<5)
|
||||||
|
#define KEEP_SEGMENTS (1<<6)
|
||||||
|
#define CAN_USE_HEAP (1<<7)
|
||||||
|
|
||||||
|
/* xloadflags */
|
||||||
|
#define XLF_KERNEL_64 (1<<0)
|
||||||
|
#define XLF_CAN_BE_LOADED_ABOVE_4G (1<<1)
|
||||||
|
#define XLF_EFI_HANDOVER_32 (1<<2)
|
||||||
|
#define XLF_EFI_HANDOVER_64 (1<<3)
|
||||||
|
|
||||||
|
#ifndef __ASSEMBLY__
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/screen_info.h>
|
#include <linux/screen_info.h>
|
||||||
#include <linux/apm_bios.h>
|
#include <linux/apm_bios.h>
|
||||||
|
@ -9,12 +34,6 @@
|
||||||
#include <asm/ist.h>
|
#include <asm/ist.h>
|
||||||
#include <video/edid.h>
|
#include <video/edid.h>
|
||||||
|
|
||||||
/* setup data types */
|
|
||||||
#define SETUP_NONE 0
|
|
||||||
#define SETUP_E820_EXT 1
|
|
||||||
#define SETUP_DTB 2
|
|
||||||
#define SETUP_PCI 3
|
|
||||||
|
|
||||||
/* extensible setup data list node */
|
/* extensible setup data list node */
|
||||||
struct setup_data {
|
struct setup_data {
|
||||||
__u64 next;
|
__u64 next;
|
||||||
|
@ -28,9 +47,6 @@ struct setup_header {
|
||||||
__u16 root_flags;
|
__u16 root_flags;
|
||||||
__u32 syssize;
|
__u32 syssize;
|
||||||
__u16 ram_size;
|
__u16 ram_size;
|
||||||
#define RAMDISK_IMAGE_START_MASK 0x07FF
|
|
||||||
#define RAMDISK_PROMPT_FLAG 0x8000
|
|
||||||
#define RAMDISK_LOAD_FLAG 0x4000
|
|
||||||
__u16 vid_mode;
|
__u16 vid_mode;
|
||||||
__u16 root_dev;
|
__u16 root_dev;
|
||||||
__u16 boot_flag;
|
__u16 boot_flag;
|
||||||
|
@ -42,10 +58,6 @@ struct setup_header {
|
||||||
__u16 kernel_version;
|
__u16 kernel_version;
|
||||||
__u8 type_of_loader;
|
__u8 type_of_loader;
|
||||||
__u8 loadflags;
|
__u8 loadflags;
|
||||||
#define LOADED_HIGH (1<<0)
|
|
||||||
#define QUIET_FLAG (1<<5)
|
|
||||||
#define KEEP_SEGMENTS (1<<6)
|
|
||||||
#define CAN_USE_HEAP (1<<7)
|
|
||||||
__u16 setup_move_size;
|
__u16 setup_move_size;
|
||||||
__u32 code32_start;
|
__u32 code32_start;
|
||||||
__u32 ramdisk_image;
|
__u32 ramdisk_image;
|
||||||
|
@ -58,7 +70,8 @@ struct setup_header {
|
||||||
__u32 initrd_addr_max;
|
__u32 initrd_addr_max;
|
||||||
__u32 kernel_alignment;
|
__u32 kernel_alignment;
|
||||||
__u8 relocatable_kernel;
|
__u8 relocatable_kernel;
|
||||||
__u8 _pad2[3];
|
__u8 min_alignment;
|
||||||
|
__u16 xloadflags;
|
||||||
__u32 cmdline_size;
|
__u32 cmdline_size;
|
||||||
__u32 hardware_subarch;
|
__u32 hardware_subarch;
|
||||||
__u64 hardware_subarch_data;
|
__u64 hardware_subarch_data;
|
||||||
|
@ -106,7 +119,10 @@ struct boot_params {
|
||||||
__u8 hd1_info[16]; /* obsolete! */ /* 0x090 */
|
__u8 hd1_info[16]; /* obsolete! */ /* 0x090 */
|
||||||
struct sys_desc_table sys_desc_table; /* 0x0a0 */
|
struct sys_desc_table sys_desc_table; /* 0x0a0 */
|
||||||
struct olpc_ofw_header olpc_ofw_header; /* 0x0b0 */
|
struct olpc_ofw_header olpc_ofw_header; /* 0x0b0 */
|
||||||
__u8 _pad4[128]; /* 0x0c0 */
|
__u32 ext_ramdisk_image; /* 0x0c0 */
|
||||||
|
__u32 ext_ramdisk_size; /* 0x0c4 */
|
||||||
|
__u32 ext_cmd_line_ptr; /* 0x0c8 */
|
||||||
|
__u8 _pad4[116]; /* 0x0cc */
|
||||||
struct edid_info edid_info; /* 0x140 */
|
struct edid_info edid_info; /* 0x140 */
|
||||||
struct efi_info efi_info; /* 0x1c0 */
|
struct efi_info efi_info; /* 0x1c0 */
|
||||||
__u32 alt_mem_k; /* 0x1e0 */
|
__u32 alt_mem_k; /* 0x1e0 */
|
||||||
|
@ -115,7 +131,20 @@ struct boot_params {
|
||||||
__u8 eddbuf_entries; /* 0x1e9 */
|
__u8 eddbuf_entries; /* 0x1e9 */
|
||||||
__u8 edd_mbr_sig_buf_entries; /* 0x1ea */
|
__u8 edd_mbr_sig_buf_entries; /* 0x1ea */
|
||||||
__u8 kbd_status; /* 0x1eb */
|
__u8 kbd_status; /* 0x1eb */
|
||||||
__u8 _pad6[5]; /* 0x1ec */
|
__u8 _pad5[3]; /* 0x1ec */
|
||||||
|
/*
|
||||||
|
* The sentinel is set to a nonzero value (0xff) in header.S.
|
||||||
|
*
|
||||||
|
* A bootloader is supposed to only take setup_header and put
|
||||||
|
* it into a clean boot_params buffer. If it turns out that
|
||||||
|
* it is clumsy or too generous with the buffer, it most
|
||||||
|
* probably will pick up the sentinel variable too. The fact
|
||||||
|
* that this variable then is still 0xff will let kernel
|
||||||
|
* know that some variables in boot_params are invalid and
|
||||||
|
* kernel should zero out certain portions of boot_params.
|
||||||
|
*/
|
||||||
|
__u8 sentinel; /* 0x1ef */
|
||||||
|
__u8 _pad6[1]; /* 0x1f0 */
|
||||||
struct setup_header hdr; /* setup header */ /* 0x1f1 */
|
struct setup_header hdr; /* setup header */ /* 0x1f1 */
|
||||||
__u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
|
__u8 _pad7[0x290-0x1f1-sizeof(struct setup_header)];
|
||||||
__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */
|
__u32 edd_mbr_sig_buffer[EDD_MBR_SIG_MAX]; /* 0x290 */
|
||||||
|
@ -134,6 +163,6 @@ enum {
|
||||||
X86_NR_SUBARCHS,
|
X86_NR_SUBARCHS,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#endif /* __ASSEMBLY__ */
|
||||||
|
|
||||||
#endif /* _ASM_X86_BOOTPARAM_H */
|
#endif /* _ASM_X86_BOOTPARAM_H */
|
||||||
|
|
Loading…
Reference in New Issue