diff --git a/hypervisor/arch/x86/Kconfig b/hypervisor/arch/x86/Kconfig index 776d9c891..856c3088f 100644 --- a/hypervisor/arch/x86/Kconfig +++ b/hypervisor/arch/x86/Kconfig @@ -39,6 +39,7 @@ endchoice config MULTIBOOT2 bool "Multiboot2 support" + depends on RELOC default n help Support boot ACRN from multiboot2 protocol. Multiboot2 support is needed for diff --git a/hypervisor/arch/x86/boot/cpu_primary.S b/hypervisor/arch/x86/boot/cpu_primary.S index dddc68688..4879c2bdd 100644 --- a/hypervisor/arch/x86/boot/cpu_primary.S +++ b/hypervisor/arch/x86/boot/cpu_primary.S @@ -56,23 +56,65 @@ mb2_header_start: /* please be aware that each tag should be 8 bytes aligned */ .align MULTIBOOT2_TAG_ALIGN + /* + * Request infomation from boot loader, which is supposed to provide th relevant information + * specified in the following tags to the image through the MBI if it is available + */ info_req_tag_start: .short MULTIBOOT2_HEADER_TAG_INFORMATION_REQUEST .short 0 .long info_req_tag_end - info_req_tag_start - .long MULTIBOOT2_TAG_TYPE_MMAP - .long MULTIBOOT2_TAG_TYPE_MODULE - .long MULTIBOOT2_TAG_TYPE_ACPI_NEW - .long MULTIBOOT2_TAG_TYPE_EFI64 - .long MULTIBOOT2_TAG_TYPE_EFI_MMAP + .long MULTIBOOT2_TAG_TYPE_MMAP /* memory map */ + .long MULTIBOOT2_TAG_TYPE_MODULE /* boot modules infomation */ + .long MULTIBOOT2_TAG_TYPE_ACPI_NEW /* a copy of RSDP as defined per ACPI 2.0 or later specification */ + .long MULTIBOOT2_TAG_TYPE_EFI64 /* EFI system table, to be passed to guest Linux */ + .long MULTIBOOT2_TAG_TYPE_EFI_MMAP /* EFI memory map, to be passed to guest Linux */ info_req_tag_end: + .align MULTIBOOT2_TAG_ALIGN +address_tag_start: + .short MULTIBOOT2_HEADER_TAG_ADDRESS + .short 0 + .long address_tag_end - address_tag_start + .long mb2_header_start /* address corresponding to the beginning of the Multiboot2 header */ + .long -1 /* load_addr: the file to be loaded from its beginning */ + /* + * load_end_addr: this includes .bss so that boot loader could reserve the + * memory that .bss occupies to avoid placing boot modules or other data in that area. + * + * However, the boot loader is supposed not to actually load the .bss section because + * it's beyond the scope of acrn.bin + */ + .long _ld_ram_end + .long 0 /* bss_end_addr, don't ask boot loader to clear .bss */ +address_tag_end: + + .align MULTIBOOT2_TAG_ALIGN +entry_address_tag_start: + .short MULTIBOOT2_HEADER_TAG_ENTRY_ADDRESS + .short 0 + .long entry_address_tag_end - entry_address_tag_start + .long cpu_primary_start_32 /* The address to which the boot loader should jump to start hypervisor */ +entry_address_tag_end: + + .align MULTIBOOT2_TAG_ALIGN +relocatable_tag_start: + .short MULTIBOOT2_HEADER_TAG_RELOCATABLE + .short 0 + .long relocatable_tag_end - relocatable_tag_start + .long 0x10000000 /* min_addr. TODO: change it to 2MB after fixing the load_addr issue */ + .long 0x80000000 /* max_addr */ + .long 0x200000 /* image alignment */ + .long 1 /* preference: lowest possible address */ +relocatable_tag_end: + .align MULTIBOOT2_TAG_ALIGN .short MULTIBOOT2_HEADER_TAG_END .short 0 .long 8 mb2_header_end: #endif + .section entry, "ax" .align 8 diff --git a/hypervisor/boot/include/boot.h b/hypervisor/boot/include/boot.h index ac7e7133d..65559ee6b 100644 --- a/hypervisor/boot/include/boot.h +++ b/hypervisor/boot/include/boot.h @@ -53,7 +53,16 @@ static inline bool boot_from_multiboot1(void) #ifdef CONFIG_MULTIBOOT2 static inline bool boot_from_multiboot2(void) { - return ((boot_regs[0] == MULTIBOOT2_INFO_MAGIC) && (boot_regs[1] != 0U)); + /* + * Multiboot spec states that the Multiboot information structure may be placed + * anywhere in memory by the boot loader. + * + * Seems both SBL and GRUB won't place multiboot1 MBI structure at 0 address, + * but GRUB could place Multiboot2 MBI structure at 0 address until commit + * 0f3f5b7c13fa9b67 ("multiboot2: Set min address for mbi allocation to 0x1000") + * which dates on Dec 26 2019. + */ + return (boot_regs[0] == MULTIBOOT2_INFO_MAGIC); } int32_t multiboot2_to_acrn_mbi(struct acrn_multiboot_info *mbi, void *mb2_info);