Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:vlefebvre:unified
systemd
2002-systemd-boot-load-addons-from-type-1-and-e...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 2002-systemd-boot-load-addons-from-type-1-and-expose-them.patch of Package systemd
From 810a76a83cb20903cf3a9e2887e812ba65e1ce84 Mon Sep 17 00:00:00 2001 From: Raito Bezarius <masterancpp@gmail.com> Date: Fri, 16 Jun 2023 14:03:35 +0200 Subject: [PATCH 2/7] systemd-boot: load addons from type 1 and expose them via EFI protocol This make it possible to attach addons to any Type #1 entry and get them back in the next bootable stage via an EFI protocol. --- src/boot/efi/addon-util.c | 48 +++++++++++++++++++++++++++++++++++++++ src/boot/efi/addon-util.h | 12 ++++++++++ src/boot/efi/boot.c | 31 ++++++++++++++++++++++--- src/boot/efi/meson.build | 1 + 4 files changed, 89 insertions(+), 3 deletions(-) create mode 100644 src/boot/efi/addon-util.c create mode 100644 src/boot/efi/addon-util.h diff --git a/src/boot/efi/addon-util.c b/src/boot/efi/addon-util.c new file mode 100644 index 0000000000..3b99855c93 --- /dev/null +++ b/src/boot/efi/addon-util.c @@ -0,0 +1,48 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "addon-util.h" +#include "proto/device-path.h" +#include "util.h" +#include "log.h" + +EFI_STATUS addons_install_proto(EFI_LOADED_IMAGE_PROTOCOL *stub_image, char16_t * const *addons) { + EFI_STATUS err; + EFI_DEVICE_PATH **dps; + + assert(stub_image); + + err = make_multiple_file_device_path(stub_image->DeviceHandle, addons, &dps); + if (err != EFI_SUCCESS || dps == NULL) + return err; + + return BS->InstallMultipleProtocolInterfaces(&stub_image->DeviceHandle, + MAKE_GUID_PTR(SYSTEMD_ADDON_MEDIA), + dps, NULL); +} + +EFI_STATUS addons_unload_proto(EFI_HANDLE *addons) +{ + EFI_STATUS err; + EFI_DEVICE_PATH *dps; + + assert(addons); + + if (!*addons) + return EFI_SUCCESS; + + /* get the EFI_DEVICE_PATH* interface that we allocated earlier */ + err = BS->HandleProtocol(*addons, MAKE_GUID_PTR(SYSTEMD_ADDON_MEDIA), + (void **) &dps); + if (err != EFI_SUCCESS) + return err; + + err = BS->UninstallMultipleProtocolInterfaces(*addons, + MAKE_GUID_PTR(SYSTEMD_ADDON_MEDIA), + &dps, NULL); + + if (err != EFI_SUCCESS) + return err; + + *addons = NULL; + return EFI_SUCCESS; +} diff --git a/src/boot/efi/addon-util.h b/src/boot/efi/addon-util.h new file mode 100644 index 0000000000..f1883fdcdb --- /dev/null +++ b/src/boot/efi/addon-util.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#pragma once + +#include "proto/loaded-image.h" +#include "device-path-util.h" +#include "util.h" + +#define SYSTEMD_ADDON_MEDIA_GUID \ + GUID_DEF(0x97ac68bf, 0xc741, 0x4bbb, 0xb7, 0xbf, 0x7f, 0x6c, 0xcc, 0x00, 0x8a, 0x7e) + +EFI_STATUS addons_install_proto(EFI_LOADED_IMAGE_PROTOCOL *loaded_image, char16_t * const *addons); +EFI_STATUS addons_unload_proto(EFI_HANDLE *addons); diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 7b17088b08..1debd591b3 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "addon-util.h" #include "bcd.h" #include "bootspec-fundamental.h" #include "console.h" @@ -63,6 +64,7 @@ typedef struct { char16_t *options; bool options_implied; /* If true, these options are implied if we invoke the PE binary without any parameters (as in: UKI). If false we must specify these options explicitly. */ char16_t **initrd; + char16_t **addons; /* systemd-addons for this entry */ char16_t key; EFI_STATUS (*call)(void); int tries_done; @@ -599,6 +601,8 @@ static void print_status(Config *config, char16_t *loaded_image_path) { printf(" loader: %ls\n", entry->loader); STRV_FOREACH(initrd, entry->initrd) printf(" initrd: %ls\n", *initrd); + STRV_FOREACH(addon, entry->addons) + printf(" addon: %ls\n", *addon); if (entry->devicetree) printf(" devicetree: %ls\n", entry->devicetree); if (entry->options) @@ -1176,6 +1180,7 @@ static BootEntry* boot_entry_free(BootEntry *entry) { free(entry->devicetree); free(entry->options); strv_free(entry->initrd); + strv_free(entry->addons); free(entry->path); free(entry->current_name); free(entry->next_name); @@ -1412,7 +1417,7 @@ static void boot_entry_add_type1( _cleanup_(boot_entry_freep) BootEntry *entry = NULL; char *line; - size_t pos = 0, n_initrd = 0; + size_t pos = 0, n_initrd = 0, n_addons = 0; char *key, *value; EFI_STATUS err; @@ -1481,7 +1486,14 @@ static void boot_entry_add_type1( (n_initrd + 2) * sizeof(uint16_t *)); entry->initrd[n_initrd++] = xstr8_to_path(value); entry->initrd[n_initrd] = NULL; - + } else if (streq8(key, "add-on")) { + entry->addons = xrealloc( + entry->addons, + n_addons == 0 ? 0 : (n_addons + 1) * sizeof(uint16_t *), + (n_addons + 2) * sizeof(uint16_t *)); + entry->addons[n_addons++] = xstr8_to_path(value); + entry->addons[n_addons] = NULL; + continue; } else if (streq8(key, "options")) { _cleanup_free_ char16_t *new = NULL; @@ -2309,6 +2321,13 @@ static EFI_STATUS initrd_prepare( return EFI_SUCCESS; } +static void cleanup_loaded_image(EFI_LOADED_IMAGE_PROTOCOL **loaded_image) { + assert(loaded_image); + + (void) addons_unload_proto((EFI_HANDLE *)*loaded_image); + *loaded_image = NULL; +} + static EFI_STATUS image_start( EFI_HANDLE parent_image, const BootEntry *entry) { @@ -2358,7 +2377,7 @@ static EFI_STATUS image_start( if (err != EFI_SUCCESS) return log_error_status(err, "Error registering initrd: %m"); - EFI_LOADED_IMAGE_PROTOCOL *loaded_image; + _cleanup_(cleanup_loaded_image) EFI_LOADED_IMAGE_PROTOCOL *loaded_image = NULL; err = BS->HandleProtocol(image, MAKE_GUID_PTR(EFI_LOADED_IMAGE_PROTOCOL), (void **) &loaded_image); if (err != EFI_SUCCESS) return log_error_status(err, "Error getting LoadedImageProtocol handle: %m"); @@ -2375,6 +2394,12 @@ static EFI_STATUS image_start( (void) tpm_log_load_options(options, NULL); } + if (entry->addons) { + err = addons_install_proto(loaded_image, entry->addons); + if (err != EFI_SUCCESS) + return log_error_status(err, "Error installing addons protocol: %m"); + } + efivar_set_time_usec(MAKE_GUID_PTR(LOADER), u"LoaderTimeExecUSec", 0); err = BS->StartImage(image, NULL, NULL); graphics_mode(false); diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index c95132e420..ba37ac9fb9 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -250,6 +250,7 @@ endif ############################################################ libefi_sources = files( + 'addon-util.c', 'console.c', 'device-path-util.c', 'devicetree.c', -- 2.35.3
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor