avnish писал(а) 24.09.2024 14:46: > On 2024-09-22 21:30, grub-devel-requ...@gnu.org wrote: >> >> Message: 1 >> Date: Sun, 22 Sep 2024 13:05:07 +0500 >> From: Nikita Travkin <nik...@trvn.ru> >> To: grub-devel@gnu.org >> Cc: Nikita Travkin <nik...@trvn.ru> >> Subject: [PATCH] loader/efi/chainloader: Add efidriver command >> Message-ID: <20240922-cmd-efidriver-v1-1-750b77bfc...@trvn.ru> >> Content-Type: text/plain; charset="utf-8" >> >> Sometimes it's useful to load EFI drivers. Since loading a driver is >> the same as starting it and UEFI handles cleanup after on it's own, we >> can piggy back on existing chainloader command and just start the image >> immediately instead of defering to "boot". Conveniently this also means >> that grub can also run plain efi applications with the new command, >> though the command is still called "efidriver" since it's the primary >> intended usecase. >> >> Refactor chainloader to split up image loading and starting from the >> command and loader functions and add a new "efidriver" command that >> executes those steps immediately. >> >> Signed-off-by: Nikita Travkin <nik...@trvn.ru> >> --- >> This patch adds EFI driver loading support to grub. >> >> Similar feature already exists in systemd-boot in a form of a dedicated >> directory that it loads drivers from. >> >> A few specific examples where it can be necessary: >> >> Loading devicetree >> ------------------ >> >> Linux can't rely on ACPI on most currently existing >> Windows-on-Snapdragon devices and instead makes use of devicetree. This >> means that something has to load said devicetree and provide it to the >> kerne. GRUB has a "devicetree" command for that but it has a couple of >> shortcomings: >> >> - One has to know beforehand what dtb they want to load; >> - This command doesn't verify the dtb and can't be used with UEFI >> secure-boot. >> >> Instead dtb could be loaded by a dedicated efi driver such as >> dtbloader [1]. Such driver could dynamically detect the device and load >> appropriate dtb and since it's a normal efi driver, it's verified with >> secure-boot, and itself can implement some security model to safely load >> dtbs. >> >> This would allow distro image makers to create generic os/installer >> images instead of adding device-specific hacks or asking the users for >> manual action to load the dtb. >> >> Peforming pre-boot firmware hacks >> --------------------------------- >> >> Most currently shipping WoS devices boot UEFI (and thus Linux) in EL1 >> which means Linux can't use KVM and virtualization. Windows has a custom >> api to switch to EL2. To work around that, custom efi driver, >> slbounce[2] can be used. This driver hooks into UEFI boot services and >> performs EL1->EL2 transition upon EBS. >> >> Adding "efidriver" command to GRUB would make it easy to "dual boot" >> EL1 and EL2 modes for users since at the moment Linux can't use some >> hardware while running in EL2. >> >> [1] https://github.com/TravMurav/dtbloader >> [2] https://github.com/TravMurav/slbounce >> --- >> grub-core/loader/efi/chainloader.c | 68 >> ++++++++++++++++++++++++++++++++------ >> 1 file changed, 57 insertions(+), 11 deletions(-) >> >> diff --git a/grub-core/loader/efi/chainloader.c >> b/grub-core/loader/efi/chainloader.c >> index 869307bf3..17b9c671e 100644 >> --- a/grub-core/loader/efi/chainloader.c >> +++ b/grub-core/loader/efi/chainloader.c >> @@ -64,9 +64,8 @@ grub_chainloader_unload (void *context) >> } >> >> static grub_err_t >> -grub_chainloader_boot (void *context) >> +start_efi_image (grub_efi_handle_t image_handle) >> { >> - grub_efi_handle_t image_handle = (grub_efi_handle_t) context; >> grub_efi_boot_services_t *b; >> grub_efi_status_t status; >> grub_efi_uintn_t exit_data_size; >> @@ -97,9 +96,20 @@ grub_chainloader_boot (void *context) >> if (exit_data) >> b->free_pool (exit_data); >> >> + return grub_errno; >> +} >> + >> +static grub_err_t >> +grub_chainloader_boot (void *context) >> +{ >> + grub_efi_handle_t image_handle = (grub_efi_handle_t) context; >> + grub_err_t ret; >> + >> + ret = start_efi_image(image_handle); > > Hi Nikita, > It seems a space is missing before '('
Oh, you're right, I somehow completely missed different code style... I will fix all of those as well as indents (probably happened due to different tab settings in my editor) and send a v2. Thanks for your review! Nikita > >> + >> grub_loader_unset (); >> >> - return grub_errno; >> + return ret; >> } >> >> static grub_err_t >> @@ -209,8 +219,7 @@ make_file_path (grub_efi_device_path_t *dp, const >> char *filename) >> } >> >> static grub_err_t >> -grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), >> - int argc, char *argv[]) >> +load_efi_image (int argc, char *argv[], grub_efi_handle_t *image_ret) >> { >> grub_file_t file = 0; >> grub_ssize_t size; >> @@ -400,8 +409,8 @@ grub_cmd_chainloader (grub_command_t cmd >> __attribute__ ((unused)), >> b->free_pages (address, pages); >> grub_free (file_path); >> >> - grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, >> image_handle, 0); >> - return 0; >> + *image_ret = image_handle; >> + return GRUB_ERR_NONE; >> >> fail: >> >> @@ -425,16 +434,53 @@ grub_cmd_chainloader (grub_command_t cmd >> __attribute__ ((unused)), >> return grub_errno; >> } >> >> -static grub_command_t cmd; >> +static grub_err_t >> +grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), >> + int argc, char *argv[]) > > alignment seems off. > Something like this: > grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), > int argc, char *argv[]) > > >> +{ >> + grub_efi_handle_t image_handle = NULL; >> + grub_err_t ret; >> + >> + ret = load_efi_image(argc, argv, &image_handle); > > Ditto. Missing space before '(' > >> + if (ret != GRUB_ERR_NONE) >> + return ret; >> + >> + grub_loader_set_ex (grub_chainloader_boot, grub_chainloader_unload, >> image_handle, 0); >> + return GRUB_ERR_NONE; >> +} >> + >> +static grub_err_t >> +grub_cmd_efidriver (grub_command_t cmd __attribute__ ((unused)), >> + int argc, char *argv[]) >> +{ >> + grub_efi_handle_t image_handle = NULL; >> + grub_err_t ret; >> + >> + ret = load_efi_image(argc, argv, &image_handle); > > Ditto. Missing space before '(' > >> + if (ret != GRUB_ERR_NONE) >> + return ret; >> + >> + ret = start_efi_image(image_handle); > > Ditto. Missing space before '(' > >> + >> + grub_dl_unref (my_mod); >> + >> + return ret; >> +} >> + >> +static grub_command_t cmd_chainloader; >> +static grub_command_t cmd_efidriver; >> >> GRUB_MOD_INIT(chainloader) >> { >> - cmd = grub_register_command ("chainloader", grub_cmd_chainloader, >> - 0, N_("Load another boot loader.")); >> + cmd_chainloader = grub_register_command ("chainloader", >> grub_cmd_chainloader, >> + 0, N_("Load another boot loader.")); >> + cmd_efidriver = grub_register_command ("efidriver", grub_cmd_efidriver, >> + 0, N_("Load a efi driver.")); > > alignment seems off for above two lines. Same as mentioned earlier. > > Thank you! > > Regards, > Avnish Chouhan > >> my_mod = mod; >> } >> >> GRUB_MOD_FINI(chainloader) >> { >> - grub_unregister_command (cmd); >> + grub_unregister_command (cmd_chainloader); >> + grub_unregister_command (cmd_efidriver); >> } >> >> --- >> base-commit: 9c34d56c2dafcd2737db0e3e49df63bce4d8b504 >> change-id: 20240922-cmd-efidriver-5b644a784851 >> >> Best regards, >> -- >> Nikita Travkin <nik...@trvn.ru> >> >> >> >> >> ------------------------------ >> >> Subject: Digest Footer >> >> _______________________________________________ >> Grub-devel mailing list >> Grub-devel@gnu.org >> https://lists.gnu.org/mailman/listinfo/grub-devel >> >> >> ------------------------------ >> >> End of Grub-devel Digest, Vol 247, Issue 74 >> ******************************************* > > _______________________________________________ > Grub-devel mailing list > Grub-devel@gnu.org > https://lists.gnu.org/mailman/listinfo/grub-devel _______________________________________________ Grub-devel mailing list Grub-devel@gnu.org https://lists.gnu.org/mailman/listinfo/grub-devel