[Concept,13/20] efi: Add a command to help with shim

Message ID 20250828020732.981415-14-sjg@u-boot.org
State New
Headers
Series efi: App and devicetree improvements |

Commit Message

Simon Glass Aug. 28, 2025, 2:07 a.m. UTC
  From: Simon Glass <sjg@chromium.org>

Shim is a program which normally comes before U-Boot in the boot
process. But when the app runs first, it can sometimes chain Shim since
that is what is contained within the bootaa64.efi file, for example.

Add a simple command for dealing with shim. For now it only supports
enabling verbosity.

Co-developed-by: Claude <noreply@anthropic.com>
Signed-off-by: Simon Glass <sjg@chromium.org>
---

 cmd/Kconfig            |   9 ++++
 cmd/Makefile           |   1 +
 cmd/shim.c             |  65 ++++++++++++++++++++++++++
 doc/usage/cmd/shim.rst | 101 +++++++++++++++++++++++++++++++++++++++++
 doc/usage/index.rst    |   1 +
 include/efi.h          |   3 ++
 include/efi_api.h      |   4 ++
 include/shim.h         |  13 ++++++
 lib/efi/device_path.c  |   2 +
 9 files changed, 199 insertions(+)
 create mode 100644 cmd/shim.c
 create mode 100644 doc/usage/cmd/shim.rst
 create mode 100644 include/shim.h
  

Patch

diff --git a/cmd/Kconfig b/cmd/Kconfig
index 99101ff6c82..6a3ef56b3b9 100644
--- a/cmd/Kconfig
+++ b/cmd/Kconfig
@@ -547,6 +547,15 @@  config SYS_XIMG_LEN
 	  It should be large enough to fit uncompressed size of
 	  FIT piece we are extracting.
 
+config CMD_SHIM
+	bool "shim"
+	depends on CMD_NVEDIT_EFI
+	default y if SANDBOX || EFI_APP
+	help
+	  Provides a few commands for dealing with Shim being in the boot
+	  chain. This can be useful when debugging booting, particularly on
+	  x86 machines.
+
 config CMD_SPL
 	bool "spl export - Export boot information for Falcon boot"
 	depends on SPL
diff --git a/cmd/Makefile b/cmd/Makefile
index 407056b778b..bc381905729 100644
--- a/cmd/Makefile
+++ b/cmd/Makefile
@@ -174,6 +174,7 @@  obj-$(CONFIG_CMD_SHA1SUM) += sha1sum.o
 obj-$(CONFIG_CMD_SEAMA) += seama.o
 obj-$(CONFIG_CMD_SETEXPR) += setexpr.o
 obj-$(CONFIG_CMD_SETEXPR_FMT) += printf.o
+obj-$(CONFIG_CMD_SHIM) += shim.o
 obj-$(CONFIG_CMD_SPI) += spi.o
 obj-$(CONFIG_CMD_STRINGS) += strings.o
 obj-$(CONFIG_CMD_SMBIOS) += smbios.o
