/* Which loader types shall be considered for automatic selection */
#define LOADER_TYPE_MAY_AUTO_SELECT(t) IN_SET(t, LOADER_EFI, LOADER_LINUX, LOADER_UKI, LOADER_UKI_URL, LOADER_TYPE2_UKI)
-typedef struct {
+typedef struct BootEntry {
char16_t *id; /* The unique identifier for this entry (typically the filename of the file defining the entry, possibly suffixed with a profile id) */
char16_t *id_without_profile; /* same, but without any profile id suffixed */
char16_t *title_show; /* The string to actually display (this is made unique before showing) */
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 key;
- EFI_STATUS (*call)(void);
+ EFI_STATUS (*call)(const struct BootEntry *entry, EFI_FILE *root_dir, EFI_HANDLE parent_image);
int tries_done;
int tries_left;
char16_t *path;
return EFI_SUCCESS;
}
-_noreturn_ static EFI_STATUS poweroff_system(void) {
+_noreturn_ static EFI_STATUS call_poweroff_system(const BootEntry *entry, EFI_FILE *root_dir, EFI_HANDLE parent_image) {
RT->ResetSystem(EfiResetShutdown, EFI_SUCCESS, 0, NULL);
assert_not_reached();
}
-_noreturn_ static EFI_STATUS reboot_system(void) {
+_noreturn_ static EFI_STATUS call_reboot_system(const BootEntry *entry, EFI_FILE *root_dir, EFI_HANDLE parent_image) {
RT->ResetSystem(EfiResetCold, EFI_SUCCESS, 0, NULL);
assert_not_reached();
}
-static EFI_STATUS reboot_into_firmware(void) {
+static EFI_STATUS call_reboot_into_firmware(const BootEntry *entry, EFI_FILE *root_dir, EFI_HANDLE parent_image) {
EFI_STATUS err;
err = set_reboot_into_firmware();
if (err != EFI_SUCCESS)
return err;
- return reboot_system();
+ return call_reboot_system(entry, root_dir, parent_image);
}
static bool menu_run(
case ACTION_CONTINUE:
assert_not_reached();
case ACTION_POWEROFF:
- poweroff_system();
+ (void) call_poweroff_system(/* entry= */ NULL, /* root_dir= */ NULL, /* parent_image= */ NULL);
case ACTION_REBOOT:
case ACTION_FIRMWARE_SETUP:
- reboot_system();
+ (void) call_reboot_system(/* entry= */ NULL, /* root_dir= */ NULL, /* parent_image= */ NULL);
case ACTION_RUN:
case ACTION_QUIT:
break;
}
#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__)
-static EFI_STATUS boot_windows_bitlocker(void) {
+static EFI_STATUS call_boot_windows_bitlocker(const BootEntry *entry, EFI_FILE *root_dir, EFI_HANDLE parent_image) {
_cleanup_free_ EFI_HANDLE *handles = NULL;
size_t n_handles;
EFI_STATUS err;
+ assert(entry);
+
// FIXME: Experimental for now. Should be generalized, and become a per-entry option that can be
// enabled independently of BitLocker, and without a BootXXXX entry pre-existing.
u"\\EFI\\Microsoft\\Boot\\bootmgfw.efi");
if (config->reboot_for_bitlocker)
- e->call = boot_windows_bitlocker;
+ e->call = call_boot_windows_bitlocker;
#endif
}
}
static EFI_STATUS image_start(
- EFI_HANDLE parent_image,
- const BootEntry *entry) {
+ const BootEntry *entry,
+ EFI_FILE *root,
+ EFI_HANDLE parent_image) {
_cleanup_(devicetree_cleanup) struct devicetree_state dtstate = {};
_cleanup_(unload_imagep) EFI_HANDLE image = NULL;
/* If this loader entry has a special way to boot, try that first. */
if (entry->call)
- (void) entry->call();
+ (void) entry->call(entry, root, parent_image);
_cleanup_file_close_ EFI_FILE *image_root = NULL;
_cleanup_free_ EFI_DEVICE_PATH *path = NULL;
*entry = (BootEntry) {
.id = xstrdup16(u"auto-reboot-to-firmware-setup"),
.title = xstrdup16(u"Reboot Into Firmware Interface"),
- .call = reboot_into_firmware,
+ .call = call_reboot_into_firmware,
.tries_done = -1,
.tries_left = -1,
};
*entry = (BootEntry) {
.id = xstrdup16(u"auto-poweroff"),
.title = xstrdup16(u"Power Off The System"),
- .call = poweroff_system,
+ .call = call_poweroff_system,
.tries_done = -1,
.tries_left = -1,
};
*entry = (BootEntry) {
.id = xstrdup16(u"auto-reboot"),
.title = xstrdup16(u"Reboot The System"),
- .call = reboot_system,
+ .call = call_reboot_system,
.tries_done = -1,
.tries_left = -1,
};
/* Run special entry like "reboot" now. Those that have a loader
* will be handled by image_start() instead. */
if (entry->call && !entry->loader) {
- entry->call();
+ entry->call(entry, root_dir, image);
continue;
}
/* Optionally, read a random seed off the ESP and pass it to the OS */
(void) process_random_seed(root_dir);
- err = image_start(image, entry);
+ err = image_start(entry, root_dir, image);
if (err != EFI_SUCCESS)
return err;