On Thu, Mar 30, 2023 at 01:18:12PM +0200, Oliver Steffen wrote: > Add a new module named boot_loader_interface, which provides a command
s/boot_loader_interface/bli/? > with the same name. It implements a small but quite useful part of the > Boot Loader Interface [0]. This interface uses EFI variables for > communication between the boot loader and the operating system. > > This module sets two EFI variables under the vendor GUID > 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f: > > - LoaderInfo: contains GRUB + <version number>. > This allows the running operating system to identify the boot loader > used during boot. > > - LoaderDevicePartUUID: contains the partition UUID of the > EFI System Partition (ESP). This is used by > systemd-gpt-auto-generator [1] to find the root partitions (and others > too), via partition type IDs [2]. > > This module is only available on EFI platforms. > > [0] https://systemd.io/BOOT_LOADER_INTERFACE/ > [1] > https://www.freedesktop.org/software/systemd/man/systemd-gpt-auto-generator.html > [2] > https://uapi-group.org/specifications/specs/discoverable_partitions_specification/ > > Signed-off-by: Oliver Steffen <ostef...@redhat.com> > --- > docs/grub.texi | 22 +++++ > grub-core/Makefile.core.def | 6 ++ > grub-core/commands/bli.c | 166 ++++++++++++++++++++++++++++++++++++ > include/grub/efi/api.h | 5 ++ > 4 files changed, 199 insertions(+) > create mode 100644 grub-core/commands/bli.c > > diff --git a/docs/grub.texi b/docs/grub.texi > index a3e9ce2d1..2fe8756a5 100644 > --- a/docs/grub.texi > +++ b/docs/grub.texi > @@ -4291,6 +4291,7 @@ you forget a command, you can run the command > @command{help} > * background_image:: Load background image for active terminal > * badram:: Filter out bad regions of RAM > * blocklist:: Print a block list > +* bli:: Set Boot Loader Interface EFI variables > * boot:: Start up your operating system > * cat:: Show the contents of a file > * clear:: Clear the screen > @@ -4471,6 +4472,27 @@ Print a block list (@pxref{Block list syntax}) for > @var{file}. > @end deffn > > > +@node bli > +@subsection bli > + > +@deffn Command bli > +Initialize the @url{https://systemd.io/BOOT_LOADER_INTERFACE/, Boot Loader > Interface}. > + > +This command sets two EFI variables under the vendor GUID > +@code{4a67b082-0a4c-41cf-b6c7-440b29bb8c4f}: > + > +@code{LoaderDevicePartUUID} is set to the Partition UUID of the EFI System > Partition used during boot. > +This is needed for automatic partition discovery as described by the > +@url{https://uapi-group.org/specifications/specs/discoverable_partitions_specification/, > +Discoverable Partitions Specification}. > + > +@code{LoaderInfo} is set to the string @code{Grub} followed by the version > number. This is used by > +user-space tools to identify the boot loader that was used. > + > +This command is only available on UEFI platforms. Please move "only" to the end of the sentence. > +@end deffn > + > + > @node boot > @subsection boot > > diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def > index 801df7c21..b77375857 100644 > --- a/grub-core/Makefile.core.def > +++ b/grub-core/Makefile.core.def > @@ -2561,3 +2561,9 @@ module = { > common = commands/memtools.c; > condition = COND_MM_DEBUG; > }; > + > +module = { > + name = bli; > + efi = commands/bli.c; > + enable = efi; > +}; > diff --git a/grub-core/commands/bli.c b/grub-core/commands/bli.c > new file mode 100644 > index 000000000..3ce0161a8 > --- /dev/null > +++ b/grub-core/commands/bli.c > @@ -0,0 +1,166 @@ > +/* > + * GRUB -- GRand Unified Bootloader > + * Copyright (C) 2023 Free Software Foundation, Inc. > + * > + * GRUB is free software: you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation, either version 3 of the License, or > + * (at your option) any later version. > + * > + * GRUB is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License > + * along with GRUB. If not, see <http://www.gnu.org/licenses/>. > + * > + * Implementation of the Boot Loader Interface. > + */ > + > +#include <grub/charset.h> > +#include <grub/efi/api.h> > +#include <grub/efi/disk.h> > +#include <grub/efi/efi.h> > +#include <grub/err.h> > +#include <grub/extcmd.h> > +#include <grub/gpt_partition.h> > +#include <grub/misc.h> > +#include <grub/mm.h> > +#include <grub/partition.h> > +#include <grub/types.h> > + > +GRUB_MOD_LICENSE ("GPLv3+"); > + > +#define MODNAME "bli" > + > +static const grub_guid_t bli_vendor_guid = > GRUB_EFI_VENDOR_BOOT_LOADER_INTERFACE_GUID; > + > +static grub_err_t > +get_part_uuid (const char *device_name, char **part_uuid) > +{ > + grub_device_t device; > + grub_err_t status = GRUB_ERR_NONE; > + grub_disk_t disk = NULL; > + struct grub_gpt_partentry entry; > + > + device = grub_device_open (device_name); > + if (device == NULL) > + { > + status = grub_error (grub_errno, N_("error opening device: %s"), > device_name); s/error opening device/cannot open device/ Otherwise you will see following error message: error: error opening device: ... 🤔 > + goto fail; > + } > + > + disk = grub_disk_open (device->disk->name); > + if (disk == NULL) > + { > + status = grub_error (grub_errno, N_("error opening disk: %s"), > device_name); s/error opening disk/cannot open disk/ > + return status; > + } > + > + if (grub_strcmp (device->disk->partition->partmap->name, "gpt") != 0) > + { > + status = grub_error (GRUB_ERR_BAD_PART_TABLE, > + N_("this is not a GPT partition table: %s"), > device_name); > + goto fail; > + } > + > + if (grub_disk_read (disk, device->disk->partition->offset, > + device->disk->partition->index, sizeof (entry), &entry) > != GRUB_ERR_NONE) > + { > + status = grub_error (grub_errno, N_("read error: %s"), device_name); > + goto fail; > + } > + > + *part_uuid = grub_xasprintf ("%pG", &entry.guid); > + if (*part_uuid == NULL) > + status = grub_errno; > + > + fail: > + grub_disk_close (disk); > + grub_device_close (device); > + > + return status; > +} > + > +static grub_err_t > +set_efi_str_variable (const char *name, const grub_guid_t *guid, > + const char *value) This function looks pretty generic and I have an itching to move it to the GRUB EFI common code. Could you do that? > +{ > + grub_efi_char16_t *value_16; > + grub_ssize_t len16; > + grub_err_t status; > + > + len16 = grub_utf8_to_utf16_alloc (value, &value_16, NULL); > + > + if (len16 < 0) > + return grub_errno; > + > + status = grub_efi_set_variable_with_attributes (name, guid, > + (void *) value_16, (len16 + 1) * sizeof (value_16[0]), > + GRUB_EFI_VARIABLE_BOOTSERVICE_ACCESS | > GRUB_EFI_VARIABLE_RUNTIME_ACCESS); > + > + grub_free (value_16); > + > + return status; > +} Daniel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel