Automatically determine prefix when netbooted on EFI
This commit is contained in:
parent
574618a2e9
commit
cae730b452
8 changed files with 237 additions and 123 deletions
|
@ -84,54 +84,6 @@ find_last_device_path (const grub_efi_device_path_t *dp)
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Compare device paths. */
|
|
||||||
static int
|
|
||||||
compare_device_paths (const grub_efi_device_path_t *dp1,
|
|
||||||
const grub_efi_device_path_t *dp2)
|
|
||||||
{
|
|
||||||
if (! dp1 || ! dp2)
|
|
||||||
/* Return non-zero. */
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
while (1)
|
|
||||||
{
|
|
||||||
grub_efi_uint8_t type1, type2;
|
|
||||||
grub_efi_uint8_t subtype1, subtype2;
|
|
||||||
grub_efi_uint16_t len1, len2;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
|
|
||||||
type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
|
|
||||||
|
|
||||||
if (type1 != type2)
|
|
||||||
return (int) type2 - (int) type1;
|
|
||||||
|
|
||||||
subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
|
|
||||||
subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
|
|
||||||
|
|
||||||
if (subtype1 != subtype2)
|
|
||||||
return (int) subtype1 - (int) subtype2;
|
|
||||||
|
|
||||||
len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1);
|
|
||||||
len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
|
|
||||||
|
|
||||||
if (len1 != len2)
|
|
||||||
return (int) len1 - (int) len2;
|
|
||||||
|
|
||||||
ret = grub_memcmp (dp1, dp2, len1);
|
|
||||||
if (ret != 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1))
|
|
||||||
break;
|
|
||||||
|
|
||||||
dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1);
|
|
||||||
dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct grub_efidisk_data *
|
static struct grub_efidisk_data *
|
||||||
make_devices (void)
|
make_devices (void)
|
||||||
{
|
{
|
||||||
|
@ -214,7 +166,7 @@ find_parent_device (struct grub_efidisk_data *devices,
|
||||||
if (parent == d)
|
if (parent == d)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (compare_device_paths (parent->device_path, dp) == 0)
|
if (grub_efi_compare_device_paths (parent->device_path, dp) == 0)
|
||||||
{
|
{
|
||||||
/* Found. */
|
/* Found. */
|
||||||
if (! parent->last_device_path)
|
if (! parent->last_device_path)
|
||||||
|
@ -249,7 +201,7 @@ iterate_child_devices (struct grub_efidisk_data *devices,
|
||||||
ldp->length[0] = sizeof (*ldp);
|
ldp->length[0] = sizeof (*ldp);
|
||||||
ldp->length[1] = 0;
|
ldp->length[1] = 0;
|
||||||
|
|
||||||
if (compare_device_paths (dp, d->device_path) == 0)
|
if (grub_efi_compare_device_paths (dp, d->device_path) == 0)
|
||||||
if (hook (p))
|
if (hook (p))
|
||||||
{
|
{
|
||||||
grub_free (dp);
|
grub_free (dp);
|
||||||
|
@ -273,11 +225,11 @@ add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = compare_device_paths (find_last_device_path ((*p)->device_path),
|
ret = grub_efi_compare_device_paths (find_last_device_path ((*p)->device_path),
|
||||||
find_last_device_path (d->device_path));
|
find_last_device_path (d->device_path));
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
ret = compare_device_paths ((*p)->device_path,
|
ret = grub_efi_compare_device_paths ((*p)->device_path,
|
||||||
d->device_path);
|
d->device_path);
|
||||||
if (ret == 0)
|
if (ret == 0)
|
||||||
return;
|
return;
|
||||||
else if (ret > 0)
|
else if (ret > 0)
|
||||||
|
@ -706,7 +658,35 @@ grub_efidisk_get_device_handle (grub_disk_t disk)
|
||||||
char *
|
char *
|
||||||
grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
||||||
{
|
{
|
||||||
grub_efi_device_path_t *dp, *ldp;
|
grub_efi_device_path_t *dp, *ldp, *sdp;
|
||||||
|
/* This is a hard disk partition. */
|
||||||
|
grub_disk_t parent = 0;
|
||||||
|
auto int find_parent_disk (const char *name);
|
||||||
|
|
||||||
|
/* Find the disk which is the parent of a given hard disk partition. */
|
||||||
|
int find_parent_disk (const char *name)
|
||||||
|
{
|
||||||
|
grub_disk_t disk;
|
||||||
|
|
||||||
|
disk = grub_disk_open (name);
|
||||||
|
if (! disk)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
|
||||||
|
{
|
||||||
|
struct grub_efidisk_data *d;
|
||||||
|
|
||||||
|
d = disk->data;
|
||||||
|
if (grub_efi_compare_device_paths (d->device_path, sdp) == 0)
|
||||||
|
{
|
||||||
|
parent = disk;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
grub_disk_close (disk);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
dp = grub_efi_get_device_path (handle);
|
dp = grub_efi_get_device_path (handle);
|
||||||
if (! dp)
|
if (! dp)
|
||||||
|
@ -720,40 +700,12 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
||||||
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)
|
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (ldp)
|
||||||
== GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
|
== GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE))
|
||||||
{
|
{
|
||||||
/* This is a hard disk partition. */
|
|
||||||
grub_disk_t parent = 0;
|
|
||||||
grub_partition_t tpart = NULL;
|
grub_partition_t tpart = NULL;
|
||||||
char *device_name;
|
char *device_name;
|
||||||
grub_efi_device_path_t *dup_dp, *dup_ldp;
|
grub_efi_device_path_t *dup_dp, *dup_ldp;
|
||||||
grub_efi_hard_drive_device_path_t hd;
|
grub_efi_hard_drive_device_path_t hd;
|
||||||
auto int find_parent_disk (const char *name);
|
|
||||||
auto int find_partition (grub_disk_t disk, const grub_partition_t part);
|
auto int find_partition (grub_disk_t disk, const grub_partition_t part);
|
||||||
|
|
||||||
/* Find the disk which is the parent of a given hard disk partition. */
|
|
||||||
int find_parent_disk (const char *name)
|
|
||||||
{
|
|
||||||
grub_disk_t disk;
|
|
||||||
|
|
||||||
disk = grub_disk_open (name);
|
|
||||||
if (! disk)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
|
|
||||||
{
|
|
||||||
struct grub_efidisk_data *d;
|
|
||||||
|
|
||||||
d = disk->data;
|
|
||||||
if (compare_device_paths (d->device_path, dup_dp) == 0)
|
|
||||||
{
|
|
||||||
parent = disk;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_disk_close (disk);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the identical partition. */
|
/* Find the identical partition. */
|
||||||
int find_partition (grub_disk_t disk __attribute__ ((unused)),
|
int find_partition (grub_disk_t disk __attribute__ ((unused)),
|
||||||
const grub_partition_t part)
|
const grub_partition_t part)
|
||||||
|
@ -780,6 +732,8 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
||||||
dup_ldp->length[0] = sizeof (*dup_ldp);
|
dup_ldp->length[0] = sizeof (*dup_ldp);
|
||||||
dup_ldp->length[1] = 0;
|
dup_ldp->length[1] = 0;
|
||||||
|
|
||||||
|
sdp = dup_dp;
|
||||||
|
|
||||||
grub_efidisk_iterate (find_parent_disk);
|
grub_efidisk_iterate (find_parent_disk);
|
||||||
grub_free (dup_dp);
|
grub_free (dup_dp);
|
||||||
|
|
||||||
|
@ -816,36 +770,15 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* This should be an entire disk. */
|
/* This should be an entire disk. */
|
||||||
auto int find_disk (const char *name);
|
|
||||||
char *device_name = 0;
|
char *device_name = 0;
|
||||||
|
|
||||||
int find_disk (const char *name)
|
sdp = dp;
|
||||||
{
|
|
||||||
grub_disk_t disk;
|
|
||||||
|
|
||||||
disk = grub_disk_open (name);
|
grub_efidisk_iterate (find_parent_disk);
|
||||||
if (! disk)
|
if (!parent)
|
||||||
return 1;
|
return NULL;
|
||||||
|
device_name = grub_strdup (parent->name);
|
||||||
if (disk->dev->id == GRUB_DISK_DEVICE_EFIDISK_ID)
|
grub_disk_close (parent);
|
||||||
{
|
|
||||||
struct grub_efidisk_data *d;
|
|
||||||
|
|
||||||
d = disk->data;
|
|
||||||
if (compare_device_paths (d->device_path, dp) == 0)
|
|
||||||
{
|
|
||||||
device_name = grub_strdup (disk->name);
|
|
||||||
grub_disk_close (disk);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_disk_close (disk);
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
grub_efidisk_iterate (find_disk);
|
|
||||||
return device_name;
|
return device_name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -746,3 +746,51 @@ grub_efi_print_device_path (grub_efi_device_path_t *dp)
|
||||||
dp = (grub_efi_device_path_t *) ((char *) dp + len);
|
dp = (grub_efi_device_path_t *) ((char *) dp + len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Compare device paths. */
|
||||||
|
int
|
||||||
|
grub_efi_compare_device_paths (const grub_efi_device_path_t *dp1,
|
||||||
|
const grub_efi_device_path_t *dp2)
|
||||||
|
{
|
||||||
|
if (! dp1 || ! dp2)
|
||||||
|
/* Return non-zero. */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
while (1)
|
||||||
|
{
|
||||||
|
grub_efi_uint8_t type1, type2;
|
||||||
|
grub_efi_uint8_t subtype1, subtype2;
|
||||||
|
grub_efi_uint16_t len1, len2;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
type1 = GRUB_EFI_DEVICE_PATH_TYPE (dp1);
|
||||||
|
type2 = GRUB_EFI_DEVICE_PATH_TYPE (dp2);
|
||||||
|
|
||||||
|
if (type1 != type2)
|
||||||
|
return (int) type2 - (int) type1;
|
||||||
|
|
||||||
|
subtype1 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp1);
|
||||||
|
subtype2 = GRUB_EFI_DEVICE_PATH_SUBTYPE (dp2);
|
||||||
|
|
||||||
|
if (subtype1 != subtype2)
|
||||||
|
return (int) subtype1 - (int) subtype2;
|
||||||
|
|
||||||
|
len1 = GRUB_EFI_DEVICE_PATH_LENGTH (dp1);
|
||||||
|
len2 = GRUB_EFI_DEVICE_PATH_LENGTH (dp2);
|
||||||
|
|
||||||
|
if (len1 != len2)
|
||||||
|
return (int) len1 - (int) len2;
|
||||||
|
|
||||||
|
ret = grub_memcmp (dp1, dp2, len1);
|
||||||
|
if (ret != 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp1))
|
||||||
|
break;
|
||||||
|
|
||||||
|
dp1 = (grub_efi_device_path_t *) ((char *) dp1 + len1);
|
||||||
|
dp2 = (grub_efi_device_path_t *) ((char *) dp2 + len2);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -42,6 +42,10 @@ grub_efi_init (void)
|
||||||
grub_efidisk_init ();
|
grub_efidisk_init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void (*grub_efi_net_config) (grub_efi_handle_t hnd,
|
||||||
|
char **device,
|
||||||
|
char **path);
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_machine_get_bootlocation (char **device, char **path)
|
grub_machine_get_bootlocation (char **device, char **path)
|
||||||
{
|
{
|
||||||
|
@ -53,6 +57,8 @@ grub_machine_get_bootlocation (char **device, char **path)
|
||||||
return;
|
return;
|
||||||
*device = grub_efidisk_get_device_name (image->device_handle);
|
*device = grub_efidisk_get_device_name (image->device_handle);
|
||||||
*path = grub_efi_get_filename (image->file_path);
|
*path = grub_efi_get_filename (image->file_path);
|
||||||
|
if (!*device && grub_efi_net_config)
|
||||||
|
grub_efi_net_config (image->device_handle, device, path);
|
||||||
|
|
||||||
/* Get the directory. */
|
/* Get the directory. */
|
||||||
p = grub_strrchr (*path, '/');
|
p = grub_strrchr (*path, '/');
|
||||||
|
|
|
@ -27,14 +27,14 @@ GRUB_MOD_LICENSE ("GPLv3+");
|
||||||
|
|
||||||
/* GUID. */
|
/* GUID. */
|
||||||
static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID;
|
static grub_efi_guid_t net_io_guid = GRUB_EFI_SIMPLE_NETWORK_GUID;
|
||||||
|
static grub_efi_guid_t pxe_io_guid = GRUB_EFI_PXE_GUID;
|
||||||
|
|
||||||
static grub_err_t
|
static grub_err_t
|
||||||
send_card_buffer (const struct grub_net_card *dev,
|
send_card_buffer (const struct grub_net_card *dev,
|
||||||
struct grub_net_buff *pack)
|
struct grub_net_buff *pack)
|
||||||
{
|
{
|
||||||
grub_efi_status_t st;
|
grub_efi_status_t st;
|
||||||
grub_efi_simple_network_t *net = dev->data;
|
grub_efi_simple_network_t *net = dev->efi_net;
|
||||||
st = efi_call_7 (net->transmit, net, 0, pack->tail - pack->data,
|
st = efi_call_7 (net->transmit, net, 0, pack->tail - pack->data,
|
||||||
pack->data, NULL, NULL, NULL);
|
pack->data, NULL, NULL, NULL);
|
||||||
if (st != GRUB_EFI_SUCCESS)
|
if (st != GRUB_EFI_SUCCESS)
|
||||||
|
@ -46,7 +46,7 @@ static grub_ssize_t
|
||||||
get_card_packet (const struct grub_net_card *dev,
|
get_card_packet (const struct grub_net_card *dev,
|
||||||
struct grub_net_buff *nb)
|
struct grub_net_buff *nb)
|
||||||
{
|
{
|
||||||
grub_efi_simple_network_t *net = dev->data;
|
grub_efi_simple_network_t *net = dev->efi_net;
|
||||||
grub_err_t err;
|
grub_err_t err;
|
||||||
grub_efi_status_t st;
|
grub_efi_status_t st;
|
||||||
grub_efi_uintn_t bufsize = 1500;
|
grub_efi_uintn_t bufsize = 1500;
|
||||||
|
@ -139,21 +139,62 @@ grub_efinet_findcards (void)
|
||||||
grub_memcpy (card->default_address.mac,
|
grub_memcpy (card->default_address.mac,
|
||||||
net->mode->current_address,
|
net->mode->current_address,
|
||||||
sizeof (card->default_address.mac));
|
sizeof (card->default_address.mac));
|
||||||
card->data = net;
|
card->efi_net = net;
|
||||||
|
card->efi_handle = *handle;
|
||||||
|
|
||||||
grub_net_card_register (card);
|
grub_net_card_register (card);
|
||||||
}
|
}
|
||||||
grub_free (handles);
|
grub_free (handles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
grub_efi_net_config_real (grub_efi_handle_t hnd, char **device,
|
||||||
|
char **path)
|
||||||
|
{
|
||||||
|
struct grub_net_card *card;
|
||||||
|
grub_efi_device_path_t *dp;
|
||||||
|
|
||||||
|
dp = grub_efi_get_device_path (hnd);
|
||||||
|
if (! dp)
|
||||||
|
return;
|
||||||
|
|
||||||
|
FOR_NET_CARDS (card)
|
||||||
|
{
|
||||||
|
grub_efi_device_path_t *cdp;
|
||||||
|
struct grub_efi_pxe *pxe;
|
||||||
|
struct grub_efi_pxe_mode *pxe_mode;
|
||||||
|
if (card->driver != &efidriver)
|
||||||
|
continue;
|
||||||
|
cdp = grub_efi_get_device_path (card->efi_handle);
|
||||||
|
if (! cdp)
|
||||||
|
continue;
|
||||||
|
if (grub_efi_compare_device_paths (dp, cdp) != 0)
|
||||||
|
continue;
|
||||||
|
pxe = grub_efi_open_protocol (hnd, &pxe_io_guid,
|
||||||
|
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||||||
|
if (! pxe)
|
||||||
|
continue;
|
||||||
|
pxe_mode = pxe->mode;
|
||||||
|
grub_net_configure_by_dhcp_ack (card->name, card, 0,
|
||||||
|
(struct grub_net_bootp_packet *)
|
||||||
|
&pxe_mode->dhcp_ack,
|
||||||
|
sizeof (pxe_mode->dhcp_ack),
|
||||||
|
1, device, path);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
GRUB_MOD_INIT(efinet)
|
GRUB_MOD_INIT(efinet)
|
||||||
{
|
{
|
||||||
grub_efinet_findcards ();
|
grub_efinet_findcards ();
|
||||||
|
grub_efi_net_config = grub_efi_net_config_real;
|
||||||
}
|
}
|
||||||
|
|
||||||
GRUB_MOD_FINI(ofnet)
|
GRUB_MOD_FINI(ofnet)
|
||||||
{
|
{
|
||||||
struct grub_net_card *card;
|
struct grub_net_card *card;
|
||||||
|
grub_efi_net_config = 0;
|
||||||
FOR_NET_CARDS (card)
|
FOR_NET_CARDS (card)
|
||||||
if (card->driver && !grub_strcmp (card->driver->name, "efinet"))
|
if (card->driver && !grub_strcmp (card->driver->name, "efinet"))
|
||||||
{
|
{
|
||||||
|
|
|
@ -936,7 +936,8 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
||||||
const struct grub_net_card *card,
|
const struct grub_net_card *card,
|
||||||
grub_net_interface_flags_t flags,
|
grub_net_interface_flags_t flags,
|
||||||
const struct grub_net_bootp_packet *bp,
|
const struct grub_net_bootp_packet *bp,
|
||||||
grub_size_t size)
|
grub_size_t size,
|
||||||
|
int is_def, char **device, char **path)
|
||||||
{
|
{
|
||||||
grub_net_network_level_address_t addr;
|
grub_net_network_level_address_t addr;
|
||||||
grub_net_link_level_address_t hwaddr;
|
grub_net_link_level_address_t hwaddr;
|
||||||
|
@ -945,6 +946,11 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
||||||
addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
|
addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV4;
|
||||||
addr.ipv4 = bp->your_ip;
|
addr.ipv4 = bp->your_ip;
|
||||||
|
|
||||||
|
if (device)
|
||||||
|
*device = 0;
|
||||||
|
if (path)
|
||||||
|
*path = 0;
|
||||||
|
|
||||||
grub_memcpy (hwaddr.mac, bp->mac_addr,
|
grub_memcpy (hwaddr.mac, bp->mac_addr,
|
||||||
bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len
|
bp->hw_len < sizeof (hwaddr.mac) ? bp->hw_len
|
||||||
: sizeof (hwaddr.mac));
|
: sizeof (hwaddr.mac));
|
||||||
|
@ -975,26 +981,57 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
||||||
if (size > OFFSET_OF (boot_file, bp))
|
if (size > OFFSET_OF (boot_file, bp))
|
||||||
set_env_limn_ro (name, "boot_file", (char *) bp->boot_file,
|
set_env_limn_ro (name, "boot_file", (char *) bp->boot_file,
|
||||||
sizeof (bp->boot_file));
|
sizeof (bp->boot_file));
|
||||||
|
if (is_def)
|
||||||
|
default_server = 0;
|
||||||
if (size > OFFSET_OF (server_name, bp)
|
if (size > OFFSET_OF (server_name, bp)
|
||||||
&& bp->server_name[0])
|
&& bp->server_name[0])
|
||||||
{
|
{
|
||||||
set_env_limn_ro (name, "dhcp_server_name", (char *) bp->server_name,
|
set_env_limn_ro (name, "dhcp_server_name", (char *) bp->server_name,
|
||||||
sizeof (bp->server_name));
|
sizeof (bp->server_name));
|
||||||
if (!default_server)
|
if (is_def && !default_server)
|
||||||
{
|
{
|
||||||
default_server = grub_strdup (bp->server_name);
|
default_server = grub_strdup (bp->server_name);
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_print_error ();
|
||||||
}
|
}
|
||||||
|
if (device && !*device)
|
||||||
|
{
|
||||||
|
*device = grub_xasprintf ("tftp,%s", bp->server_name);
|
||||||
|
grub_print_error ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (!default_server)
|
if (is_def && !default_server)
|
||||||
{
|
{
|
||||||
default_server = grub_xasprintf ("%d.%d.%d.%d",
|
default_server = grub_xasprintf ("%d.%d.%d.%d",
|
||||||
((grub_uint8_t *) &bp->server_ip)[0],
|
((grub_uint8_t *) &bp->server_ip)[0],
|
||||||
((grub_uint8_t *) &bp->server_ip)[1],
|
((grub_uint8_t *) &bp->server_ip)[1],
|
||||||
((grub_uint8_t *) &bp->server_ip)[2],
|
((grub_uint8_t *) &bp->server_ip)[2],
|
||||||
((grub_uint8_t *) &bp->server_ip)[3]);
|
((grub_uint8_t *) &bp->server_ip)[3]);
|
||||||
grub_errno = GRUB_ERR_NONE;
|
grub_print_error ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (device && !*device)
|
||||||
|
{
|
||||||
|
*device = grub_xasprintf ("tftp,%d.%d.%d.%d",
|
||||||
|
((grub_uint8_t *) &bp->server_ip)[0],
|
||||||
|
((grub_uint8_t *) &bp->server_ip)[1],
|
||||||
|
((grub_uint8_t *) &bp->server_ip)[2],
|
||||||
|
((grub_uint8_t *) &bp->server_ip)[3]);
|
||||||
|
grub_print_error ();
|
||||||
|
}
|
||||||
|
if (size > OFFSET_OF (boot_file, bp) && path)
|
||||||
|
{
|
||||||
|
*path = grub_strndup (bp->boot_file, sizeof (bp->boot_file));
|
||||||
|
grub_print_error ();
|
||||||
|
if (*path)
|
||||||
|
{
|
||||||
|
char *slash;
|
||||||
|
slash = grub_strrchr (*path, '/');
|
||||||
|
if (slash)
|
||||||
|
*slash = 0;
|
||||||
|
else
|
||||||
|
**path = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (size > OFFSET_OF (vendor, bp))
|
if (size > OFFSET_OF (vendor, bp))
|
||||||
parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp));
|
parse_dhcp_vendor (name, &bp->vendor, size - OFFSET_OF (vendor, bp));
|
||||||
|
|
||||||
|
@ -1025,7 +1062,7 @@ grub_net_process_dhcp (struct grub_net_buff *nb,
|
||||||
}
|
}
|
||||||
grub_net_configure_by_dhcp_ack (name, card,
|
grub_net_configure_by_dhcp_ack (name, card,
|
||||||
0, (const struct grub_net_bootp_packet *) nb->data,
|
0, (const struct grub_net_bootp_packet *) nb->data,
|
||||||
(nb->tail - nb->data));
|
(nb->tail - nb->data), 0, 0, 0);
|
||||||
grub_free (name);
|
grub_free (name);
|
||||||
if (grub_errno)
|
if (grub_errno)
|
||||||
grub_print_error ();
|
grub_print_error ();
|
||||||
|
|
|
@ -89,6 +89,11 @@
|
||||||
{ 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
|
{ 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define GRUB_EFI_PXE_GUID \
|
||||||
|
{ 0x03c4e603, 0xac28, 0x11d3, \
|
||||||
|
{ 0x9a, 0x2d, 0x00, 0x90, 0x27, 0x3f, 0xc1, 0x4d } \
|
||||||
|
}
|
||||||
|
|
||||||
#define GRUB_EFI_DEVICE_PATH_GUID \
|
#define GRUB_EFI_DEVICE_PATH_GUID \
|
||||||
{ 0x09576e91, 0x6d3f, 0x11d2, \
|
{ 0x09576e91, 0x6d3f, 0x11d2, \
|
||||||
{ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
|
{ 0x8e, 0x39, 0x00, 0xa0, 0xc9, 0x69, 0x72, 0x3b } \
|
||||||
|
@ -1118,6 +1123,36 @@ struct grub_efi_simple_text_output_interface
|
||||||
};
|
};
|
||||||
typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t;
|
typedef struct grub_efi_simple_text_output_interface grub_efi_simple_text_output_interface_t;
|
||||||
|
|
||||||
|
typedef grub_uint8_t grub_efi_pxe_packet_t[1472];
|
||||||
|
|
||||||
|
typedef struct grub_efi_pxe_mode
|
||||||
|
{
|
||||||
|
grub_uint8_t unused[52];
|
||||||
|
grub_efi_pxe_packet_t dhcp_discover;
|
||||||
|
grub_efi_pxe_packet_t dhcp_ack;
|
||||||
|
grub_efi_pxe_packet_t proxy_offer;
|
||||||
|
grub_efi_pxe_packet_t pxe_discover;
|
||||||
|
grub_efi_pxe_packet_t pxe_reply;
|
||||||
|
} grub_efi_pxe_mode_t;
|
||||||
|
|
||||||
|
typedef struct grub_efi_pxe
|
||||||
|
{
|
||||||
|
grub_uint64_t rev;
|
||||||
|
void (*start) (void);
|
||||||
|
void (*stop) (void);
|
||||||
|
void (*dhcp) (void);
|
||||||
|
void (*discover) (void);
|
||||||
|
void (*mftp) (void);
|
||||||
|
void (*udpwrite) (void);
|
||||||
|
void (*udpread) (void);
|
||||||
|
void (*setipfilter) (void);
|
||||||
|
void (*arp) (void);
|
||||||
|
void (*setparams) (void);
|
||||||
|
void (*setstationip) (void);
|
||||||
|
void (*setpackets) (void);
|
||||||
|
struct grub_efi_pxe_mode *mode;
|
||||||
|
} grub_efi_pxe_t;
|
||||||
|
|
||||||
#define GRUB_EFI_BLACK 0x00
|
#define GRUB_EFI_BLACK 0x00
|
||||||
#define GRUB_EFI_BLUE 0x01
|
#define GRUB_EFI_BLUE 0x01
|
||||||
#define GRUB_EFI_GREEN 0x02
|
#define GRUB_EFI_GREEN 0x02
|
||||||
|
|
|
@ -62,6 +62,14 @@ grub_err_t EXPORT_FUNC (grub_efi_set_virtual_address_map) (grub_efi_uintn_t memo
|
||||||
grub_efi_uint32_t descriptor_version,
|
grub_efi_uint32_t descriptor_version,
|
||||||
grub_efi_memory_descriptor_t *virtual_map);
|
grub_efi_memory_descriptor_t *virtual_map);
|
||||||
|
|
||||||
|
int
|
||||||
|
EXPORT_FUNC (grub_efi_compare_device_paths) (const grub_efi_device_path_t *dp1,
|
||||||
|
const grub_efi_device_path_t *dp2);
|
||||||
|
|
||||||
|
extern void (*EXPORT_VAR(grub_efi_net_config)) (grub_efi_handle_t hnd,
|
||||||
|
char **device,
|
||||||
|
char **path);
|
||||||
|
|
||||||
void grub_efi_mm_init (void);
|
void grub_efi_mm_init (void);
|
||||||
void grub_efi_mm_fini (void);
|
void grub_efi_mm_fini (void);
|
||||||
void grub_efi_init (void);
|
void grub_efi_init (void);
|
||||||
|
|
|
@ -109,6 +109,11 @@ struct grub_net_card
|
||||||
grub_net_card_flags_t flags;
|
grub_net_card_flags_t flags;
|
||||||
union
|
union
|
||||||
{
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
struct grub_efi_simple_network *efi_net;
|
||||||
|
void *efi_handle;
|
||||||
|
};
|
||||||
void *data;
|
void *data;
|
||||||
int data_num;
|
int data_num;
|
||||||
};
|
};
|
||||||
|
@ -404,7 +409,8 @@ grub_net_configure_by_dhcp_ack (const char *name,
|
||||||
const struct grub_net_card *card,
|
const struct grub_net_card *card,
|
||||||
grub_net_interface_flags_t flags,
|
grub_net_interface_flags_t flags,
|
||||||
const struct grub_net_bootp_packet *bp,
|
const struct grub_net_bootp_packet *bp,
|
||||||
grub_size_t size);
|
grub_size_t size,
|
||||||
|
int is_def, char **device, char **path);
|
||||||
|
|
||||||
void
|
void
|
||||||
grub_net_process_dhcp (struct grub_net_buff *nb,
|
grub_net_process_dhcp (struct grub_net_buff *nb,
|
||||||
|
|
Loading…
Reference in a new issue