Commit 1fdeacd32c6335acb7bd5f00c3f177013d971d3d

Authored by Bin Meng
1 parent cbe503fbc1

x86: zimage: Support booting Linux kernel from an EFI payload

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@gmail.com>
Reviewed-by: Simon Glass <sjg@chromium.org>

Showing 4 changed files with 45 additions and 0 deletions Side-by-side Diff

arch/x86/cpu/efi/payload.c
... ... @@ -8,6 +8,7 @@
8 8 #include <efi.h>
9 9 #include <errno.h>
10 10 #include <usb.h>
  11 +#include <asm/bootparam.h>
11 12 #include <asm/e820.h>
12 13 #include <asm/post.h>
13 14  
... ... @@ -249,5 +250,41 @@
249 250 }
250 251  
251 252 return num_entries;
  253 +}
  254 +
  255 +void setup_efi_info(struct efi_info *efi_info)
  256 +{
  257 + struct efi_entry_systable *table;
  258 + struct efi_entry_memmap *map;
  259 + char *signature;
  260 + int size, ret;
  261 +
  262 + memset(efi_info, 0, sizeof(struct efi_info));
  263 +
  264 + ret = efi_info_get(EFIET_SYS_TABLE, (void **)&table, &size);
  265 + if (ret) {
  266 + printf("Cannot find EFI system table, ret=%d\n", ret);
  267 + return;
  268 + }
  269 + efi_info->efi_systab = (u32)(table->sys_table);
  270 +
  271 + ret = efi_info_get(EFIET_MEMORY_MAP, (void **)&map, &size);
  272 + if (ret) {
  273 + printf("Cannot find EFI memory map tables, ret=%d\n", ret);
  274 + return;
  275 + }
  276 + efi_info->efi_memdesc_size = map->desc_size;
  277 + efi_info->efi_memdesc_version = map->version;
  278 + efi_info->efi_memmap = (u32)(map->desc);
  279 + efi_info->efi_memmap_size = size - sizeof(struct efi_entry_memmap);
  280 +
  281 +#ifdef CONFIG_EFI_STUB_64BIT
  282 + efi_info->efi_systab_hi = table->sys_table >> 32;
  283 + efi_info->efi_memmap_hi = (u64)(u32)(map->desc) >> 32;
  284 + signature = EFI64_LOADER_SIGNATURE;
  285 +#else
  286 + signature = EFI32_LOADER_SIGNATURE;
  287 +#endif
  288 + memcpy(&efi_info->efi_loader_signature, signature, 4);
252 289 }
arch/x86/include/asm/zimage.h
... ... @@ -35,6 +35,7 @@
35 35 int setup_zimage(struct boot_params *setup_base, char *cmd_line, int auto_boot,
36 36 unsigned long initrd_addr, unsigned long initrd_size);
37 37 void setup_video(struct screen_info *screen_info);
  38 +void setup_efi_info(struct efi_info *efi_info);
38 39  
39 40 #endif
arch/x86/lib/zimage.c
... ... @@ -295,6 +295,10 @@
295 295 setup_device_tree(hdr, (const void *)env_get_hex("fdtaddr", 0));
296 296 setup_video(&setup_base->screen_info);
297 297  
  298 +#ifdef CONFIG_EFI_STUB
  299 + setup_efi_info(&setup_base->efi_info);
  300 +#endif
  301 +
298 302 return 0;
299 303 }
300 304  
... ... @@ -41,6 +41,9 @@
41 41 #define efi_va_end va_end
42 42 #endif /* __x86_64__ */
43 43  
  44 +#define EFI32_LOADER_SIGNATURE "EL32"
  45 +#define EFI64_LOADER_SIGNATURE "EL64"
  46 +
44 47 struct efi_device_path;
45 48  
46 49 typedef struct {