diff --git a/cmd/shim.c b/cmd/shim.c
new file mode 100644
index 00000000000..903f1823f19
--- /dev/null
+++ b/cmd/shim.c
@@ -0,0 +1,65 @@ 
+// SPDX-License-Identifier: GPL-2.0+
+/*
+ * Control of settings for Shim
+ *
+ * Copyright 2025 Simon Glass <sjg@chromium.org>
+ */
+
+#define __efi_runtime
+
+#include <abuf.h>
+#include <command.h>
+#include <efi.h>
+#include <efi_variable.h>
+#include <errno.h>
+#include <shim.h>
+#include <vsprintf.h>
+
+static int do_shim_debug(struct cmd_tbl *cmdtp, int flag, int argc,
+			 char *const argv[])
+{
+	efi_status_t eret;
+	struct abuf buf;
+	const char *sub;
+	u32 value;
+	int ret;
+
+	sub = cmd_arg1(argc, argv);
+	if (!sub) {
+		ret = efi_read_var(SHIM_VERBOSE_VAR_NAME, &efi_shim_lock, NULL,
+				   &buf, NULL);
+		if (ret == -ENOENT) {
+			value = 0;
+		} else if (ret) {
+			printf("Failed to read variable (err=%dE)\n", ret);
+			goto fail;
+		} else if (buf.size != sizeof(value)) {
+			printf("Invalid value size %zd\n", buf.size);
+			goto fail;
+		} else {
+			value = *(typeof(value) *)buf.data;
+		}
+		printf("%d\n", value);
+	} else {
+		value = hextoul(sub, NULL) ? 1 : 0;
+		eret = efi_set_variable_int(SHIM_VERBOSE_VAR_NAME,
+					    &efi_shim_lock,
+					    EFI_VARIABLE_BOOTSERVICE_ACCESS,
+					    sizeof(value), &value, false);
+		if (eret) {
+			printf("Failed to write variable (err=%lx)\n", eret);
+			goto fail;
+		}
+	}
+
+	return 0;
+
+fail:
+	return 1;
+}
+
+U_BOOT_LONGHELP(shim,
+	"debug [<0/1>]  - Enable / disable debug verbose mode");
+
+U_BOOT_CMD_WITH_SUBCMDS(shim, "Shim utilities", shim_help_text,
+	U_BOOT_SUBCMD_MKENT(debug, 3, 1, do_shim_debug));
diff --git a/doc/usage/cmd/shim.rst b/doc/usage/cmd/shim.rst
new file mode 100644
index 00000000000..285dd200558
--- /dev/null
+++ b/doc/usage/cmd/shim.rst
@@ -0,0 +1,101 @@ 
+.. SPDX-License-Identifier: GPL-2.0+
+
+shim command
+============
+
+Synopsis
+--------
+
+::
+
+    shim debug [<0/1>]
+
+Description
+-----------
+
+The ``shim`` command provides utilities for controlling and configuring the
+UEFI Shim bootloader when U-Boot is running as an EFI application. Shim is a
+UEFI bootloader that is used to verify and boot signed operating system
+loaders, commonly used in secure boot environments.
+
+The ``shim debug`` subcommand manages the Shim verbose debugging mode through
+the ``SHIM_VERBOSE`` EFI variable.
+
+Subcommands
+~~~~~~~~~~~
+
+shim debug
+^^^^^^^^^^
+
+Controls the Shim verbose debugging mode.
+
+**Usage:**
+
+::
+
+    shim debug          # Display current debug state (0 or 1)
+    shim debug 0        # Disable verbose debugging
+    shim debug 1        # Enable verbose debugging
+
+The command reads from or writes to the ``SHIM_VERBOSE`` EFI variable in the
+Shim Lock GUID namespace. When verbose mode is enabled (value = 1), Shim will
+output additional debugging information during the boot process. When disabled
+(value = 0 or variable doesn't exist), Shim operates silently.
+
+**Parameters:**
+
+* ``<0/1>`` - Optional parameter to set debug mode:
+
+  * ``0`` - Disable verbose debugging
+  * ``1`` - Enable verbose debugging
+  * If omitted, displays current debug state
+
+**Return value:**
+
+The command returns 0 on success, 1 on failure.
+
+**Examples:**
+
+Check current debug state::
+
+    => shim debug
+    0
+
+Enable verbose debugging::
+
+    => shim debug 1
+
+Disable verbose debugging::
+
+    => shim debug 0
+
+Configuration
+~~~~~~~~~~~~~
+
+The shim command is available when:
+
+* ``CONFIG_CMD_SHIM`` is enabled
+* U-Boot is running as an EFI application
+* EFI-variable support is available
+
+Implementation Details
+~~~~~~~~~~~~~~~~~~~~~~
+
+The command uses the EFI variable services to read and write the
+``SHIM_VERBOSE`` variable with the following characteristics:
+
+* **Variable Name:** ``SHIM_VERBOSE`` (Unicode string)
+* **GUID:** EFI Shim Lock GUID (``605dab50-e046-4300-abb6-3dd810dd8b23``)
+* **Attributes:** ``EFI_VARIABLE_BOOTSERVICE_ACCESS``
+* **Data Type:** 32-bit unsigned integer (4 bytes)
+* **Values:** 0 (disabled) or 1 (enabled)
+
+The variable is stored in the EFI variable store and persists across reboots
+until explicitly changed or the variable store is cleared.
+
+See Also
+~~~~~~~~
+
+* :doc:`efidebug` - EFI debugging utilities
+* :doc:`bootefi` - Boot EFI applications
+* :doc:`/develop/uefi/u-boot_on_efi`
diff --git a/doc/usage/index.rst b/doc/usage/index.rst
index 585aa3f9784..3b45d443d5c 100644
--- a/doc/usage/index.rst
+++ b/doc/usage/index.rst
@@ -115,6 +115,7 @@  Shell commands
    cmd/seama
    cmd/setexpr
    cmd/sf
+   cmd/shim
    cmd/size
    cmd/sleep
    cmd/sm
diff --git a/include/efi.h b/include/efi.h
index 07d07050c01..2ca7cc30d52 100644
--- a/include/efi.h
+++ b/include/efi.h
@@ -163,6 +163,9 @@  extern const efi_guid_t efi_guid_component_name2;
 /* GUIDs for authentication - most of these are still in efi_loader.h */
 extern const efi_guid_t efi_guid_image_security_database;
 
+/* Access to Shim variables */
+extern const efi_guid_t efi_shim_lock;
+
 /* Generic EFI table header */
 struct efi_table_hdr {
 	u64 signature;
diff --git a/include/efi_api.h b/include/efi_api.h
index b3f6172e97a..00a9d29b8fe 100644
--- a/include/efi_api.h
+++ b/include/efi_api.h
@@ -487,6 +487,10 @@  struct efi_runtime_services {
 	EFI_GUID(0x6a7a5cff, 0xe8d9, 0x4f70, \
 		 0xba, 0xda, 0x75, 0xab, 0x30, 0x25, 0xce, 0x14)
 
+#define EFI_SHIM_LOCK_GUID \
+	EFI_GUID(0x605dab50, 0xe046, 0x4300, \
+		 0xab, 0xb6, 0x3d, 0xd8, 0x10, 0xdd, 0x8b, 0x23)
+
 /**
  * struct efi_configuration_table - EFI Configuration Table
  *
diff --git a/include/shim.h b/include/shim.h
new file mode 100644
index 00000000000..23061398933
--- /dev/null
+++ b/include/shim.h
@@ -0,0 +1,13 @@ 
+/* SPDX-License-Identifier: GPL-2.0+ */
+/*
+ * Shim features and settings
+ *
+ * Copyright 2025 Simon Glass <sjg@chromium.org>
+ */
+
+#ifndef __SHIM_H
+#define __SHIM_H
+
+#define SHIM_VERBOSE_VAR_NAME	L"SHIM_VERBOSE"
+
+#endif
diff --git a/lib/efi/device_path.c b/lib/efi/device_path.c
index bae9e5c537a..b09ea030341 100644
--- a/lib/efi/device_path.c
+++ b/lib/efi/device_path.c
@@ -43,6 +43,8 @@  const efi_guid_t efi_guid_component_name2 = EFI_COMPONENT_NAME2_PROTOCOL_GUID;
 const efi_guid_t efi_guid_image_security_database =
 		EFI_IMAGE_SECURITY_DATABASE_GUID;
 
+const efi_guid_t efi_shim_lock = EFI_SHIM_LOCK_GUID;
+
 /* template EFI_DP_END node: */
 const struct efi_device_path EFI_DP_END = {
 	.type     = DEVICE_PATH_TYPE_END,