diff options
-rw-r--r-- | src/efi/gummiboot.c | 19 | ||||
-rw-r--r-- | src/efi/pefile.c | 2 | ||||
-rw-r--r-- | src/efi/stub.c | 39 | ||||
-rwxr-xr-x | test/test-create-disk.sh | 4 |
4 files changed, 51 insertions, 13 deletions
diff --git a/src/efi/gummiboot.c b/src/efi/gummiboot.c index ff1226d..4e71ca6 100644 --- a/src/efi/gummiboot.c +++ b/src/efi/gummiboot.c @@ -1570,10 +1570,12 @@ static BOOLEAN config_entry_add_call(Config *config, CHAR16 *title, EFI_STATUS ( return TRUE; } -static ConfigEntry *config_entry_add_loader(Config *config, EFI_HANDLE *device, CHAR16 *file, CHAR16 key, CHAR16 *title, CHAR16 *loader) { +static ConfigEntry *config_entry_add_loader(Config *config, EFI_HANDLE *device, + enum loader_type type,CHAR16 *file, CHAR16 key, CHAR16 *title, CHAR16 *loader) { ConfigEntry *entry; entry = AllocateZeroPool(sizeof(ConfigEntry)); + entry->type = type; entry->title = StrDuplicate(title); entry->device = device; entry->loader = StrDuplicate(loader); @@ -1601,7 +1603,7 @@ static BOOLEAN config_entry_add_loader_auto(Config *config, EFI_HANDLE *device, return FALSE; uefi_call_wrapper(handle->Close, 1, handle); - entry = config_entry_add_loader(config, device, file, key, title, loader); + entry = config_entry_add_loader(config, device, LOADER_UNDEFINED, file, key, title, loader); if (!entry) return FALSE; @@ -1661,10 +1663,13 @@ static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_ima CHAR16 buf[256]; UINTN bufsize; EFI_FILE_INFO *f; - CHAR8 *sections[2] = { (UINT8 *)".osrel", NULL }; - UINTN offs[1] = {}; - UINTN szs[1] = {}; - UINTN addrs[1] = {}; + CHAR8 *sections[] = { + (UINT8 *)".osrel", + NULL + }; + UINTN offs[ELEMENTSOF(sections)-1] = {}; + UINTN szs[ELEMENTSOF(sections)-1] = {}; + UINTN addrs[ELEMENTSOF(sections)-1] = {}; CHAR8 *content = NULL; UINTN len; CHAR8 *line; @@ -1724,7 +1729,7 @@ static VOID config_entry_add_linux( Config *config, EFI_LOADED_IMAGE *loaded_ima conf = PoolPrint(L"%s-%s", os_id, os_version); path = PoolPrint(L"\\EFI\\Linux\\%s", f->FileName); - config_entry_add_loader(config, loaded_image->DeviceHandle, conf, 'l', os_name, path); + config_entry_add_loader(config, loaded_image->DeviceHandle, LOADER_LINUX, conf, 'l', os_name, path); FreePool(conf); FreePool(path); FreePool(os_name); diff --git a/src/efi/pefile.c b/src/efi/pefile.c index 5d750e0..e6fedbc 100644 --- a/src/efi/pefile.c +++ b/src/efi/pefile.c @@ -154,7 +154,7 @@ EFI_STATUS pefile_locate_sections(EFI_FILE *dir, CHAR16 *path, CHAR8 **sections, goto out; } for (j = 0; sections[j]; j++) { - if (strcmpa(sections[j], sect.Name) != 0) + if (CompareMem(sect.Name, sections[j], strlena(sections[j])) != 0) continue; if (addrs) diff --git a/src/efi/stub.c b/src/efi/stub.c index c1be3d6..67a2661 100644 --- a/src/efi/stub.c +++ b/src/efi/stub.c @@ -20,19 +20,28 @@ #include "pefile.h" #include "linux.h" +/* magic string to find in the binary image */ +static const char __attribute__((used)) magic[] = "#### LoaderInfo: stub " VERSION " ####"; + +static const EFI_GUID global_guid = EFI_GLOBAL_VARIABLE; + EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { EFI_LOADED_IMAGE *loaded_image; EFI_FILE *root_dir; CHAR16 *loaded_image_path; + CHAR8 *b; + UINTN size; + BOOLEAN secure = TRUE; CHAR8 *sections[] = { (UINT8 *)".cmdline", (UINT8 *)".linux", (UINT8 *)".initrd", NULL }; - UINTN addrs[3] = {}; - UINTN offs[3] = {}; - UINTN szs[3] = {}; + UINTN addrs[ELEMENTSOF(sections)-1] = {}; + UINTN offs[ELEMENTSOF(sections)-1] = {}; + UINTN szs[ELEMENTSOF(sections)-1] = {}; + CHAR8 *cmdline = NULL; EFI_STATUS err; InitializeLib(image, sys_table); @@ -54,6 +63,12 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { loaded_image_path = DevicePathToStr(loaded_image->FilePath); + if (efivar_get_raw(&global_guid, L"SecureBoot", &b, &size) == EFI_SUCCESS) { + if (*b == 0) + secure = FALSE; + FreePool(b); + } + err = pefile_locate_sections(root_dir, loaded_image_path, sections, addrs, offs, szs); if (EFI_ERROR(err)) { Print(L"Unable to locate embedded .linux section: %r ", err); @@ -61,7 +76,23 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) { return err; } - err = linux_exec(image, (CHAR8 *)"", + if (szs[0] > 0) + cmdline = (CHAR8 *)(loaded_image->ImageBase + addrs[0]); + + /* if we are not in secure boot mode, accept a custom command line and replace the built-in one */ + if (!secure && loaded_image->LoadOptionsSize > 0) { + CHAR16 *options; + CHAR8 *line; + UINTN i; + + options = (CHAR16 *)loaded_image->LoadOptions; + line = AllocatePool((loaded_image->LoadOptionsSize / sizeof(CHAR16)) * sizeof(CHAR8)); + for (i = 0; i < loaded_image->LoadOptionsSize; i++) + line[i] = options[i]; + cmdline = line; + } + + err = linux_exec(image, cmdline, (UINTN)loaded_image->ImageBase + addrs[1], (UINTN)loaded_image->ImageBase + addrs[2], szs[2]); diff --git a/test/test-create-disk.sh b/test/test-create-disk.sh index 9fdb3c3..d8fe0d7 100755 --- a/test/test-create-disk.sh +++ b/test/test-create-disk.sh @@ -19,9 +19,11 @@ cp test/splash.bmp mnt/EFI/gummiboot/ [ -e /boot/shellx64.efi ] && cp /boot/shellx64.efi mnt/ mkdir mnt/EFI/Linux +echo "foo=yes bar=no debug" > mnt/cmdline.txt objcopy \ --add-section .osrel=/etc/os-release --change-section-vma .osrel=0x20000 \ - --add-section .linux=/boot/$(cat /etc/machine-id)/$(uname -r)/linux --change-section-vma .linux=0x30000 \ + --add-section .cmdline=mnt/cmdline.txt --change-section-vma .cmdline=0x30000 \ + --add-section .linux=/boot/$(cat /etc/machine-id)/$(uname -r)/linux --change-section-vma .linux=0x40000 \ --add-section .initrd=/boot/$(cat /etc/machine-id)/$(uname -r)/initrd --change-section-vma .initrd=0x3000000 \ stubx64.efi mnt/EFI/Linux/linux-test.efi |