Skip to content

Commit 522c8b6

Browse files
committed
connectefi: resync with Upstream
Signed-off-by: Renaud Métrich <rmetrich@redhat.com>
1 parent e224ef7 commit 522c8b6

8 files changed

Lines changed: 104 additions & 74 deletions

File tree

NEWS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ New in 2.02:
9898
* Prefer pmtimer for TSC calibration.
9999

100100
* New/improved platform support:
101-
* New `efifwsetup', `lsefi' and `connectefi` commands on EFI platforms.
101+
* New `efifwsetup', `lsefi' commands on EFI platforms.
102102
* New `cmosdump' and `cmosset' commands on platforms with CMOS support.
103103
* New command `pcidump' for PCI platforms.
104104
* Improve opcode parsing in ACPI halt implementation.

docs/grub.texi

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4009,6 +4009,7 @@ you forget a command, you can run the command @command{help}
40094009
* cmostest:: Test bit in CMOS
40104010
* cmp:: Compare two files
40114011
* configfile:: Load a configuration file
4012+
* connectefi:: Connect EFI devices (on EFI platforms only)
40124013
* cpuid:: Check for CPU features
40134014
* crc:: Compute or check CRC32 checksums
40144015
* cryptomount:: Mount a crypto device
@@ -4233,6 +4234,11 @@ syntax}) to grab the first sector of the current partition with @samp{+1}.
42334234
If you specify the option @option{--force}, then load @var{file} forcibly,
42344235
whether it has a correct signature or not. This is required when you want to
42354236
load a defective boot loader, such as SCO UnixWare 7.1.
4237+
4238+
On EFI platforms, when initially network booting, or booting from another disk,
4239+
it may be required to connect the EFI devices using @command{connectefi}
4240+
command (@pxref{connectefi}) prior to chainloading to the disk, otherwise no
4241+
disk may show up or the EFI partition on the disk may not be readable.
42364242
@end deffn
42374243

42384244

@@ -4305,6 +4311,26 @@ after @command{configfile} returns.
43054311
@end deffn
43064312

43074313

4314+
@node connectefi
4315+
@subsection connectefi
4316+
4317+
@deffn Command connectefi pciroot|disk|scsi|all
4318+
When used with @samp{pciroot} parameter, all PCI devices are recursively
4319+
connected, which may be a slow operation, depending on the hardware.
4320+
4321+
When used with @samp{disk} or @samp{scsi} parameter (deprecated), only SCSI I/O
4322+
and DISK I/O devices are connected; this is the recommended usage when
4323+
chainloading to internal disk, unless some disks are not detected anyway, in
4324+
such case @samp{all} may be used and a bug be reported to enhance the
4325+
implementation.
4326+
4327+
When used with @samp{all} parameter, all EFI devices are recursively connected,
4328+
which may be an extremely slow operation, depending on the hardware.
4329+
4330+
Note: This command is only available on EFI platforms.
4331+
@end deffn
4332+
4333+
43084334
@node cpuid
43094335
@subsection cpuid
43104336

grub-core/commands/efi/connectefi.c

Lines changed: 68 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* GRUB -- GRand Unified Bootloader
3-
* Copyright (C) 2022 Free Software Foundation, Inc.
3+
* Copyright (C) 2025 Free Software Foundation, Inc.
44
*
55
* GRUB is free software: you can redistribute it and/or modify
66
* it under the terms of the GNU General Public License as published by
@@ -15,6 +15,7 @@
1515
* You should have received a copy of the GNU General Public License
1616
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
1717
*/
18+
1819
#include <grub/types.h>
1920
#include <grub/mm.h>
2021
#include <grub/misc.h>
@@ -27,100 +28,120 @@
2728

2829
GRUB_MOD_LICENSE ("GPLv3+");
2930

30-
struct grub_efi_already_handled
31+
grub_efi_status_t
32+
grub_efi_connect_controller (grub_efi_handle_t controller_handle,
33+
grub_efi_handle_t *driver_image_handle,
34+
grub_efi_device_path_protocol_t *remaining_device_path,
35+
grub_efi_boolean_t recursive)
36+
{
37+
grub_efi_boot_services_t *b;
38+
39+
b = grub_efi_system_table->boot_services;
40+
return efi_call_4 (b->connect_controller, controller_handle,
41+
driver_image_handle, remaining_device_path, recursive);
42+
}
43+
44+
struct grub_efi_handle_list
3145
{
32-
struct grub_efi_already_handled *next;
33-
struct grub_efi_already_handled **prev;
46+
struct grub_efi_handle_list *next;
47+
struct grub_efi_handle_list **prev;
3448
grub_efi_handle_t handle;
3549
};
3650

37-
static struct grub_efi_already_handled *already_handled;
51+
typedef struct grub_efi_handle_list grub_efi_handle_list_t;
3852

39-
static struct grub_efi_already_handled *
40-
is_in_list (grub_efi_handle_t handle)
53+
static bool
54+
is_in_list (grub_efi_handle_t handle, grub_efi_handle_list_t *handles)
4155
{
42-
struct grub_efi_already_handled *e;
56+
grub_efi_handle_list_t *e;
4357

44-
FOR_LIST_ELEMENTS (e, already_handled)
58+
FOR_LIST_ELEMENTS (e, handles)
4559
if (e->handle == handle)
46-
return e;
60+
return true;
4761

48-
return NULL;
62+
return false;
4963
}
5064

5165
static void
52-
free_handle_list (void)
66+
free_handle_list (grub_efi_handle_list_t **handles_p)
5367
{
54-
struct grub_efi_already_handled *e;
55-
while ((e = already_handled) != NULL)
68+
grub_efi_handle_list_t *e;
69+
70+
while ((e = *handles_p) != NULL)
5671
{
57-
already_handled = already_handled->next;
72+
*handles_p = e->next;
5873
grub_free (e);
5974
}
6075
}
6176

62-
typedef enum searched_item_flag
77+
enum searched_item_flag
6378
{
6479
SEARCHED_ITEM_FLAG_LOOP = 1,
6580
SEARCHED_ITEM_FLAG_RECURSIVE = 2
66-
} searched_item_flags;
81+
};
82+
83+
typedef enum searched_item_flag searched_item_flag_t;
6784

68-
typedef struct searched_item
85+
struct searched_item
6986
{
7087
grub_efi_guid_t guid;
7188
const char *name;
72-
searched_item_flags flags;
73-
} searched_items;
89+
searched_item_flag_t flags;
90+
};
91+
92+
typedef struct searched_item searched_item_t;
7493

7594
static grub_err_t
7695
grub_cmd_connectefi (grub_command_t cmd __attribute__ ((unused)),
7796
int argc, char **args)
7897
{
79-
unsigned s;
80-
searched_items pciroot_items[] =
98+
int s;
99+
searched_item_t pciroot_items[] =
81100
{
82101
{ GRUB_EFI_PCI_ROOT_IO_GUID, "PCI root", SEARCHED_ITEM_FLAG_RECURSIVE }
83102
};
84-
searched_items disk_items[] =
103+
searched_item_t disk_items[] =
85104
{
86105
{ GRUB_EFI_PCI_ROOT_IO_GUID, "PCI root", 0 },
87106
{ GRUB_EFI_PCI_IO_GUID, "PCI", SEARCHED_ITEM_FLAG_LOOP },
88107
{ GRUB_EFI_SCSI_IO_PROTOCOL_GUID, "SCSI I/O", SEARCHED_ITEM_FLAG_RECURSIVE },
89108
{ GRUB_EFI_DISK_IO_PROTOCOL_GUID, "DISK I/O", SEARCHED_ITEM_FLAG_RECURSIVE }
90109
};
91-
searched_items *items = NULL;
92-
unsigned nitems = 0;
110+
searched_item_t *items = NULL;
111+
int nitems = 0;
93112
grub_err_t grub_err = GRUB_ERR_NONE;
94-
unsigned total_connected = 0;
113+
bool connected_devices = false;
114+
grub_efi_handle_list_t *already_handled = NULL;
95115

96116
if (argc != 1)
97117
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
98118

99-
if (grub_strcmp(args[0], "pciroot") == 0)
119+
if (grub_strcmp (args[0], "pciroot") == 0)
100120
{
101121
items = pciroot_items;
102122
nitems = ARRAY_SIZE (pciroot_items);
103123
}
104-
else if ((grub_strcmp(args[0], "disk") == 0) ||
105-
(grub_strcmp(args[0], "scsi") == 0))
124+
else if ((grub_strcmp (args[0], "disk") == 0) ||
125+
(grub_strcmp (args[0], "scsi") == 0))
106126
{
107127
items = disk_items;
108128
nitems = ARRAY_SIZE (disk_items);
109129
}
110-
else if (grub_strcmp(args[0], N_("all")) == 0)
130+
else if (grub_strcmp (args[0], "all") == 0)
111131
{
112132
items = NULL;
113133
nitems = 1;
114134
}
115135
else
116136
return grub_error (GRUB_ERR_BAD_ARGUMENT,
117-
N_("unexpected argument `%s'"), args[0]);
137+
N_("unexpected argument: `%s'"), args[0]);
118138

