summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2022-12-02 14:37:17 +0100
committerGitHub <noreply@github.com>2022-12-02 14:37:17 +0100
commit6accdcc547d9f3bbe3dddae7e0594d06c33168ff (patch)
tree2065a74cac74a75fefcb4f66bfb8c39a2957a1c3
parentd19e5540f20c78caa949ff33050b4a530cae1982 (diff)
parentf6d59e2ebfc1bf50683a2e640aad501c372a50e4 (diff)
downloadsystemd-6accdcc547d9f3bbe3dddae7e0594d06c33168ff.tar.gz
Merge pull request #25541 from medhefgo/boot-reconnect
boot: Fix huge boot delay
-rw-r--r--src/boot/efi/boot.c6
-rw-r--r--src/boot/efi/console.c16
-rw-r--r--src/boot/efi/missing_efi.h19
-rw-r--r--src/boot/efi/part-discovery.c4
-rw-r--r--src/boot/efi/vmm.c4
5 files changed, 43 insertions, 6 deletions
diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c
index 9123c9a84c..9a562dcf22 100644
--- a/src/boot/efi/boot.c
+++ b/src/boot/efi/boot.c
@@ -2638,12 +2638,6 @@ EFI_STATUS efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *sys_table) {
/* Uncomment the next line if you need to wait for debugger. */
// debug_break();
- /* The firmware may skip initializing some devices for the sake of a faster boot. This is especially
- * true for fastboot enabled firmwares. But this means that things we use like input devices or the
- * xbootldr partition may not be available yet. Reconnect all drivers should hopefully make the
- * firmware initialize everything we need. */
- (void) reconnect_all_drivers();
-
err = BS->OpenProtocol(image,
&LoadedImageProtocol,
(void **)&loaded_image,
diff --git a/src/boot/efi/console.c b/src/boot/efi/console.c
index 14c0008afb..cd980fd535 100644
--- a/src/boot/efi/console.c
+++ b/src/boot/efi/console.c
@@ -12,6 +12,20 @@
#define VERTICAL_MAX_OK 1080
#define VIEWPORT_RATIO 10
+static EFI_STATUS console_connect(void) {
+ EFI_BOOT_MANAGER_POLICY_PROTOCOL *boot_policy;
+ EFI_STATUS err;
+
+ /* This should make console devices appear/fully initialize on fastboot firmware. */
+
+ err = BS->LocateProtocol(
+ &(EFI_GUID) EFI_BOOT_MANAGER_POLICY_PROTOCOL_GUID, NULL, (void **) &boot_policy);
+ if (err != EFI_SUCCESS)
+ return err;
+
+ return boot_policy->ConnectDeviceClass(boot_policy, &(EFI_GUID) EFI_BOOT_MANAGER_POLICY_CONSOLE_GUID);
+}
+
static inline void event_closep(EFI_EVENT *event) {
if (!*event)
return;
@@ -47,6 +61,8 @@ EFI_STATUS console_key_read(uint64_t *key, uint64_t timeout_usec) {
assert(key);
if (!checked) {
+ console_connect();
+
/* Get the *first* TextInputEx device.*/
err = BS->LocateProtocol(&SimpleTextInputExProtocol, NULL, (void **) &extraInEx);
if (err != EFI_SUCCESS || BS->CheckEvent(extraInEx->WaitForKeyEx) == EFI_INVALID_PARAMETER)
diff --git a/src/boot/efi/missing_efi.h b/src/boot/efi/missing_efi.h
index 250c84c248..b446e0399f 100644
--- a/src/boot/efi/missing_efi.h
+++ b/src/boot/efi/missing_efi.h
@@ -398,3 +398,22 @@ typedef struct {
void *StdErr;
} EFI_SHELL_PARAMETERS_PROTOCOL;
#endif
+
+#ifndef EFI_BOOT_MANAGER_POLICY_PROTOCOL_GUID
+#define EFI_BOOT_MANAGER_POLICY_PROTOCOL_GUID \
+ { 0xFEDF8E0C, 0xE147, 0x11E3, { 0x99, 0x03, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA } }
+#define EFI_BOOT_MANAGER_POLICY_CONSOLE_GUID \
+ { 0xCAB0E94C, 0xE15F, 0x11E3, { 0x91, 0x8D, 0xB8, 0xE8, 0x56, 0x2C, 0xBA, 0xFA } }
+
+typedef struct EFI_BOOT_MANAGER_POLICY_PROTOCOL EFI_BOOT_MANAGER_POLICY_PROTOCOL;
+struct EFI_BOOT_MANAGER_POLICY_PROTOCOL {
+ UINT64 Revision;
+ EFI_STATUS (EFIAPI *ConnectDevicePath)(
+ EFI_BOOT_MANAGER_POLICY_PROTOCOL *This,
+ EFI_DEVICE_PATH *DevicePath,
+ BOOLEAN Recursive);
+ EFI_STATUS (EFIAPI *ConnectDeviceClass)(
+ EFI_BOOT_MANAGER_POLICY_PROTOCOL *This,
+ EFI_GUID *Class);
+};
+#endif
diff --git a/src/boot/efi/part-discovery.c b/src/boot/efi/part-discovery.c
index de6d6112a1..14479c06ea 100644
--- a/src/boot/efi/part-discovery.c
+++ b/src/boot/efi/part-discovery.c
@@ -202,6 +202,10 @@ static EFI_STATUS find_device(const EFI_GUID *type, EFI_HANDLE *device, EFI_DEVI
if (err != EFI_SUCCESS)
return err;
+ /* The drivers for other partitions on this drive may not be initialized on fastboot firmware, so we
+ * have to ask the firmware to do just that. */
+ (void) BS->ConnectController(disk_handle, NULL, NULL, true);
+
err = BS->HandleProtocol(disk_handle, &BlockIoProtocol, (void **)&block_io);
if (err != EFI_SUCCESS)
return err;
diff --git a/src/boot/efi/vmm.c b/src/boot/efi/vmm.c
index b1bfd778fc..2260b217b7 100644
--- a/src/boot/efi/vmm.c
+++ b/src/boot/efi/vmm.c
@@ -83,6 +83,10 @@ EFI_STATUS vmm_open(EFI_HANDLE *ret_vmm_dev, EFI_FILE **ret_vmm_dir) {
assert(ret_vmm_dev);
assert(ret_vmm_dir);
+ /* Make sure all file systems have been initialized. Only do this in VMs as this is slow
+ * on some real firmwares. */
+ (void) reconnect_all_drivers();
+
/* find all file system handles */
err = BS->LocateHandleBuffer(ByProtocol, &FileSystemProtocol, NULL, &n_handles, &handles);
if (err != EFI_SUCCESS)