On February 15, 2017 6:41:56 AM PST, Chao Peng <chao.p.p...@linux.intel.com> wrote: >Multiboot specification >(http://git.savannah.gnu.org/cgit/grub.git/tree/doc/multiboot.texi?h=multiboot2) >is an open standard that provides kernels with a uniform way to be >booted >by multiboot-compliant bootloaders (like grub). > >This patch is trying to make Linux ELF kernel image to be a >multiboot-compliant OS so that it can be loaded by a multiboot-comliant >bootloader. The benefit is eliminating the maintainance for realmode >and >decompression code and especially when the kernel is loaded in a >virtual >machine, the reducing for these code can greatly cuts down the boot >time. > >However, the current version of multiboot spec doesn't support 64 bit >well so for 64 bit kernel we need stub code to jump from 32 bit code to >64 bit code. Besides, there are still some other issues: > 1). '-z max-page-size=0x1000' is used so the text segment start is in > multiboot header search scope because GNU LD has default page size of > 0x00200000 for ELF64, which will fail multiboot test. > >2). The bootloader like grub has support for ELF kernel (even for >ELF64) > which makes the patch easier. However, the current grub implementaion >thinks the entry address should be a VA. E.g. for 64 bit kernel, the >entry >address (0x1000000) is actually phiscial address, grub refuses to load >it > by saying: 'entry point isn't in a segment'. > >This patch is sent out as RFC in case you have some ideas. > >Signed-off-by: Chao Peng <chao.p.p...@linux.intel.com> >--- > arch/x86/Kconfig | 6 + > arch/x86/Makefile | 4 + > arch/x86/kernel/head64.c | 64 ++++++- > arch/x86/kernel/head_64.S | 175 ++++++++++++++++++ >arch/x86/kernel/multiboot2.h | 417 >+++++++++++++++++++++++++++++++++++++++++++ > 5 files changed, 665 insertions(+), 1 deletion(-) > create mode 100644 arch/x86/kernel/multiboot2.h > >diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig >index bada636..75a9ef2 100644 >--- a/arch/x86/Kconfig >+++ b/arch/x86/Kconfig >@@ -585,6 +585,12 @@ config X86_AMD_PLATFORM_DEVICE > I2C and UART depend on COMMON_CLK to set clock. GPIO driver is > implemented under PINCTRL subsystem. > >+config X86_MULTIBOOT_STUB >+ bool "Multiboot stub support for ELF kernel image" >+ default n >+ ---help--- >+ Set whether multiboot stub is on or off. >+ > config IOSF_MBI > tristate "Intel SoC IOSF Sideband support for SoC platforms" > depends on PCI >diff --git a/arch/x86/Makefile b/arch/x86/Makefile >index 2d44933..d945c34 100644 >--- a/arch/x86/Makefile >+++ b/arch/x86/Makefile >@@ -39,6 +39,10 @@ ifdef CONFIG_X86_NEED_RELOCS > LDFLAGS_vmlinux := --emit-relocs > endif > >+ifdef CONFIG_X86_MULTIBOOT_STUB >+ LDFLAGS_vmlinux += -z max-page-size=0x1000 >+endif >+ > # > # Prevent GCC from generating any FP code by mistake. > # >diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c >index 54a2372..c0f375a 100644 >--- a/arch/x86/kernel/head64.c >+++ b/arch/x86/kernel/head64.c >@@ -29,6 +29,8 @@ > #include <asm/microcode.h> > #include <asm/kasan.h> > >+#include "multiboot2.h" >+ > /* > * Manage page tables very early on. > */ >@@ -36,6 +38,7 @@ extern pgd_t early_level4_pgt[PTRS_PER_PGD]; >extern pmd_t >early_dynamic_pgts[EARLY_DYNAMIC_PAGE_TABLES][PTRS_PER_PMD]; > static unsigned int __initdata next_early_pgt = 2; >pmdval_t early_pmd_flags = __PAGE_KERNEL_LARGE & ~(_PAGE_GLOBAL | >_PAGE_NX); >+char *multiboot_info = NULL; > > /* Wipe all early page tables except for the kernel symbol map */ > static void __init reset_early_page_tables(void) >@@ -130,6 +133,60 @@ static void __init copy_bootdata(char >*real_mode_data) > } > } > >+static void __init copy_multiboot_cmdline(struct multiboot_tag_string >*tag) >+{ >+ unsigned int size = tag->size - 8; >+ >+ if (size > COMMAND_LINE_SIZE) >+ size = COMMAND_LINE_SIZE; >+ boot_params.hdr.cmdline_size = size; >+ memcpy(boot_command_line, tag->string, size); >+} >+ >+static void __init copy_multiboot_mmap(struct multiboot_tag_mmap *tag) >+{ >+ multiboot_memory_map_t *mmap; >+ int nr = 0; >+ >+ for (mmap = tag->entries; >+ (u8 *)mmap < (u8 *)tag + tag->size && nr < E820MAX; >+ mmap = (multiboot_memory_map_t *)((unsigned long)mmap + >+ tag->entry_size)) { >+ boot_params.e820_map[nr].addr = mmap->addr; >+ boot_params.e820_map[nr].size = mmap->len; >+ boot_params.e820_map[nr].type = mmap->type; >+ nr++; >+ } >+ boot_params.e820_entries = nr; >+} >+ >+static void __init copy_multiboot_info(void) >+{ >+ struct multiboot_tag *tag; >+ char *ptr = __va(multiboot_info); >+ >+ boot_params.hdr.boot_flag = 0xAA55; >+ boot_params.hdr.header = 0x53726448; >+ boot_params.hdr.version = 0x202; >+ >+ for (tag = (struct multiboot_tag *)(ptr + 8); >+ tag->type != MULTIBOOT_TAG_TYPE_END; >+ tag = (struct multiboot_tag *)((u8 *) tag + >+ ((tag->size + 7) & ~7))) { >+ switch (tag->type) { >+ case MULTIBOOT_TAG_TYPE_CMDLINE: >+ copy_multiboot_cmdline( >+ (struct multiboot_tag_string *)tag); >+ break; >+ case MULTIBOOT_TAG_TYPE_MMAP: >+ copy_multiboot_mmap((struct multiboot_tag_mmap *)tag); >+ break; >+ default: >+ break; >+ } >+ } >+} >+ >asmlinkage __visible void __init x86_64_start_kernel(char * >real_mode_data) > { > int i; >@@ -163,7 +220,12 @@ asmlinkage __visible void __init >x86_64_start_kernel(char * real_mode_data) > set_intr_gate(i, early_idt_handler_array[i]); > load_idt((const struct desc_ptr *)&idt_descr); > >- copy_bootdata(__va(real_mode_data)); >+ if (multiboot_info) { >+ copy_multiboot_info(); >+ real_mode_data = (char *) (__pa(&boot_params)); >+ } else { >+ copy_bootdata(__va(real_mode_data)); >+ } > > /* > * Load microcode early on BSP. >diff --git a/arch/x86/kernel/head_64.S b/arch/x86/kernel/head_64.S >index b4421cc..1c944fd 100644 >--- a/arch/x86/kernel/head_64.S >+++ b/arch/x86/kernel/head_64.S >@@ -22,6 +22,7 @@ > #include <asm/nops.h> > #include "../entry/calling.h" > #include <asm/export.h> >+#include <asm/boot.h> > > #ifdef CONFIG_PARAVIRT > #include <asm/asm-offsets.h> >@@ -32,6 +33,8 @@ > #define INTERRUPT_RETURN iretq > #endif > >+#include "multiboot2.h" >+ >/* we are not able to switch in one step to the final KERNEL ADDRESS >SPACE > * because we need identity-mapped pages. > * >@@ -66,6 +69,161 @@ startup_64: > * tables and then reload them. > */ > >+#ifdef CONFIG_X86_MULTIBOOT_STUB >+ jmp multiboot_entry >+ >+ .align MULTIBOOT_HEADER_ALIGN >+multiboot_header: >+ /* magic */ >+ .long MULTIBOOT2_HEADER_MAGIC >+ /* ISA: i386 */ >+ .long MULTIBOOT_ARCHITECTURE_I386 >+ /* Header length. */ >+ .long multiboot_header_end - multiboot_header >+ /* checksum */ >+ .long -(MULTIBOOT2_HEADER_MAGIC + MULTIBOOT_ARCHITECTURE_I386 >+ \ >+ (multiboot_header_end - multiboot_header)) >+ >+ /* information request tag */ >+infomation_request_start: >+ .short MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST >+ .short MULTIBOOT_HEADER_TAG_OPTIONAL >+ .long infomation_request_end - infomation_request_start >+ .long MULTIBOOT_TAG_TYPE_CMDLINE >+ .long MULTIBOOT_TAG_TYPE_MMAP >+infomation_request_end: >+ >+ .short MULTIBOOT_HEADER_TAG_END >+ .short 0 >+ .long 8 >+multiboot_header_end: >+ >+multiboot_entry: >+ cmpl $MULTIBOOT2_BOOTLOADER_MAGIC, %eax >+ jne not_multiboot >+ >+ .code32 >+ /* %ebp contains the address we are loaded at by the boot loader */ >+ movl $_text - __START_KERNEL_map, %ebp >+ >+ /* Store the Multiboot information structure */ >+ movl %ebx, (multiboot_info - startup_64)(%ebp) >+ >+ /* >+ * The Multiboot-compliant bootloader puts the machine in 32-bit mode >+ * so we need to switch to long mode by ourself. If later version of >+ * Multiboot protocal supports 64-bit machine state then this part of >+ * code may be eliminated. >+ */ >+ cli >+ movl $(__BOOT_DS), %eax >+ movl %eax, %ds >+ movl %eax, %es >+ movl %eax, %ss >+ >+ /* Setup a stack and make sure cpu supports long mode. */ >+ movl (__end_init_task - 8 - startup_64)(%ebp), %eax >+ movl %eax, %esp >+ >+ call verify_cpu >+ testl %eax, %eax >+ jnz no_longmode >+ >+/* >+ * Prepare for entering 64 bit mode >+ */ >+ >+ /* Load new GDT with the 64bit segments using 32bit descriptor */ >+ leal (gdt - startup_64)(%ebp), %eax >+ movl %eax, (gdt + 2 - startup_64)(%ebp) >+ lgdt (gdt - startup_64)(%ebp) >+ >+ /* Enable PAE mode */ >+ movl %cr4, %eax >+ orl $X86_CR4_PAE, %eax >+ movl %eax, %cr4 >+ >+ /* >+ * Build early 4G boot pagetable >+ */ >+ /* Initialize Page tables to 0 */ >+ /*leal pgtable(%ebp), %edi >+ xorl %eax, %eax >+ movl $(BOOT_INIT_PGT_SIZE/4), %ecx >+ rep stosl*/ >+ >+ /* Build Level 4 */ >+ leal (pgtable - startup_64)(%ebp), %edi >+ leal 0x1007 (%edi), %eax >+ movl %eax, 0(%edi) >+ >+ /* Build Level 3 */ >+ leal (pgtable + 0x1000 - startup_64)(%ebp), %edi >+ leal 0x1007(%edi), %eax >+ movl $4, %ecx >+1: movl %eax, 0x00(%edi) >+ addl $0x00001000, %eax >+ addl $8, %edi >+ decl %ecx >+ jnz 1b >+ >+ /* Build Level 2 */ >+ leal (pgtable + 0x2000 - startup_64)(%ebp), %edi >+ movl $0x00000183, %eax >+ movl $2048, %ecx >+1: movl %eax, 0(%edi) >+ addl $0x00200000, %eax >+ addl $8, %edi >+ decl %ecx >+ jnz 1b >+ >+ /* Enable the boot page tables */ >+ leal (pgtable - startup_64)(%ebp), %eax >+ movl %eax, %cr3 >+ >+ /* Enable Long mode in EFER (Extended Feature Enable Register) */ >+ movl $MSR_EFER, %ecx >+ rdmsr >+ btsl $_EFER_LME, %eax >+ wrmsr >+ >+ /* After gdt is loaded */ >+ xorl %eax, %eax >+ lldt %ax >+ movl $__BOOT_TSS, %eax >+ ltr %ax >+ >+ /* >+ * Setup for the jump to 64bit mode >+ * >+ * When the jump is performend we will be in long mode but >+ * in 32bit compatibility mode with EFER.LME = 1, CS.L = 0, CS.D = 1 >+ * (and in turn EFER.LMA = 1). To jump into 64bit mode we use >+ * the new gdt/idt that has __KERNEL_CS with CS.L = 1. >+ * We place all of the values on our mini stack so lret can >+ * used to perform that far jump. >+ */ >+ pushl $__KERNEL_CS >+ leal (not_multiboot - startup_64)(%ebp), %eax >+ pushl %eax >+ >+ /* Enter paged protected Mode, activating Long Mode */ >+ movl $(X86_CR0_PG | X86_CR0_PE), %eax /* Enable Paging and Protected >mode */ >+ movl %eax, %cr0 >+ >+ /* Jump from 32bit compatibility mode into 64bit mode. */ >+ lret >+ >+no_longmode: >+ /* This isn't an x86-64 CPU so hang */ >+1: >+ hlt >+ jmp 1b >+ >+ .code64 >+not_multiboot: >+#endif >+ > /* > * Setup stack for verify_cpu(). "-8" because initial_stack is defined > * this way, see below. Our best guess is a NULL ptr for stack >@@ -489,6 +647,23 @@ ENTRY(phys_base) > .quad 0x0000000000000000 > EXPORT_SYMBOL(phys_base) > >+#ifdef CONFIG_X86_MULTIBOOT_STUB >+gdt: >+ .word gdt_end - gdt >+ .long 0 >+ .word 0 >+ .quad 0x0000000000000000 /* NULL descriptor */ >+ .quad 0x00af9a000000ffff /* __KERNEL_CS */ >+ .quad 0x00cf92000000ffff /* __KERNEL_DS */ >+ .quad 0x0080890000000000 /* TS descriptor */ >+ .quad 0x0000000000000000 /* TS continued */ >+gdt_end: >+ >+ .balign 4096 >+pgtable: >+ .fill BOOT_PGT_SIZE, 1, 0 >+#endif >+ > #include "../../x86/xen/xen-head.S" > > __PAGE_ALIGNED_BSS >diff --git a/arch/x86/kernel/multiboot2.h >b/arch/x86/kernel/multiboot2.h >new file mode 100644 >index 0000000..03bb5d2 >--- /dev/null >+++ b/arch/x86/kernel/multiboot2.h >@@ -0,0 +1,417 @@ >+/* multiboot2.h - Multiboot 2 header file. */ >+/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software >Foundation, Inc. >+ * >+ * Permission is hereby granted, free of charge, to any person >obtaining a copy >+ * of this software and associated documentation files (the >"Software"), to >+ * deal in the Software without restriction, including without >limitation the >+ * rights to use, copy, modify, merge, publish, distribute, >sublicense, and/or >+ * sell copies of the Software, and to permit persons to whom the >Software is >+ * furnished to do so, subject to the following conditions: >+ * >+ * The above copyright notice and this permission notice shall be >included in >+ * all copies or substantial portions of the Software. >+ * >+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, >EXPRESS OR >+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF >MERCHANTABILITY, >+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT >SHALL ANY >+ * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER >LIABILITY, >+ * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, >OUT OF OR >+ * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN >THE SOFTWARE. >+ */ >+ >+#ifndef _ARCH_X86_KERNEL_MULTIBOOT2 >+#define _ARCH_X86_KERNEL_MULTIBOOT2 >+ >+/* How many bytes from the start of the file we search for the header. > */ >+#define MULTIBOOT_SEARCH 32768 >+#define MULTIBOOT_HEADER_ALIGN 8 >+ >+/* The magic field should contain this. */ >+#define MULTIBOOT2_HEADER_MAGIC 0xe85250d6 >+ >+/* This should be in %eax. */ >+#define MULTIBOOT2_BOOTLOADER_MAGIC 0x36d76289 >+ >+/* Alignment of multiboot modules. */ >+#define MULTIBOOT_MOD_ALIGN 0x00001000 >+ >+/* Alignment of the multiboot info structure. */ >+#define MULTIBOOT_INFO_ALIGN 0x00000008 >+ >+/* Flags set in the 'flags' member of the multiboot header. */ >+ >+#define MULTIBOOT_TAG_ALIGN 8 >+#define MULTIBOOT_TAG_TYPE_END 0 >+#define MULTIBOOT_TAG_TYPE_CMDLINE 1 >+#define MULTIBOOT_TAG_TYPE_BOOT_LOADER_NAME 2 >+#define MULTIBOOT_TAG_TYPE_MODULE 3 >+#define MULTIBOOT_TAG_TYPE_BASIC_MEMINFO 4 >+#define MULTIBOOT_TAG_TYPE_BOOTDEV 5 >+#define MULTIBOOT_TAG_TYPE_MMAP 6 >+#define MULTIBOOT_TAG_TYPE_VBE 7 >+#define MULTIBOOT_TAG_TYPE_FRAMEBUFFER 8 >+#define MULTIBOOT_TAG_TYPE_ELF_SECTIONS 9 >+#define MULTIBOOT_TAG_TYPE_APM 10 >+#define MULTIBOOT_TAG_TYPE_EFI32 11 >+#define MULTIBOOT_TAG_TYPE_EFI64 12 >+#define MULTIBOOT_TAG_TYPE_SMBIOS 13 >+#define MULTIBOOT_TAG_TYPE_ACPI_OLD 14 >+#define MULTIBOOT_TAG_TYPE_ACPI_NEW 15 >+#define MULTIBOOT_TAG_TYPE_NETWORK 16 >+#define MULTIBOOT_TAG_TYPE_EFI_MMAP 17 >+#define MULTIBOOT_TAG_TYPE_EFI_BS 18 >+#define MULTIBOOT_TAG_TYPE_EFI32_IH 19 >+#define MULTIBOOT_TAG_TYPE_EFI64_IH 20 >+#define MULTIBOOT_TAG_TYPE_LOAD_BASE_ADDR 21 >+ >+#define MULTIBOOT_HEADER_TAG_END 0 >+#define MULTIBOOT_HEADER_TAG_INFORMATION_REQUEST 1 >+#define MULTIBOOT_HEADER_TAG_ADDRESS 2 >+#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS 3 >+#define MULTIBOOT_HEADER_TAG_CONSOLE_FLAGS 4 >+#define MULTIBOOT_HEADER_TAG_FRAMEBUFFER 5 >+#define MULTIBOOT_HEADER_TAG_MODULE_ALIGN 6 >+#define MULTIBOOT_HEADER_TAG_EFI_BS 7 >+#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI32 8 >+#define MULTIBOOT_HEADER_TAG_ENTRY_ADDRESS_EFI64 9 >+#define MULTIBOOT_HEADER_TAG_RELOCATABLE 10 >+ >+#define MULTIBOOT_ARCHITECTURE_I386 0 >+#define MULTIBOOT_ARCHITECTURE_MIPS32 4 >+#define MULTIBOOT_HEADER_TAG_OPTIONAL 1 >+ >+#define MULTIBOOT_LOAD_PREFERENCE_NONE 0 >+#define MULTIBOOT_LOAD_PREFERENCE_LOW 1 >+#define MULTIBOOT_LOAD_PREFERENCE_HIGH 2 >+ >+#define MULTIBOOT_CONSOLE_FLAGS_CONSOLE_REQUIRED 1 >+#define MULTIBOOT_CONSOLE_FLAGS_EGA_TEXT_SUPPORTED 2 >+ >+#ifndef __ASSEMBLY__ >+ >+typedef unsigned char multiboot_uint8_t; >+typedef unsigned short multiboot_uint16_t; >+typedef unsigned int multiboot_uint32_t; >+typedef unsigned long long multiboot_uint64_t; >+ >+struct multiboot_header >+{ >+ /* Must be MULTIBOOT_MAGIC - see above. */ >+ multiboot_uint32_t magic; >+ >+ /* ISA */ >+ multiboot_uint32_t architecture; >+ >+ /* Total header length. */ >+ multiboot_uint32_t header_length; >+ >+ /* The above fields plus this one must equal 0 mod 2^32. */ >+ multiboot_uint32_t checksum; >+}; >+ >+struct multiboot_header_tag >+{ >+ multiboot_uint16_t type; >+ multiboot_uint16_t flags; >+ multiboot_uint32_t size; >+}; >+ >+struct multiboot_header_tag_information_request >+{ >+ multiboot_uint16_t type; >+ multiboot_uint16_t flags; >+ multiboot_uint32_t size; >+ multiboot_uint32_t requests[0]; >+}; >+ >+struct multiboot_header_tag_address >+{ >+ multiboot_uint16_t type; >+ multiboot_uint16_t flags; >+ multiboot_uint32_t size; >+ multiboot_uint32_t header_addr; >+ multiboot_uint32_t load_addr; >+ multiboot_uint32_t load_end_addr; >+ multiboot_uint32_t bss_end_addr; >+}; >+ >+struct multiboot_header_tag_entry_address >+{ >+ multiboot_uint16_t type; >+ multiboot_uint16_t flags; >+ multiboot_uint32_t size; >+ multiboot_uint32_t entry_addr; >+}; >+ >+struct multiboot_header_tag_console_flags >+{ >+ multiboot_uint16_t type; >+ multiboot_uint16_t flags; >+ multiboot_uint32_t size; >+ multiboot_uint32_t console_flags; >+}; >+ >+struct multiboot_header_tag_framebuffer >+{ >+ multiboot_uint16_t type; >+ multiboot_uint16_t flags; >+ multiboot_uint32_t size; >+ multiboot_uint32_t width; >+ multiboot_uint32_t height; >+ multiboot_uint32_t depth; >+}; >+ >+struct multiboot_header_tag_module_align >+{ >+ multiboot_uint16_t type; >+ multiboot_uint16_t flags; >+ multiboot_uint32_t size; >+}; >+ >+struct multiboot_header_tag_relocatable >+{ >+ multiboot_uint16_t type; >+ multiboot_uint16_t flags; >+ multiboot_uint32_t size; >+ multiboot_uint32_t min_addr; >+ multiboot_uint32_t max_addr; >+ multiboot_uint32_t align; >+ multiboot_uint32_t preference; >+}; >+ >+struct multiboot_color >+{ >+ multiboot_uint8_t red; >+ multiboot_uint8_t green; >+ multiboot_uint8_t blue; >+}; >+ >+struct multiboot_mmap_entry >+{ >+ multiboot_uint64_t addr; >+ multiboot_uint64_t len; >+#define MULTIBOOT_MEMORY_AVAILABLE 1 >+#define MULTIBOOT_MEMORY_RESERVED 2 >+#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 >+#define MULTIBOOT_MEMORY_NVS 4 >+#define MULTIBOOT_MEMORY_BADRAM 5 >+ multiboot_uint32_t type; >+ multiboot_uint32_t zero; >+}; >+typedef struct multiboot_mmap_entry multiboot_memory_map_t; >+ >+struct multiboot_tag >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+}; >+ >+struct multiboot_tag_string >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ char string[0]; >+}; >+ >+struct multiboot_tag_module >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint32_t mod_start; >+ multiboot_uint32_t mod_end; >+ char cmdline[0]; >+}; >+ >+struct multiboot_tag_basic_meminfo >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint32_t mem_lower; >+ multiboot_uint32_t mem_upper; >+}; >+ >+struct multiboot_tag_bootdev >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint32_t biosdev; >+ multiboot_uint32_t slice; >+ multiboot_uint32_t part; >+}; >+ >+struct multiboot_tag_mmap >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint32_t entry_size; >+ multiboot_uint32_t entry_version; >+ struct multiboot_mmap_entry entries[0]; >+}; >+ >+struct multiboot_vbe_info_block >+{ >+ multiboot_uint8_t external_specification[512]; >+}; >+ >+struct multiboot_vbe_mode_info_block >+{ >+ multiboot_uint8_t external_specification[256]; >+}; >+ >+struct multiboot_tag_vbe >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ >+ multiboot_uint16_t vbe_mode; >+ multiboot_uint16_t vbe_interface_seg; >+ multiboot_uint16_t vbe_interface_off; >+ multiboot_uint16_t vbe_interface_len; >+ >+ struct multiboot_vbe_info_block vbe_control_info; >+ struct multiboot_vbe_mode_info_block vbe_mode_info; >+}; >+ >+struct multiboot_tag_framebuffer_common >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ >+ multiboot_uint64_t framebuffer_addr; >+ multiboot_uint32_t framebuffer_pitch; >+ multiboot_uint32_t framebuffer_width; >+ multiboot_uint32_t framebuffer_height; >+ multiboot_uint8_t framebuffer_bpp; >+#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 >+#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 >+#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 >+ multiboot_uint8_t framebuffer_type; >+ multiboot_uint16_t reserved; >+}; >+ >+struct multiboot_tag_framebuffer >+{ >+ struct multiboot_tag_framebuffer_common common; >+ >+ union >+ { >+ struct >+ { >+ multiboot_uint16_t framebuffer_palette_num_colors; >+ struct multiboot_color framebuffer_palette[0]; >+ }; >+ struct >+ { >+ multiboot_uint8_t framebuffer_red_field_position; >+ multiboot_uint8_t framebuffer_red_mask_size; >+ multiboot_uint8_t framebuffer_green_field_position; >+ multiboot_uint8_t framebuffer_green_mask_size; >+ multiboot_uint8_t framebuffer_blue_field_position; >+ multiboot_uint8_t framebuffer_blue_mask_size; >+ }; >+ }; >+}; >+ >+struct multiboot_tag_elf_sections >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint32_t num; >+ multiboot_uint32_t entsize; >+ multiboot_uint32_t shndx; >+ char sections[0]; >+}; >+ >+struct multiboot_tag_apm >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint16_t version; >+ multiboot_uint16_t cseg; >+ multiboot_uint32_t offset; >+ multiboot_uint16_t cseg_16; >+ multiboot_uint16_t dseg; >+ multiboot_uint16_t flags; >+ multiboot_uint16_t cseg_len; >+ multiboot_uint16_t cseg_16_len; >+ multiboot_uint16_t dseg_len; >+}; >+ >+struct multiboot_tag_efi32 >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint32_t pointer; >+}; >+ >+struct multiboot_tag_efi64 >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint64_t pointer; >+}; >+ >+struct multiboot_tag_smbios >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint8_t major; >+ multiboot_uint8_t minor; >+ multiboot_uint8_t reserved[6]; >+ multiboot_uint8_t tables[0]; >+}; >+ >+struct multiboot_tag_old_acpi >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint8_t rsdp[0]; >+}; >+ >+struct multiboot_tag_new_acpi >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint8_t rsdp[0]; >+}; >+ >+struct multiboot_tag_network >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint8_t dhcpack[0]; >+}; >+ >+struct multiboot_tag_efi_mmap >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint32_t descr_size; >+ multiboot_uint32_t descr_vers; >+ multiboot_uint8_t efi_mmap[0]; >+}; >+ >+struct multiboot_tag_efi32_ih >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint32_t pointer; >+}; >+ >+struct multiboot_tag_efi64_ih >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint64_t pointer; >+}; >+ >+struct multiboot_tag_load_base_addr >+{ >+ multiboot_uint32_t type; >+ multiboot_uint32_t size; >+ multiboot_uint32_t load_base_addr; >+}; >+ >+#endif /* __ASSEMBLY__ */ >+ >+#endif /* _ARCH_X86_KERNEL_MULTIBOOT2 */
As has been shown many times before, this is a really bad idea. Unless there is a real-life use case where this matters enormously, this is nacked with extreme prejudice. -- Sent from my Android device with K-9 Mail. Please excuse my brevity.