On Sun, Jul 27, 2025 at 01:54:36AM +0000, Alec Brown wrote:
> A Unified Kernel Image is a single UEFI PE file that combines a UEFI boot
> stub,
> a Linux kernel image, an initrd, and further resources. The uki command will
> locate where the UKI file is and create a GRUB menu entry to load it.
>
> The Unified Kernel Image Specification:
> https://uapi-group.org/specifications/specs/unified_kernel_image/
>
> Signed-off-by: Alec Brown <[email protected]>
> ---
> docs/grub.texi | 33 +++
> grub-core/commands/blsuki.c | 453 +++++++++++++++++++++++++++++++++---
> include/grub/menu.h | 2 +
> 3 files changed, 450 insertions(+), 38 deletions(-)
>
> diff --git a/docs/grub.texi b/docs/grub.texi
> index 1186f274f..5d9217057 100644
> --- a/docs/grub.texi
> +++ b/docs/grub.texi
> @@ -6495,6 +6495,7 @@ you forget a command, you can run the command
> @command{help}
> * tpm2_dump_pcr:: Dump TPM2 PCRs
> * true:: Do nothing, successfully
> * trust:: Add public key to list of trusted keys
> +* uki:: Load Unified Kernel Image menu entries
> * unset:: Unset an environment variable
> @comment * vbeinfo:: List available video modes
> * verify_detached:: Verify detached digital signature
> @@ -8247,6 +8248,38 @@ Unset the environment variable @var{envvar}.
> @end deffn
>
>
> +@node uki
> +@subsection uki
> +
> +@deffn Command uki [@option{-p|--path} dir] [@option{-f|--enable-fallback}]
> [@option{-d|--show-default}] [@option{-n|--show-non-default}]
> [@option{-e|--entry} file]
> +Load Unified Kernel Image (UKI) entries into the GRUB menu. Boot entries
> +generated from @command{uki} won't interfere with entries from
> @file{grub.cfg} appearing in the
> +GRUB menu. Also, entries generated from @command{uki} exists only in memory
> and don't
> +update @file{grub.cfg}.
> +
> +By default, the UKI entries are stored in the @file{/EFI/Linux} directory in
> the EFI
"entries"? I think you mean UKI "files"? The GRUB generates "UKI entires"
from "UKI files". I think this should be fixed in the doc snippet.
> +system partition. If UKI entries are stored elsewhere, the @option{--path}
> option can be
> +used to check a different directory instead of the default location. If no
> UKI
> +entries are found while using the @option{--path} option, the
> @option{--enable-fallback} option
> +can be used to check for entries in the default location.
> +
> +The @option{--show-default} option allows the default boot entry to be added
> to the
> +GRUB menu from the UKI entries.
> +
> +The @option{--show-non-default} option allows non-default boot entries to be
> added to
> +the GRUB menu from the UKI entries.
> +
> +The @option{--entry} option allows specific boot entries to be added to the
> GRUB menu
> +from the UKI entries.
> +
> +The @option{--entry}, @option{--show-default}, and
> @option{--show-non-default} options
> +are used to filter which UKI entries are added to the GRUB menu. If none are
> +used, all entries in the default location or the location specified by
> @option{--path}
> +will be added to the GRUB menu.
> +
> +For more information on UKI, see:
> @uref{https://uapi-group.org/specifications/specs/unified_kernel_image/, The
> Unified Kernel Image Specification}
> +@end deffn
> +
> @ignore
> @node vbeinfo
> @subsection vbeinfo
> diff --git a/grub-core/commands/blsuki.c b/grub-core/commands/blsuki.c
> index 76615e9bc..86a72cd0b 100644
> --- a/grub-core/commands/blsuki.c
> +++ b/grub-core/commands/blsuki.c
> @@ -32,6 +32,12 @@
> #include <grub/lib/envblk.h>
> #include <filevercmp.h>
>
> +#ifdef GRUB_MACHINE_EFI
> +#include <grub/efi/efi.h>
> +#include <grub/efi/disk.h>
> +#include <grub/efi/pe32.h>
> +#endif
> +
> #ifdef GRUB_MACHINE_EMU
> #include <grub/emu/misc.h>
> #define GRUB_BOOT_DEVICE "/boot"
> @@ -42,10 +48,19 @@
> GRUB_MOD_LICENSE ("GPLv3+");
>
> #define GRUB_BLS_CONFIG_PATH "/loader/entries/"
> +#define GRUB_UKI_CONFIG_PATH "/EFI/Linux"
>
> #define BLS_EXT_LEN (sizeof (".conf") - 1)
> +#define UKI_EXT_LEN (sizeof (".efi") - 1)
>
> #define BLSUKI_KEYVALS_MAX 10000
> +#define UKI_SECTION_SIZE_MAX 10000
I think these MAX values require some comments. Where do they come from?
Why not 20000 or 25000? This should be explained.
> +enum blsuki_cmd_type
> + {
> + BLSUKI_BLS_CMD,
> + BLSUKI_UKI_CMD,
> + };
>
> static const struct grub_arg_option bls_opt[] =
> {
> @@ -57,6 +72,18 @@ static const struct grub_arg_option bls_opt[] =
> {0, 0, 0, 0, 0, 0}
> };
>
> +#ifdef GRUB_MACHINE_EFI
> +static const struct grub_arg_option uki_opt[] =
> + {
> + {"path", 'p', 0, N_("Specify path to find UKI entries."), N_("DIR"),
> ARG_TYPE_PATHNAME},
> + {"enable-fallback", 'f', 0, "Fallback to the default BLS path if --path
> fails to find UKI entries.", 0, ARG_TYPE_NONE},
> + {"show-default", 'd', 0, N_("Allow the default UKI entry to be added to
> the GRUB menu."), 0, ARG_TYPE_NONE},
> + {"show-non-default", 'n', 0, N_("Allow the non-default UKI entries to be
> added to the GRUB menu."), 0, ARG_TYPE_NONE},
> + {"entry", 'e', 0, N_("Allow specificUKII entries to be added to the GRUB
> menu."), N_("FILE"), ARG_TYPE_FILE},
> + {0, 0, 0, 0, 0, 0}
> + };
> +#endif
> +
> struct keyval
> {
> const char *key;
> @@ -67,6 +94,7 @@ struct read_entry_info
> {
> const char *devid;
> const char *dirname;
> + enum blsuki_cmd_type cmd_type;
> grub_file_t file;
> };
>
> @@ -78,7 +106,7 @@ struct find_entry_info
> grub_fs_t fs;
> };
>
> -static grub_blsuki_entry_t *entries;
> +static grub_blsuki_entry_t *entries = NULL;
>
> #define FOR_BLSUKI_ENTRIES(var) FOR_LIST_ELEMENTS (var, entries)
>
> @@ -183,7 +211,7 @@ blsuki_add_keyval (grub_blsuki_entry_t *entry, char *key,
> char *val)
> * Find the value of the key named by keyname. If there are allowed to be
> * more than one, pass a pointer set to -1 to the last parameter the first
> * time, and pass the same pointer through each time after, and it'll return
> - * them in sorted order as defined in the BLS fragment file.
> + * them in sorted order.
> */
> static char *
> blsuki_get_val (grub_blsuki_entry_t *entry, const char *keyname, int *last)
> @@ -312,20 +340,213 @@ bls_parse_keyvals (grub_file_t f, grub_blsuki_entry_t
> *entry)
> return err;
> }
>
> +/*
> + * This function searches for the .cmdline, .osrel, and .linux sections of a
> + * UKI. We only need to store the data for the .cmdline and .osrel sections,
> + * but we also need to verify that the .linux section exists.
> + */
> +#ifdef GRUB_MACHINE_EFI
> +static grub_err_t
> +uki_parse_keyvals (grub_file_t f, grub_blsuki_entry_t *entry)
> +{
> + struct grub_msdos_image_header *dos = NULL;
> + struct grub_pe_image_header *pe = NULL;
> + grub_off_t section_offset = 0;
> + struct grub_pe32_section_table *section = NULL;
> + struct grub_pe32_coff_header *coff_header = NULL;
> + char *val = NULL;
> + char *key = NULL;
> + const char *target[] = {".cmdline", ".osrel", ".linux", NULL};
> + bool has_linux = false;
> + grub_err_t err = GRUB_ERR_NONE;
> +
> + dos = grub_zalloc (sizeof (*dos));
> + if (dos == NULL)
> + return grub_errno;
> + if (grub_file_read (f, dos, sizeof (*dos)) < (grub_ssize_t) sizeof (*dos))
> + {
> + err = grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read UKI image
> header");
> + goto finish;
> + }
> + if (dos->msdos_magic != GRUB_PE32_MAGIC)
> + {
> + err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "plain image kernel is not
> supported");
> + goto finish;
> + }
> +
> + grub_dprintf ("blsuki", "PE/COFF header @ %08x\n",
> dos->pe_image_header_offset);
> + pe = grub_zalloc (sizeof (*pe));
> + if (pe == NULL)
> + {
> + err = grub_errno;
> + goto finish;
> + }
> + if (grub_file_seek (f, dos->pe_image_header_offset) == (grub_off_t) -1 ||
> + grub_file_read (f, pe, sizeof (*pe)) != sizeof (*pe))
> + {
> + err = grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read COFF image
> header");
> + goto finish;
> + }
> + if (pe->optional_header.magic != GRUB_PE32_NATIVE_MAGIC)
> + {
> + err = grub_error (GRUB_ERR_BAD_FILE_TYPE, "non-native image not
> supported");
> + goto finish;
> + }
> +
> + coff_header = &(pe->coff_header);
> + section_offset = dos->pe_image_header_offset + sizeof (*pe);
> +
> + for (int i = 0; i < coff_header->num_sections; i++)
> + {
> + key = NULL;
> + val = NULL;
These two assignments seem redundant to me...
> + section = grub_zalloc (sizeof (*section));
> + if (section == NULL)
> + {
> + err = grub_errno;
> + goto finish;
> + }
> +
> + if (grub_file_seek (f, section_offset) == (grub_off_t) -1 ||
> + grub_file_read (f, section, sizeof (*section)) != sizeof
> (*section))
> + {
> + err = grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read section
> header");
> + goto finish;
> + }
> +
> + key = grub_strndup (section->name, 8);
> + if (key == NULL)
> + {
> + err = grub_errno;
> + goto finish;
> + }
> +
> + for (int j = 0; target[j] != NULL; j++)
> + {
> + if (grub_strcmp (key, target[j]) == 0)
> + {
> + /*
> + * We don't need to read the contents of the .linux PE section,
> but we
> + * should verify that the section exists.
> + */
> + if (grub_strcmp (key, ".linux") == 0)
> + {
> + has_linux = true;
> + break;
> + }
> +
> + if (section->raw_data_size > UKI_SECTION_SIZE_MAX)
> + {
> + err = grub_error (GRUB_ERR_BAD_NUMBER, "UKI section size is
> larger than expected");
> + goto finish;
> + }
> +
> + val = grub_zalloc (section->raw_data_size);
> + if (val == NULL)
> + {
> + err = grub_errno;
> + goto finish;
> + }
> +
> + if (grub_file_seek (f, section->raw_data_offset) == (grub_off_t)
> -1 ||
> + grub_file_read (f, val, section->raw_data_size) !=
> (grub_ssize_t) section->raw_data_size)
> + {
> + err = grub_error (GRUB_ERR_FILE_READ_ERROR, "failed to read
> section");
> + goto finish;
> + }
> +
> + err = blsuki_add_keyval (entry, key, val);
> + if (err != GRUB_ERR_NONE)
> + goto finish;
> +
> + break;
> + }
> + }
> +
> + section_offset += sizeof (*section);
> + grub_free (section);
> + grub_free (val);
> + grub_free (key);
> + section = NULL;
> + val = NULL;
> + key = NULL;
> + }
> +
> + if (has_linux == false)
> + err = grub_error (GRUB_ERR_NO_KERNEL, "UKI is missing the '.linux'
> section");
> +
> + finish:
> + grub_free (dos);
> + grub_free (pe);
> + grub_free (section);
> + grub_free (val);
> + grub_free (key);
> + return err;
> +}
> +#endif
> +
> +/*
> + * This function obtains the keyval pairs when the .osrel data is input into
> + * the osrel_ptr parameter and returns the keyval pair. Since we are using
> + * grub_strtok_r(), the osrel_ptr will be updated to the following line of
> + * osrel. This function returns NULL when it reaches the end of osrel.
> + */
> +static char *
> +uki_read_osrel (char **osrel_ptr, char **val_ret)
> +{
> + char *key, *val;
> + grub_size_t val_size;
> +
> + for (;;)
> + {
> + key = grub_strtok_r (NULL, "\n\r", osrel_ptr);
> + if (key == NULL)
> + return NULL;
> +
> + /* Remove leading white space */
> + while (*key == ' ' || *key == '\t')
> + key++;
> +
> + /* Skip commented lines */
> + if (*key == '#')
> + continue;
> +
> + /* Split key/value */
> + key = grub_strtok_r (key, "=", &val);
> + if (key == NULL || *val == '\0')
> + continue;
> +
> + /* Remove quotes from value */
> + val_size = grub_strlen (val);
> + if (*val == '\"' && val[val_size - 1] == '\"')
Does it matter if somebody puts quotes into middle of the string?
What about single quotes?
> + {
> + val[val_size - 1] = '\0';
> + val++;
> + }
> +
> + *val_ret = val;
> + break;
> + }
> +
> + return key;
> +}
> +
> /*
> * If a file hasn't already been opened, this function opens a BLS config
> file
> - * and initializes entry data before parsing keyvals and adding the entry to
> - * the list of BLS entries.
> + * or UKI and initializes entry data before parsing keyvals and adding the
> entry
> + * to the list of BLS or UKI entries.
> */
> static int
> blsuki_read_entry (const char *filename,
> const struct grub_dirhook_info *dirhook_info __attribute__
> ((__unused__)),
> void *data)
> {
> - grub_size_t path_len = 0, filename_len;
> - grub_err_t err;
> + grub_size_t path_len = 0, ext_len = 0, filename_len;
> + grub_err_t err = GRUB_ERR_NONE;
> char *p = NULL;
> + const char *ext = NULL;
> grub_file_t f = NULL;
> + enum grub_file_type file_type = 0;
> grub_blsuki_entry_t *entry;
> struct read_entry_info *info = (struct read_entry_info *) data;
>
> @@ -333,17 +554,29 @@ blsuki_read_entry (const char *filename,
>
> filename_len = grub_strlen (filename);
>
> + if (info->cmd_type == BLSUKI_BLS_CMD)
> + {
> + ext = ".conf";
> + ext_len = BLS_EXT_LEN;
> + file_type = GRUB_FILE_TYPE_CONFIG;
> + }
> + else if (info->cmd_type == BLSUKI_UKI_CMD)
> + {
> + ext = ".efi";
> + ext_len = UKI_EXT_LEN;
> + file_type = GRUB_FILE_TYPE_EFI_CHAINLOADED_IMAGE;
Should not we fail here immediately on non-UEFI platforms?
Or probably it should be disabled in that case...
> + }
> +
> if (info->file != NULL)
> f = info->file;
> else
> {
> - if (filename_len < BLS_EXT_LEN ||
> - grub_strcmp (filename + filename_len - BLS_EXT_LEN, ".conf") != 0)
> + if (filename_len < ext_len ||
> + grub_strcmp (filename + filename_len - ext_len, ext) != 0)
> return 0;
>
> p = grub_xasprintf ("(%s)%s/%s", info->devid, info->dirname, filename);
> -
> - f = grub_file_open (p, GRUB_FILE_TYPE_CONFIG);
> + f = grub_file_open (p, file_type);
> grub_free (p);
> if (f == NULL)
> goto finish;
> @@ -380,7 +613,26 @@ blsuki_read_entry (const char *filename,
> goto finish;
> }
>
> - err = bls_parse_keyvals (f, entry);
> + entry->dirname = grub_strdup (info->dirname);
> + if (entry->dirname == NULL)
> + {
> + grub_free (entry);
> + goto finish;
> + }
> +
> + entry->devid = grub_strdup (info->devid);
> + if (entry->devid == NULL)
> + {
> + grub_free (entry);
> + goto finish;
> + }
> +
> + if (info->cmd_type == BLSUKI_BLS_CMD)
> + err = bls_parse_keyvals (f, entry);
> +#ifdef GRUB_MACHINE_EFI
> + else if (info->cmd_type == BLSUKI_UKI_CMD)
> + err = uki_parse_keyvals (f, entry);
> +#endif
>
> if (err == GRUB_ERR_NONE)
> blsuki_add_entry (entry);
> @@ -396,7 +648,7 @@ blsuki_read_entry (const char *filename,
>
> /*
> * This function returns a list of values that had the same key in the BLS
> - * config file. The number of entries in this list is returned by the len
> + * config file or UKI. The number of entries in this list is returned by the
> len
> * parameter.
> */
> static char **
> @@ -786,6 +1038,63 @@ bls_create_entry (grub_blsuki_entry_t *entry)
> grub_free (src);
> }
>
> +/*
> + * This function puts together the section data recieved from the UKI and
> + * generates a new entry un the GRUB boot menu.
s/un/in/
> + */
> +static void
> +uki_create_entry (grub_blsuki_entry_t *entry)
> +{
> + const char **argv = NULL;
> + char *id = entry->filename;
> + char *title = NULL;
> + char *options = NULL;
> + char *osrel, *osrel_line;
> + char *key = NULL;
> + char *value = NULL;
> + char *src = NULL;
> +
> + /*
> + * Although .osrel is listed as optional in the UKI specification, the
> .osrel
> + * section is needed to generate the GRUB menu entry title.
> + */
> + osrel = blsuki_get_val (entry, ".osrel", NULL);
> + if (osrel == NULL)
> + {
> + grub_dprintf ("blsuki", "Skipping file %s with no '.osrel' key.\n",
> entry->filename);
> + goto finish;
> + }
> +
> + osrel_line = osrel;
> + while ((key = uki_read_osrel (&osrel_line, &value)))
(key = uki_read_osrel (&osrel_line, &value)) != NULL
> + {
> + if (grub_strcmp ("PRETTY_NAME", key) == 0)
> + {
> + title = value;
> + break;
> + }
> + }
> +
> + options = blsuki_get_val (entry, ".cmdline", NULL);
> +
> + argv = grub_zalloc (2 * sizeof (char *));
> + if (argv == NULL)
> + goto finish;
> + argv[0] = title;
> +
> + src = grub_xasprintf ("chainloader (%s)%s/%s%s%s\n",
> + entry->devid, entry->dirname,
> + entry->filename, options ? " " : "", options ? options
> : "");
(options != NULL) ? " " : "",
(options != NULL) ? options : ""
> +
> + grub_normal_add_menu_entry (1, argv, NULL, id, NULL, NULL, NULL, src, 0,
> entry);
> +
> + finish:
> + grub_free (argv);
> + grub_free (src);
> + grub_free (options);
> + grub_free (osrel);
> +}
> +
> /*
> * This function fills a find_entry_info struct passed in by the info
> parameter.
> * If the dirname or devid parameters are set to NULL, the dirname and devid
> @@ -795,7 +1104,7 @@ bls_create_entry (grub_blsuki_entry_t *entry)
> * device.
> */
> static grub_err_t
> -blsuki_set_find_entry_info (struct find_entry_info *info, const char
> *dirname, const char *devid)
> +blsuki_set_find_entry_info (struct find_entry_info *info, const char
> *dirname, const char *devid, enum blsuki_cmd_type cmd_type)
> {
> grub_device_t dev;
> grub_fs_t fs;
> @@ -805,10 +1114,23 @@ blsuki_set_find_entry_info (struct find_entry_info
> *info, const char *dirname, c
>
> if (devid == NULL)
> {
> + if (cmd_type == BLSUKI_BLS_CMD)
> + {
> #ifdef GRUB_MACHINE_EMU
> - devid = "host";
> + devid = "host";
> #else
> - devid = grub_env_get ("root");
> + devid = grub_env_get ("root");
> +#endif
> + }
> +#ifdef GRUB_MACHINE_EFI
> + else if (cmd_type == BLSUKI_UKI_CMD)
> + {
> + grub_efi_loaded_image_t *image;
Please add empty line here and/or...
grub_efi_loaded_image_t *image = grub_efi_get_loaded_image
(grub_efi_image_handle);
> + image = grub_efi_get_loaded_image (grub_efi_image_handle);
> + if (image == NULL)
> + return grub_error (GRUB_ERR_BAD_DEVICE, N_("unable to find boot
> device"));
> + devid = grub_efidisk_get_device_name (image->device_handle);
> + }
> #endif
> if (devid == NULL)
> return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't
> set"), "root");
> @@ -847,15 +1169,16 @@ blsuki_set_find_entry_info (struct find_entry_info
> *info, const char *dirname, c
> }
>
> /*
> - * This function searches for BLS config files based on the data in the info
> - * parameter. If the fallback option is enabled, the default location will be
> - * checked for BLS config files if the first attempt fails.
> + * This function searches for BLS config files and UKIs based on the data in
> the
> + * info parameter. If the fallback option is enabled, the default location
> will
> + * be checked for BLS config files or UKIs if the first attempt fails.
> */
> static grub_err_t
> -blsuki_find_entry (struct find_entry_info *info, bool enable_fallback)
> +blsuki_find_entry (struct find_entry_info *info, bool enable_fallback, enum
> blsuki_cmd_type cmd_type)
> {
> struct read_entry_info read_entry_info;
> char *default_dir = NULL;
> + const char *cmd_dir = NULL;
> char *tmp;
> grub_size_t default_size;
> grub_fs_t dir_fs = NULL;
> @@ -872,6 +1195,7 @@ blsuki_find_entry (struct find_entry_info *info, bool
> enable_fallback)
> dir_dev = info->dev;
> dir_fs = info->fs;
> read_entry_info.devid = info->devid;
> + read_entry_info.cmd_type = cmd_type;
>
> r = dir_fs->fs_dir (dir_dev, read_entry_info.dirname,
> blsuki_read_entry,
> &read_entry_info);
> @@ -884,19 +1208,25 @@ blsuki_find_entry (struct find_entry_info *info, bool
> enable_fallback)
> /*
> * If we aren't able to find BLS entries in the directory given by
> info->dirname,
> * we can fallback to the default location "/boot/loader/entries/" and
> see if we
> - * can find the files there.
> + * can find the files there. If we can't find UKI entries, fallback to
> + * "/EFI/Linux" on the EFI system partition.
> */
> if (entries == NULL && fallback == false && enable_fallback == true)
> {
> - default_size = sizeof (GRUB_BOOT_DEVICE) + sizeof
> (GRUB_BLS_CONFIG_PATH) - 2;
> + if (cmd_type == BLSUKI_BLS_CMD)
> + cmd_dir = GRUB_BLS_CONFIG_PATH;
> + else if (cmd_type == BLSUKI_UKI_CMD)
> + cmd_dir = GRUB_UKI_CONFIG_PATH;
> +
> + default_size = sizeof (GRUB_BOOT_DEVICE) + sizeof (cmd_dir) - 2;
Oops... ... + strlen (cmd_dir) - 1;
> default_dir = grub_malloc (default_size);
> if (default_dir == NULL)
> return grub_errno;
>
> tmp = blsuki_update_boot_device (default_dir);
> - tmp = grub_stpcpy (tmp, GRUB_BLS_CONFIG_PATH);
> + tmp = grub_stpcpy (tmp, cmd_dir);
>
> - blsuki_set_find_entry_info (info, default_dir, NULL);
> + blsuki_set_find_entry_info (info, default_dir, NULL, cmd_type);
> grub_dprintf ("blsuki", "Entries weren't found in %s, fallback to
> %s\n",
> read_entry_info.dirname, info->dirname);
> fallback = true;
> @@ -911,15 +1241,17 @@ blsuki_find_entry (struct find_entry_info *info, bool
> enable_fallback)
> }
>
> static grub_err_t
> -blsuki_load_entries (char *path, bool enable_fallback)
> +blsuki_load_entries (char *path, bool enable_fallback, enum blsuki_cmd_type
> cmd_type)
> {
> - grub_size_t len;
> + grub_size_t len, ext_len = 0;
> static grub_err_t r;
> const char *devid = NULL;
> char *dir = NULL;
> char *default_dir = NULL;
> char *tmp;
> + const char *cmd_dir = NULL;
> grub_size_t dir_size;
> + const char *ext = NULL;
> struct find_entry_info info = {
> .dev = NULL,
> .fs = NULL,
> @@ -928,12 +1260,24 @@ blsuki_load_entries (char *path, bool enable_fallback)
> struct read_entry_info rei = {
> .devid = NULL,
> .dirname = NULL,
> + .cmd_type = cmd_type,
> };
>
> if (path != NULL)
> {
> + if (cmd_type == BLSUKI_BLS_CMD)
> + {
> + ext = ".conf";
> + ext_len = BLS_EXT_LEN;
> + }
> + else if (cmd_type == BLSUKI_UKI_CMD)
> + {
> + ext = ".efi";
> + ext_len = UKI_EXT_LEN;
Missing EFI ifdefery...
In general it seems to me you are not consistent with it. I think more
code should be disabled for nun-UEFI case.
> + }
> +
> len = grub_strlen (path);
> - if (len >= BLS_EXT_LEN && grub_strcmp (path + len - BLS_EXT_LEN,
> ".conf") == 0)
> + if (len >= ext_len && grub_strcmp (path + len - ext_len, ext) == 0)
> {
> rei.file = grub_file_open (path, GRUB_FILE_TYPE_CONFIG);
> if (rei.file == NULL)
> @@ -962,19 +1306,24 @@ blsuki_load_entries (char *path, bool enable_fallback)
>
> if (dir == NULL)
> {
> - dir_size = sizeof (GRUB_BOOT_DEVICE) + sizeof (GRUB_BLS_CONFIG_PATH) -
> 2;
> + if (cmd_type == BLSUKI_BLS_CMD)
> + cmd_dir = GRUB_BLS_CONFIG_PATH;
> + else if (cmd_type == BLSUKI_UKI_CMD)
> + cmd_dir = GRUB_UKI_CONFIG_PATH;
> +
> + dir_size = sizeof (GRUB_BOOT_DEVICE) + sizeof (cmd_dir) - 2;
Again... ... + strlen (cmd_dir) - 1;
> default_dir = grub_malloc (dir_size);
> if (default_dir == NULL)
> return grub_errno;
>
> tmp = blsuki_update_boot_device (default_dir);
> - tmp = grub_stpcpy (tmp, GRUB_BLS_CONFIG_PATH);
> + tmp = grub_stpcpy (tmp, cmd_dir);
> dir = default_dir;
> }
>
> - r = blsuki_set_find_entry_info (&info, dir, devid);
> + r = blsuki_set_find_entry_info (&info, dir, devid, cmd_type);
> if (r == GRUB_ERR_NONE)
> - r = blsuki_find_entry (&info, enable_fallback);
> + r = blsuki_find_entry (&info, enable_fallback, cmd_type);
>
> if (info.dev != NULL)
> grub_device_close (info.dev);
> @@ -1012,11 +1361,11 @@ blsuki_is_default_entry (const char *def_entry,
> grub_blsuki_entry_t *entry, int
> }
Daniel
_______________________________________________
Grub-devel mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/grub-devel