[U-Boot] [PATCH 3/4] x86: zimage: Support booting Linux kernel from an EFI payload

Bin Meng bmeng.cn at gmail.com
Thu Aug 23 15:24:10 UTC 2018


At present Linux kernel loaded from U-Boot as an EFI payload does
not boot. This fills in kernel's boot params structure with the
required critical EFI information like system table address and
memory map stuff so that kernel can obtain essential data like
runtime services and ACPI table to boot.

With this patch, now U-Boot as an EFI payload becomes much more
practical: it is another option of kernel bootloader, ie, can be
a replacement for grub.

Signed-off-by: Bin Meng <bmeng.cn at gmail.com>
---

 arch/x86/cpu/efi/payload.c    | 37 +++++++++++++++++++++++++++++++++++++
 arch/x86/include/asm/zimage.h |  1 +
 arch/x86/lib/zimage.c         |  4 ++++
 include/efi.h                 |  3 +++
 4 files changed, 45 insertions(+)

diff --git a/arch/x86/cpu/efi/payload.c b/arch/x86/cpu/efi/payload.c
index 0e7c7c1..c323c7b 100644
--- a/arch/x86/cpu/efi/payload.c
+++ b/arch/x86/cpu/efi/payload.c
@@ -8,6 +8,7 @@
 #include <efi.h>
 #include <errno.h>
 #include <usb.h>
+#include <asm/bootparam.h>
 #include <asm/e820.h>
 #include <asm/post.h>
 
@@ -250,3 +251,39 @@ unsigned int install_e820_map(unsigned int max_entries,
 
 	return num_entries;
 }
+
+void setup_efi_info(struct efi_info *efi_info)
+{
+	struct efi_entry_systable *table;
+	struct efi_entry_memmap *map;
+	char *signature;
+	int size, ret;
+
+	memset(efi_info, 0, sizeof(struct efi_info));
+
+	ret = efi_info_get(EFIET_SYS_TABLE, (void **)&table, &size);
+	if (ret) {
+		printf("Cannot find EFI system table, ret=%d\n", ret);
+		return;
+	}
+	efi_info->efi_systab = (u32)(table->sys_table);
+
+	ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
+	if (ret) {
+		printf("Cannot find EFI memory map tables, ret=%d\n", ret);
+		return;
+	}
+	efi_info->efi_memdesc_size = map->desc_size;
+	efi_info->efi_memdesc_version = map->version;
+	efi_info->efi_memmap = (u32)(map->desc);
+	efi_info->efi_memmap_size = size - sizeof(struct efi_entry_memmap);
+
+#ifdef CONFIG_EFI_STUB_64BIT
+	efi_info->efi_systab_hi = table->sys_table >> 32;
+	efi_info->efi_memmap_hi = (u64)(u32)(map->desc) >> 32;
+	signature = EFI64_LOADER_SIGNATURE;
+#else
+	signature = EFI32_LOADER_SIGNATURE;
+#endif
+	memcpy(&efi_info->efi_loader_signature, signature, 4);
+}
diff --git a/arch/x86/include/asm/zimage.h b/arch/x86/include/asm/zimage.h
index 03bed54..80e128c 100644
--- a/arch/x86/include/asm/zimage.h
+++ b/arch/x86/include/asm/zimage.h
@@ -35,5 +35,6 @@ struct boot_params *load_zimage(char *image, unsigned long kernel_size,
 int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
 		 unsigned long initrd_addr, unsigned long initrd_size);
 void setup_video(struct screen_info *screen_info);
+void setup_efi_info(struct efi_info *efi_info);
 
 #endif
diff --git a/arch/x86/lib/zimage.c b/arch/x86/lib/zimage.c
index 04ed972..0442fda 100644
--- a/arch/x86/lib/zimage.c
+++ b/arch/x86/lib/zimage.c
@@ -295,6 +295,10 @@ int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
 	setup_device_tree(hdr, (const void *)env_get_hex("fdtaddr", 0));
 	setup_video(&setup_base->screen_info);
 
+#ifdef CONFIG_EFI_STUB
+	setup_efi_info(&setup_base->efi_info);
+#endif
+
 	return 0;
 }
 
diff --git a/include/efi.h b/include/efi.h
index 1dee606..0d74e70 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -41,6 +41,9 @@
 #define efi_va_end va_end
 #endif /* __x86_64__ */
 
+#define EFI32_LOADER_SIGNATURE	"EL32"
+#define EFI64_LOADER_SIGNATURE	"EL64"
+
 struct efi_device_path;
 
 typedef struct {
-- 
2.7.4



More information about the U-Boot mailing list