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.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-03-10 20:41:28 +01:00
parent 14361ee8aa
commit 1ecd61a47a
4 changed files with 43 additions and 5 deletions

View file

@ -1,3 +1,12 @@
2012-03-10 Vladimir Serbinenko <phcoder@gmail.com>
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 <phcoder@gmail.com> 2012-03-10 Vladimir Serbinenko <phcoder@gmail.com>
* grub-core/gfxmenu/gui_progress_bar.c (grub_gui_progress_bar): Remove * grub-core/gfxmenu/gui_progress_bar.c (grub_gui_progress_bar): Remove

View file

@ -34,6 +34,7 @@
#include <grub/efi/disk.h> #include <grub/efi/disk.h>
#include <grub/command.h> #include <grub/command.h>
#include <grub/i18n.h> #include <grub/i18n.h>
#include <grub/net.h>
GRUB_MOD_LICENSE ("GPLv3+"); GRUB_MOD_LICENSE ("GPLv3+");
@ -190,11 +191,11 @@ grub_cmd_chainloader (grub_command_t cmd __attribute__ ((unused)),
grub_ssize_t size; grub_ssize_t size;
grub_efi_status_t status; grub_efi_status_t status;
grub_efi_boot_services_t *b; grub_efi_boot_services_t *b;
grub_efi_handle_t dev_handle = 0;
grub_device_t dev = 0; grub_device_t dev = 0;
grub_efi_device_path_t *dp = 0; grub_efi_device_path_t *dp = 0;
grub_efi_loaded_image_t *loaded_image; grub_efi_loaded_image_t *loaded_image;
char *filename; char *filename;
grub_efi_handle_t dev_handle = 0;
if (argc == 0) if (argc == 0)
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("filename expected")); 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; goto fail;
if (dev->disk) 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); grub_net_network_level_address_t addr;
if (dev_handle) struct grub_net_network_level_interface *inf;
dp = grub_efi_get_device_path (dev_handle); 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"); grub_error (GRUB_ERR_BAD_DEVICE, "not a valid root device");
goto fail; goto fail;

View file

@ -122,6 +122,13 @@ static struct grub_net_card_driver efidriver =
.recv = get_card_packet .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 static void
grub_efinet_findcards (void) grub_efinet_findcards (void)

View file

@ -86,4 +86,9 @@ extern grub_efi_handle_t EXPORT_VAR(grub_efi_image_handle);
extern int EXPORT_VAR(grub_efi_is_finished); 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 */ #endif /* ! GRUB_EFI_EFI_HEADER */