diff --git a/arch/x86/core/efi.c b/arch/x86/core/efi.c index e5470e6d8a3..64faeb9efa5 100644 --- a/arch/x86/core/efi.c +++ b/arch/x86/core/efi.c @@ -18,6 +18,10 @@ static uint64_t __aligned(64) efi_stack[1024]; struct efi_boot_arg *efi; +#ifdef CONFIG_DYNAMIC_BOOTARGS +__pinned_noinit char efi_bootargs[CONFIG_BOOTARGS_ARGS_BUFFER_SIZE]; +#endif + void *efi_get_acpi_rsdp(void) { if (efi == NULL) { @@ -169,3 +173,10 @@ int arch_printk_char_out(int c) return efi_console_putchar(c); } #endif + +#ifdef CONFIG_DYNAMIC_BOOTARGS +const char *get_bootargs(void) +{ + return efi_bootargs; +} +#endif /* CONFIG_DYNAMIC_BOOTARGS */ diff --git a/arch/x86/zefi/efi.h b/arch/x86/zefi/efi.h index a81f163c19a..d0773177132 100644 --- a/arch/x86/zefi/efi.h +++ b/arch/x86/zefi/efi.h @@ -619,6 +619,24 @@ struct efi_system_table { struct efi_configuration_table *ConfigurationTable; }; +#ifdef CONFIG_DYNAMIC_BOOTARGS +struct efi_loaded_image_protocol { + uint32_t Revision; + void *ParentHandle; + struct efi_system_table *SystemTable; + void *DeviceHandle; + void *FilePath; + void *Reserved; + uint32_t LoadOptionsSize; + void *LoadOptions; + void *ImageBase; + uint64_t ImageSize; + enum efi_memory_type ImageCodeType; + enum efi_memory_type ImageDataType; + efi_unload_image_t Unload; +}; +#endif /* CONFIG_DYNAMIC_BOOTARGS */ + #endif /* _ASMLANGUAGE */ #endif /* ZEPHYR_INCLUDE_ARCH_X86_EFI_H_ */ diff --git a/arch/x86/zefi/zefi.c b/arch/x86/zefi/zefi.c index 56d0701e79b..66a54b538b1 100644 --- a/arch/x86/zefi/zefi.c +++ b/arch/x86/zefi/zefi.c @@ -32,6 +32,14 @@ .Data4 = { 0xbc, 0x22, 0x00, 0x80, 0xc7, 0x3c, 0x88, 0x81 }, \ } +#define EFI_LOADED_IMAGE_PROTOCOL_GUID \ + { \ + .Data1 = 0x5b1b31a1, \ + .Data2 = 0x9562, \ + .Data3 = 0x11d2, \ + .Data4 = { 0x8e, 0x3f, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \ + } + /* The linker places this dummy last in the data memory. We can't use * traditional linker address symbols because we're relocatable; the * linker doesn't know what the runtime address will be. The compiler @@ -135,7 +143,9 @@ static void disable_hpet(void) */ uintptr_t __abi efi_entry(void *img_handle, struct efi_system_table *sys_tab) { +#ifndef CONFIG_DYNAMIC_BOOTARGS (void)img_handle; +#endif /* CONFIG_DYNAMIC_BOOTARGS */ efi = sys_tab; z_putchar = efi_putchar; @@ -180,6 +190,30 @@ uintptr_t __abi efi_entry(void *img_handle, struct efi_system_table *sys_tab) } } +#ifdef CONFIG_DYNAMIC_BOOTARGS + char *dst_bootargs = (char *)zefi_bootargs; + struct efi_loaded_image_protocol *loaded_image; + efi_guid_t loaded_image_protocol = EFI_LOADED_IMAGE_PROTOCOL_GUID; + efi_status_t loaded_image_status = sys_tab->BootServices->HandleProtocol( + img_handle, + &loaded_image_protocol, + (void **)&loaded_image + ); + + if (loaded_image_status == EFI_SUCCESS) { + uint16_t *src_bootargs = (uint16_t *)loaded_image->LoadOptions; + + while (*src_bootargs != '\0' && + dst_bootargs + 1 < + (char *)zefi_bootargs + CONFIG_BOOTARGS_ARGS_BUFFER_SIZE) { + *dst_bootargs++ = *src_bootargs++ & 0x7f; + } + *dst_bootargs = '\0'; + } else { + *dst_bootargs = '\0'; + } +#endif /* CONFIG_DYNAMIC_BOOTARGS */ + unsigned char *code = (void *)zefi_entry; efi_arg.efi_systab = efi; diff --git a/arch/x86/zefi/zefi.py b/arch/x86/zefi/zefi.py index 99c188ecd08..2f9c3482bb4 100755 --- a/arch/x86/zefi/zefi.py +++ b/arch/x86/zefi/zefi.py @@ -8,6 +8,9 @@ import elftools.elf.elffile import argparse ENTRY_SYM = "__start64" +BOOTARGS_SYM = "efi_bootargs" + +args = None def verbose(msg): if args.verbose: @@ -93,6 +96,9 @@ def build_elf(elf_file, include_dirs): cf.write("static uintptr_t zefi_entry = 0x%xUL;\n" % (entry_addr)) + if symtab.get_symbol_by_name(BOOTARGS_SYM): + cf.write("static uintptr_t zefi_bootargs = 0x%xUL;\n" % (symtab.get_symbol_by_name(BOOTARGS_SYM)[0].entry.st_value)) + cf.close() verbose("Metadata header generated.") diff --git a/kernel/Kconfig b/kernel/Kconfig index 4370443fd4f..27a8fbbb3fd 100644 --- a/kernel/Kconfig +++ b/kernel/Kconfig @@ -1005,7 +1005,7 @@ config BOOTARGS config DYNAMIC_BOOTARGS bool "Support dynamic bootargs" - depends on BOOTARGS && MULTIBOOT_INFO + depends on BOOTARGS && (MULTIBOOT_INFO || BUILD_OUTPUT_EFI) help Enables dynamic bootargs support.