d7945289e5
the preboot loader for UEFI secureboot OBS-URL: https://build.opensuse.org/request/show/148684 OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/shim?expand=0&rev=1
124 lines
3.4 KiB
Diff
124 lines
3.4 KiB
Diff
commit 940425a8bce6bf1b556dc48189884b4a82d8d420
|
|
Author: Gary Ching-Pang Lin <glin@suse.com>
|
|
Date: Thu Dec 6 17:47:26 2012 +0800
|
|
|
|
Get the second stage loader from the Load Options
|
|
|
|
This commit replaces the 2nd stage loader path with the first
|
|
argument in the Load Options and moves the rest arguments (if any)
|
|
to the Load Options for the 2nd stage loader.
|
|
|
|
For example, to make shim to load elilo.efi, just create a new
|
|
boot entry with efibootmgr:
|
|
|
|
# efibootmgr -c -L "shim elilo" -l "efi\\shim.efi" -u "elilo.efi"
|
|
|
|
diff --git a/shim.c b/shim.c
|
|
index c3aae9e..44301dd 100644
|
|
--- a/shim.c
|
|
+++ b/shim.c
|
|
@@ -42,12 +42,16 @@
|
|
#include "netboot.h"
|
|
#include "shim_cert.h"
|
|
|
|
-#define SECOND_STAGE L"\\grub.efi"
|
|
+#define DEFAULT_LOADER L"\\grub.efi"
|
|
#define MOK_MANAGER L"\\MokManager.efi"
|
|
|
|
static EFI_SYSTEM_TABLE *systab;
|
|
static EFI_STATUS (EFIAPI *entry_point) (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *system_table);
|
|
|
|
+static CHAR16 *second_stage;
|
|
+static void *load_options;
|
|
+static UINT32 load_options_size;
|
|
+
|
|
/*
|
|
* The vendor certificate used for validating the second stage loader
|
|
*/
|
|
@@ -881,6 +885,10 @@ static EFI_STATUS handle_image (void *data, unsigned int datasize,
|
|
li->ImageBase = buffer;
|
|
li->ImageSize = context.ImageSize;
|
|
|
|
+ /* Pass the load options to the second stage loader */
|
|
+ li->LoadOptions = load_options;
|
|
+ li->LoadOptionsSize = load_options_size;
|
|
+
|
|
if (!entry_point) {
|
|
Print(L"Invalid entry point\n");
|
|
FreePool(buffer);
|
|
@@ -1192,7 +1200,7 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle)
|
|
{
|
|
EFI_STATUS efi_status;
|
|
|
|
- efi_status = start_image(image_handle, SECOND_STAGE);
|
|
+ efi_status = start_image(image_handle, second_stage);
|
|
|
|
if (efi_status != EFI_SUCCESS)
|
|
efi_status = start_image(image_handle, MOK_MANAGER);
|
|
@@ -1312,6 +1320,55 @@ static EFI_STATUS check_mok_sb (void)
|
|
return status;
|
|
}
|
|
|
|
+/*
|
|
+ * Check the load options to specify the second stage loader
|
|
+ */
|
|
+EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
|
|
+{
|
|
+ EFI_STATUS status;
|
|
+ EFI_LOADED_IMAGE *li;
|
|
+ CHAR16 *start = NULL, *c;
|
|
+ int i, remaining_size = 0;
|
|
+
|
|
+ second_stage = DEFAULT_LOADER;
|
|
+ load_options = NULL;
|
|
+ load_options_size = 0;
|
|
+
|
|
+ status = uefi_call_wrapper(BS->HandleProtocol, 3, image_handle,
|
|
+ &LoadedImageProtocol, (void **) &li);
|
|
+ if (status != EFI_SUCCESS) {
|
|
+ Print (L"Failed to get load options\n");
|
|
+ return status;
|
|
+ }
|
|
+
|
|
+ /* Expect a CHAR16 string with at least one CHAR16 */
|
|
+ if (li->LoadOptionsSize < 4 || li->LoadOptionsSize % 2 != 0) {
|
|
+ return EFI_BAD_BUFFER_SIZE;
|
|
+ }
|
|
+ c = (CHAR16 *)(li->LoadOptions + (li->LoadOptionsSize - 2));
|
|
+ if (*c != L'\0') {
|
|
+ return EFI_BAD_BUFFER_SIZE;
|
|
+ }
|
|
+
|
|
+ for (i = 0; i < li->LoadOptionsSize; i += 2) {
|
|
+ c = (CHAR16 *)(li->LoadOptions + i);
|
|
+ if (*c == L' ') {
|
|
+ *c = L'\0';
|
|
+ start = c + 1;
|
|
+ remaining_size = li->LoadOptionsSize - i - 2;
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ second_stage = (CHAR16 *)li->LoadOptions;
|
|
+ if (start && remaining_size > 0) {
|
|
+ load_options = start;
|
|
+ load_options_size = remaining_size;
|
|
+ }
|
|
+
|
|
+ return EFI_SUCCESS;
|
|
+}
|
|
+
|
|
EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
|
{
|
|
EFI_GUID shim_lock_guid = SHIM_LOCK_GUID;
|
|
@@ -1334,6 +1391,9 @@ EFI_STATUS efi_main (EFI_HANDLE image_handle, EFI_SYSTEM_TABLE *passed_systab)
|
|
*/
|
|
InitializeLib(image_handle, systab);
|
|
|
|
+ /* Set the second stage loader */
|
|
+ set_second_stage (image_handle);
|
|
+
|
|
/*
|
|
* Check whether the user has configured the system to run in
|
|
* insecure mode
|