[PATCH 1/2] blsuki: scan XBOOTLDR partition for BLS/UKIs if it exists

Radoslav Kolev via Grub-devel <[email protected]> Fri, 12 Dec 2025 11:00:49 +0200
Newsgroups org.gnu.grub-devel
Message-ID <[email protected]>
The default ESP partition on some systems is limited in
space and storing a number of kernel and initrd images
can fill it up quickly.

It's not always practical to increase the size of the
existing ESP, so the Boot Loader Spec defines a new Extended
Boot Loader Partition (XBOOTLDR) with GPT type GUID of
bc13c2ff-59e6-4262-a352-b275fd6f7172 to be searched for BLS
enties and UKIs in addition to the ESP.

see https://uapi-group.org/specifications/specs/boot_loader_specification/

Signed-off-by: Radoslav Kolev <[email protected]>
---
 grub-core/commands/blsuki.c  | 86 +++++++++++++++++++++++++++++++++---
 include/grub/gpt_partition.h |  7 +++
 2 files changed, 86 insertions(+), 7 deletions(-)

diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
index a169e3f59..db5ab3a5c 100644
--- a/grub-core/commands/blsuki.c
+++ b/grub-core/commands/blsuki.c
@@ -31,6 +31,7 @@
 #include <grub/safemath.h>
 #include <grub/lib/envblk.h>
 #include <filevercmp.h>
+#include <grub/gpt_partition.h>
 
 #ifdef GRUB_MACHINE_EFI
 #include <grub/efi/efi.h>
@@ -1245,6 +1246,33 @@ blsuki_find_entry (struct find_entry_info *info, bool enable_fallback, enum blsu
   return GRUB_ERR_NONE;
 }
 
+static const grub_guid_t xbootldr_type = GRUB_GPT_PARTITION_TYPE_XBOOTLDR;
+static int find_xbootldr_iter (grub_disk_t disk, const grub_partition_t p, void *data) {
+  char **xbootldr_part = data;
+  struct grub_gpt_partentry gptdata;
+  grub_partition_t p2;
+
+  grub_dprintf("blsuki","Checking part number %d index %d \n", p->number, p->index);
+
+  p2 = disk->partition;
+  disk->partition = p->parent;
+  if (grub_disk_read (disk, p->offset, p->index, sizeof (gptdata), &gptdata))
+    {
+      disk->partition = p2;
+      return 0;
+    }
+  disk->partition = p2;
+  grub_dprintf("blsuki","Gptdata.type:  %x %x %x %x\n", gptdata.type.data1, gptdata.type.data2, gptdata.type.data3, gptdata.type.data4[0]);
+  grub_dprintf("blsuki","XBOOTLDR.type:  %x %x %x %x\n", xbootldr_type.data1, xbootldr_type.data2, xbootldr_type.data3, xbootldr_type.data4[0]);
+  if (! grub_memcmp (&gptdata.type, &xbootldr_type, 16))
+    {
+      *xbootldr_part = grub_xasprintf("%s,%s", disk->name, grub_partition_get_name(p));
+      grub_dprintf("blsuki","XBOOTLDR found! setting name to %s\n", *xbootldr_part);
+      return 1;
+    }
+  return 0;
+}
+
 static grub_err_t
 blsuki_load_entries (char *path, bool enable_fallback, enum blsuki_cmd_type cmd_type)
 {
@@ -1257,6 +1285,7 @@ blsuki_load_entries (char *path, bool enable_fallback, enum blsuki_cmd_type cmd_
   const char *cmd_dir = NULL;
   grub_size_t dir_size;
   const char *ext = NULL;
+  char *xbootldr_part = NULL;
   struct find_entry_info info = {
       .dev = NULL,
       .fs = NULL,
@@ -1329,16 +1358,59 @@ blsuki_load_entries (char *path, bool enable_fallback, enum blsuki_cmd_type cmd_
       tmp = grub_stpcpy (tmp, cmd_dir);
       dir = default_dir;
     }
+    //will search ESP ($root) if no device specified
+      r = blsuki_set_find_entry_info (&info, dir, devid, cmd_type);
+      if (r == GRUB_ERR_NONE)
+	r = blsuki_find_entry (&info, enable_fallback, cmd_type);
+      if (r != GRUB_ERR_NONE)
+	goto finish;
+     /*
+     * No device and partition specified - default behaviour as
+     * per the spec is to search both ESP and XBOOTLDR partitions
+     */
+  if (devid == NULL)
+    {
+      //find XBOOTLDR partition if it exists and scan it for entries
+      grub_disk_t esp_disk = grub_disk_open(grub_env_get ("root"));
+      grub_err_t err;
 
-  r = blsuki_set_find_entry_info (&info, dir, devid, cmd_type);
-  if (r == GRUB_ERR_NONE)
-    r = blsuki_find_entry (&info, enable_fallback, cmd_type);
+      if (esp_disk)
+	{
+	  grub_free (esp_disk->partition);
+	  //we want to access the disk device containing the ESP, so set partition to NULL
+	  esp_disk->partition = NULL;
+	  err = grub_gpt_partition_map_iterate (esp_disk, find_xbootldr_iter, &xbootldr_part);
+	  if (err)
+	    {
+	      grub_dprintf("blsuki", "iterating partitions failed with err: %d\n",err);
+	      goto finish;
+	    }
+
+	  if (xbootldr_part)
+	    {
+	      grub_dprintf("blsuki", "Found XBOOTLDR partition %s\n", xbootldr_part);
+	      r = blsuki_set_find_entry_info (&info, dir, xbootldr_part, cmd_type);
+	      if (r == GRUB_ERR_NONE)
+		r = blsuki_find_entry (&info, enable_fallback, cmd_type);
+	      if (r != GRUB_ERR_NONE)
+		goto finish;
+	    }
+	  else
+	    {
+	      grub_dprintf("blsuki", "XBOOTLDR partition not found (%s)!\n", xbootldr_part);
+	    }
+	  grub_disk_close(esp_disk);
+	}
+      else grub_dprintf("blsuki", "Failed to open ESP disk looking for XBOOTLDR partition\n");
+    }
+  finish:
+    if (info.dev != NULL)
+      grub_device_close (info.dev);
 
-  if (info.dev != NULL)
-    grub_device_close (info.dev);
+    grub_free (default_dir);
+    grub_free (xbootldr_part);
 
-  grub_free (default_dir);
-  return r;
+    return r;
 }
 
 static bool
diff --git a/include/grub/gpt_partition.h b/include/grub/gpt_partition.h
index 292ea03f1..4833827ef 100644
--- a/include/grub/gpt_partition.h
+++ b/include/grub/gpt_partition.h
@@ -41,6 +41,13 @@
 	{ 0x85, 0xD2, 0xE1, 0xE9, 0x04, 0x34, 0xCF, 0xB3 }	\
   }
 
+#define GRUB_GPT_PARTITION_TYPE_XBOOTLDR \
+  { grub_cpu_to_le32_compile_time (0xbc13c2ffU),\
+      grub_cpu_to_le16_compile_time (0x59e6), \
+      grub_cpu_to_le16_compile_time (0x4262),	       \
+	{ 0xa3, 0x52, 0xb2, 0x75, 0xfd, 0x6f, 0x71, 0x72 }	\
+  }
+
 struct grub_gpt_header
 {
   grub_uint8_t magic[8];
-- 
2.51.1


_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel