diff --git a/ChangeLog b/ChangeLog index 961d791c7..6b9f7ea9f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2012-03-10 Vladimir Serbinenko + + Fix efi chainloader on network root. + + * grub-core/loader/efi/chainloader.c (grub_cmd_chainloader): Handle + network devices. + * grub-core/net/drivers/efi/efinet.c (grub_efinet_get_device_handle): + New function. + 2012-03-10 Vladimir Serbinenko * grub-core/gfxmenu/gui_progress_bar.c (grub_gui_progress_bar): Remove diff --git a/grub-core/loader/efi/chainloader.c b/grub-core/loader/efi/chainloader.c index ffd8bf571..83d3f93e6 100644 --- a/grub-core/loader/efi/chainloader.c +++ b/grub-core/loader/efi/chainloader.c @@ -34,6 +34,7 @@ #include #include #include +#include GRUB_MOD_LICENSE ("GPLv3+"); @@ -190,11 +191,11 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), grub_ssize_t size; grub_efi_status_t status; grub_efi_boot_services_t *b; - grub_efi_handle_t dev_handle = 0; grub_device_t dev = 0; grub_efi_device_path_t *dp = 0; grub_efi_loaded_image_t *loaded_image; char *filename; + grub_efi_handle_t dev_handle = 0; if (argc == 0) return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); @@ -219,13 +220,29 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)), goto fail; if (dev->disk) + dev_handle = grub_efidisk_get_device_handle (dev->disk); + else if (dev->net && dev->net->server) { - dev_handle = grub_efidisk_get_device_handle (dev->disk); - if (dev_handle) - dp = grub_efi_get_device_path (dev_handle); + grub_net_network_level_address_t addr; + struct grub_net_network_level_interface *inf; + grub_net_network_level_address_t gateway; + grub_err_t err; + + err = grub_net_resolve_address (dev->net->server, &addr); + if (err) + goto fail; + + err = grub_net_route_address (addr, &gateway, &inf); + if (err) + goto fail; + + dev_handle = grub_efinet_get_device_handle (inf->card); } - if (! dev->disk || ! dev_handle || ! dp) + if (dev_handle) + dp = grub_efi_get_device_path (dev_handle); + + if (! dp) { grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device"); goto fail; diff --git a/grub-core/net/drivers/efi/efinet.c b/grub-core/net/drivers/efi/efinet.c index 14ab1bc2c..78a1eab16 100644 --- a/grub-core/net/drivers/efi/efinet.c +++ b/grub-core/net/drivers/efi/efinet.c @@ -122,6 +122,13 @@ static struct grub_net_card_driver efidriver = .recv = get_card_packet }; +grub_efi_handle_t +grub_efinet_get_device_handle (struct grub_net_card *card) +{ + if (!card || card->driver != &efidriver) + return 0; + return card->efi_handle; +} static void grub_efinet_findcards (void) diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h index a1a28cd4e..e67d92b35 100644 --- a/include/grub/efi/efi.h +++ b/include/grub/efi/efi.h @@ -86,4 +86,9 @@ extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle); extern int EXPORT_VAR(grub_efi_is_finished); +struct grub_net_card; + +grub_efi_handle_t +grub_efinet_get_device_handle (struct grub_net_card *card); + #endif /* ! GRUB_EFI_EFI_HEADER */