119139
for (s = 0; s < nitems; s++)
120140
{
121141
grub_efi_handle_t *handles;
122142
grub_efi_uintn_t num_handles;
123-
unsigned i, connected = 0, loop = 0;
143+
int i, loop = 0;
144+
bool connected = false;
124145

125146
loop:
126147
loop++;
@@ -141,30 +162,31 @@ grub_cmd_connectefi (grub_command_t cmd __attribute__ ((unused)),
141162
{
142163
grub_efi_handle_t handle = handles[i];
143164
grub_efi_status_t status;
144-
unsigned j;
165+
int j;
145166

146167
/* Skip already handled handles */
147-
if (is_in_list (handle) != NULL)
168+
if (is_in_list (handle, already_handled))
148169
{
149170
grub_dprintf ("efi", " handle %p: already processed\n",
150171
handle);
151172
continue;
152173
}
153174

154-
status = grub_efi_connect_controller(handle, NULL, NULL,
175+
status = grub_efi_connect_controller (handle, NULL, NULL,
155176
!items || items[s].flags & SEARCHED_ITEM_FLAG_RECURSIVE ? 1 : 0);
156177
if (status == GRUB_EFI_SUCCESS)
157178
{
158-
connected++;
159-
total_connected++;
179+
connected = true;
180+
connected_devices = true;
160181
grub_dprintf ("efi", " handle %p: connected\n", handle);
161182
}
162183
else
163-
grub_dprintf ("efi", " handle %p: failed to connect (%d)\n",
164-
handle, (grub_efi_int8_t) status);
184+
grub_dprintf ("efi", " handle %p: failed to connect ("
185+
PRIuGRUB_EFI_UINTN_T ")\n", handle, status);
165186

166-
struct grub_efi_already_handled *item = grub_malloc(sizeof (*item));
167-
if (!item)
187+
grub_efi_handle_list_t *item;
188+
item = grub_malloc (sizeof (*item));
189+
if (item == NULL)
168190
break; /* fatal */
169191
grub_list_push (GRUB_AS_LIST_P (&already_handled), GRUB_AS_LIST (item));
170192
item->handle = handle;
@@ -176,16 +198,16 @@ grub_cmd_connectefi (grub_command_t cmd __attribute__ ((unused)),
176198

177199
if (items && items[s].flags & SEARCHED_ITEM_FLAG_LOOP && connected)
178200
{
179-
connected = 0;
201+
connected = false;
180202
goto loop;
181203
}
182204

183-
free_handle_list ();
205+
free_handle_list (&already_handled);
184206
}
185207

186-
free_handle_list ();
208+
free_handle_list (&already_handled);
187209

188-
if (total_connected)
210+
if (connected_devices)
189211
grub_efidisk_reenumerate_disks ();
190212

191213
return grub_err;
@@ -196,8 +218,7 @@ static grub_command_t cmd;
196218
GRUB_MOD_INIT(connectefi)
197219
{
198220
cmd = grub_register_command ("connectefi", grub_cmd_connectefi,
199-
/* TRANSLATORS: only translate 'all' keyword */
200-
N_("pciroot|disk|scsi|all"),
221+
"pciroot|disk|scsi|all",
201222
N_("Connect EFI handles."
202223
" If 'pciroot' is specified, connect PCI"
203224
" root EFI handles recursively."

grub-core/commands/efi/lsefi.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* GRUB -- GRand Unified Bootloader
3-
* Copyright (C) 2012 Free Software Foundation, Inc.
3+
* Copyright (C) 2025 Free Software Foundation, Inc.
44
*
55
* GRUB is free software: you can redistribute it and/or modify
66
* it under the terms of the GNU General Public License as published by
@@ -15,6 +15,7 @@
1515
* You should have received a copy of the GNU General Public License
1616
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
1717
*/
18+
1819
#include <grub/types.h>
1920
#include <grub/mm.h>
2021
#include <grub/misc.h>

grub-core/disk/efi/efidisk.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
/*
22
* GRUB -- GRand Unified Bootloader
3-
* Copyright (C) 2006,2007,2008 Free Software Foundation, Inc.
3+
* Copyright (C) 2025 Free Software Foundation, Inc.
44
*
55
* GRUB is free software: you can redistribute it and/or modify
66
* it under the terms of the GNU General Public License as published by
@@ -402,9 +402,9 @@ grub_efidisk_reenumerate_disks (void)
402402
free_devices (fd_devices);
403403
free_devices (hd_devices);
404404
free_devices (cd_devices);
405-
fd_devices = 0;
406-
hd_devices = 0;
407-
cd_devices = 0;
405+
fd_devices = NULL;
406+
hd_devices = NULL;
407+
cd_devices = NULL;
408408

409409
enumerate_disks ();
410410
}

grub-core/kern/efi/efi.c

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* efi.c - generic EFI support */
22
/*
33
* GRUB -- GRand Unified Bootloader
4-
* Copyright (C) 2006,2007,2008,2009,2010 Free Software Foundation, Inc.
4+
* Copyright (C) 2025 Free Software Foundation, Inc.
55
*
66
* GRUB is free software: you can redistribute it and/or modify
77
* it under the terms of the GNU General Public License as published by
@@ -95,19 +95,6 @@ grub_efi_locate_handle (grub_efi_locate_search_type_t search_type,
9595
return buffer;
9696
}
9797

98-
grub_efi_status_t
99-
grub_efi_connect_controller (grub_efi_handle_t controller_handle,
100-
grub_efi_handle_t *driver_image_handle,
101-
grub_efi_device_path_protocol_t *remaining_device_path,
102-
grub_efi_boolean_t recursive)
103-
{
104-
grub_efi_boot_services_t *b;
105-
106-
b = grub_efi_system_table->boot_services;
107-
return efi_call_4 (b->connect_controller, controller_handle,
108-
driver_image_handle, remaining_device_path, recursive);
109-
}
110-
11198
void *
11299
grub_efi_open_protocol (grub_efi_handle_t handle,
113100
grub_efi_guid_t *protocol,

include/grub/efi/api.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* efi.h - declare EFI types and functions */
22
/*
33
* GRUB -- GRand Unified Bootloader
4-
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
4+
* Copyright (C) 2025 Free Software Foundation, Inc.
55
*
66
* GRUB is free software: you can redistribute it and/or modify
77
* it under the terms of the GNU General Public License as published by

include/grub/efi/efi.h

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/* efi.h - declare variables and functions for EFI support */
22
/*
33
* GRUB -- GRand Unified Bootloader
4-
* Copyright (C) 2006,2007,2008,2009 Free Software Foundation, Inc.
4+
* Copyright (C) 2025 Free Software Foundation, Inc.
55
*
66
* GRUB is free software: you can redistribute it and/or modify
77
* it under the terms of the GNU General Public License as published by
@@ -41,11 +41,6 @@ EXPORT_FUNC(grub_efi_locate_handle) (grub_efi_locate_search_type_t search_type,
4141
grub_efi_guid_t *protocol,
4242
void *search_key,
4343
grub_efi_uintn_t *num_handles);
44-
grub_efi_status_t
45-
EXPORT_FUNC(grub_efi_connect_controller) (grub_efi_handle_t controller_handle,
46-
grub_efi_handle_t *driver_image_handle,
47-
grub_efi_device_path_protocol_t *remaining_device_path,
48-
grub_efi_boolean_t recursive);
4944
void *EXPORT_FUNC(grub_efi_open_protocol) (grub_efi_handle_t handle,
5045
grub_efi_guid_t *protocol,
5146
grub_efi_uint32_t attributes);

0 commit comments

Comments
 (0)