diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2022-12-02 14:37:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-02 14:37:17 +0100 |
commit | 6accdcc547d9f3bbe3dddae7e0594d06c33168ff (patch) | |
tree | 2065a74cac74a75fefcb4f66bfb8c39a2957a1c3 | |
parent | d19e5540f20c78caa949ff33050b4a530cae1982 (diff) | |
parent | f6d59e2ebfc1bf50683a2e640aad501c372a50e4 (diff) | |
download | systemd-6accdcc547d9f3bbe3dddae7e0594d06c33168ff.tar.gz |
Merge pull request #25541 from medhefgo/boot-reconnect
boot: Fix huge boot delay
-rw-r--r-- | src/boot/efi/boot.c | 6 | ||||
-rw-r--r-- | src/boot/efi/console.c | 16 | ||||
-rw-r--r-- | src/boot/efi/missing_efi.h | 19 | ||||
-rw-r--r-- | src/boot/efi/part-discovery.c | 4 | ||||
-rw-r--r-- | src/boot/efi/vmm.c | 4 |
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) |