Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F154606082
D5108.id12824.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
D5108.id12824.diff
View Options
Index: sys/boot/efi/boot1/boot1.c
===================================================================
--- sys/boot/efi/boot1/boot1.c
+++ sys/boot/efi/boot1/boot1.c
@@ -51,7 +51,10 @@
EFI_STATUS efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE* Xsystab);
static void try_load(const boot_module_t* mod);
-static EFI_STATUS probe_handle(EFI_HANDLE h);
+static void probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath,
+ BOOLEAN match);
+static EFI_STATUS probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath,
+ BOOLEAN match);
EFI_SYSTEM_TABLE *systab;
EFI_BOOT_SERVICES *bs;
@@ -168,10 +171,42 @@
}
}
+static BOOLEAN
+paths_match(EFI_DEVICE_PATH *imgpath, EFI_DEVICE_PATH *devpath)
+{
+ int len;
+
+ if (imgpath == NULL || imgpath->Type != devpath->Type ||
+ imgpath->SubType != devpath->SubType)
+ return (FALSE);
+
+ len = DevicePathNodeLength(imgpath);
+
+ if (len != DevicePathNodeLength(devpath))
+ return (FALSE);
+
+ return (memcmp(imgpath, devpath, (size_t)len) == 0);
+}
+
+static EFI_DEVICE_PATH *
+messaging_path(EFI_DEVICE_PATH *devpath)
+{
+ while (!IsDevicePathMessaging(devpath) &&
+ !IsDevicePathEnd(NextDevicePathNode(devpath)))
+ devpath = NextDevicePathNode(devpath);
+
+ if (!IsDevicePathMessaging(devpath))
+ return (NULL);
+
+ return (devpath);
+}
+
EFI_STATUS
efi_main(EFI_HANDLE Ximage, EFI_SYSTEM_TABLE *Xsystab)
{
EFI_HANDLE *handles;
+ EFI_LOADED_IMAGE *img;
+ EFI_DEVICE_PATH *imgpath;
EFI_STATUS status;
EFI_CONSOLE_CONTROL_PROTOCOL *ConsoleControl = NULL;
SIMPLE_TEXT_OUTPUT_INTERFACE *conout = NULL;
@@ -254,20 +289,29 @@
/* Scan all partitions, probing with all modules. */
nhandles = hsize / sizeof(*handles);
printf(" Probing %zu block devices...", nhandles);
- for (i = 0; i < nhandles; i++) {
- status = probe_handle(handles[i]);
- switch (status) {
- case EFI_UNSUPPORTED:
- printf(".");
- break;
- case EFI_SUCCESS:
- printf("+");
- break;
- default:
- printf("x");
- break;
+
+ /*
+ * We start by probing handles which match our images media path, so if
+ * possible we boot from a partition on our device.
+ */
+ status = bs->HandleProtocol(image, &LoadedImageGUID, (VOID**)&img);
+ imgpath = NULL;
+ if (status == EFI_SUCCESS) {
+ status = bs->HandleProtocol(img->DeviceHandle, &DevicePathGUID,
+ (void **)&imgpath);
+ if (status == EFI_SUCCESS) {
+ imgpath = messaging_path(imgpath);
+ if (imgpath != NULL) {
+ for (i = 0; i < nhandles; i++)
+ probe_handle_status(handles[i], imgpath,
+ TRUE);
+ }
}
}
+
+ /* Now check for other bootable partitions. */
+ for (i = 0; i < nhandles; i++)
+ probe_handle_status(handles[i], imgpath, FALSE);
printf(" done\n");
/* Status summary. */
@@ -287,13 +331,34 @@
panic("No bootable partitions found!");
}
+static void
+probe_handle_status(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN match)
+{
+
+ switch (probe_handle(h, imgpath, match)) {
+ case EFI_UNSUPPORTED:
+ printf(".");
+ break;
+ case EFI_SUCCESS:
+ printf("%c", match ? '*' : '+');
+ break;
+ case EFI_NOT_FOUND:
+ /* Didn't match or already tested. */
+ break;
+ default:
+ printf("x");
+ break;
+ }
+}
+
static EFI_STATUS
-probe_handle(EFI_HANDLE h)
+probe_handle(EFI_HANDLE h, EFI_DEVICE_PATH *imgpath, BOOLEAN match)
{
dev_info_t *devinfo;
EFI_BLOCK_IO *blkio;
EFI_DEVICE_PATH *devpath;
EFI_STATUS status;
+ BOOLEAN matched;
UINTN i;
/* Figure out if we're dealing with an actual partition. */
@@ -307,8 +372,34 @@
return (status);
}
- while (!IsDevicePathEnd(NextDevicePathNode(devpath)))
+ matched = FALSE;
+ while (!IsDevicePathEnd(NextDevicePathNode(devpath))) {
+ if (IsDevicePathMessaging(devpath) && !matched) {
+ if (match) {
+ if (!paths_match(imgpath, devpath))
+ return (EFI_NOT_FOUND);
+ matched = TRUE;
+ } else if (paths_match(imgpath, devpath)) {
+ /* Already tested. */
+ return (EFI_NOT_FOUND);
+ }
+ }
devpath = NextDevicePathNode(devpath);
+ }
+
+ if (IsDevicePathMessaging(devpath)) {
+ if (match) {
+ if (!paths_match(imgpath, devpath))
+ return (EFI_NOT_FOUND);
+ matched = TRUE;
+ } else if (paths_match(imgpath, devpath)) {
+ /* Already tested. */
+ return (EFI_NOT_FOUND);
+ }
+ }
+
+ if (match && !matched)
+ return (EFI_NOT_FOUND);
status = bs->HandleProtocol(h, &BlockIoProtocolGUID, (void **)&blkio);
if (status == EFI_UNSUPPORTED)
Index: sys/boot/efi/boot1/ufs_module.c
===================================================================
--- sys/boot/efi/boot1/ufs_module.c
+++ sys/boot/efi/boot1/ufs_module.c
@@ -93,7 +93,7 @@
}
static EFI_STATUS
-try_load(dev_info_t *dev, const char *loader_path, void **bufp, size_t *bufsize)
+try_load(dev_info_t *dev, const char *filepath, void **bufp, size_t *bufsize)
{
ufs_ino_t ino;
EFI_STATUS status;
@@ -101,28 +101,36 @@
ssize_t read;
void *buf;
- if (init_dev(dev) < 0)
+ DPRINTF("try_load: MediaId: %d, devpath: %d.%d\n",
+ dev->dev->Media->MediaId, dev->devpath->Type,
+ dev->devpath->SubType);
+
+ if (init_dev(dev) < 0) {
+ DPRINTF("Failed to device %p\n", dev);
return (EFI_UNSUPPORTED);
+ }
- if ((ino = lookup(loader_path)) == 0)
+ if ((ino = lookup(filepath)) == 0) {
+ DPRINTF("Failed to lookup '%s' on %p\n", filepath, dev);
return (EFI_NOT_FOUND);
+ }
if (fsread_size(ino, NULL, 0, &size) < 0 || size <= 0) {
- printf("Failed to read size of '%s' ino: %d\n", loader_path,
+ printf("Failed to read size of '%s' ino: %d\n", filepath,
ino);
return (EFI_INVALID_PARAMETER);
}
if ((status = bs->AllocatePool(EfiLoaderData, size, &buf)) !=
EFI_SUCCESS) {
- printf("Failed to allocate read buffer (%lu)\n",
- EFI_ERROR_CODE(status));
+ printf("Failed to allocate read buffer %zu for '%s' (%lu)\n",
+ size, filepath, EFI_ERROR_CODE(status));
return (status);
}
read = fsread(ino, buf, size);
if ((size_t)read != size) {
- printf("Failed to read '%s' (%zd != %zu)\n", loader_path, read,
+ printf("Failed to read '%s' (%zd != %zu)\n", filepath, read,
size);
(void)bs->FreePool(buf);
return (EFI_INVALID_PARAMETER);
@@ -135,19 +143,16 @@
}
static EFI_STATUS
-load(const char *loader_path, dev_info_t **devinfop, void **buf,
+load(const char *filepath, dev_info_t **devinfop, void **buf,
size_t *bufsize)
{
dev_info_t *dev;
- EFI_STATUS status;
for (dev = devices; dev != NULL; dev = dev->next) {
- status = try_load(dev, loader_path, buf, bufsize);
- if (status == EFI_SUCCESS) {
+ if (try_load(dev, filepath, buf, bufsize) ==
+ EFI_SUCCESS) {
*devinfop = dev;
return (EFI_SUCCESS);
- } else if (status != EFI_NOT_FOUND) {
- return (status);
}
}
Index: sys/boot/efi/boot1/zfs_module.c
===================================================================
--- sys/boot/efi/boot1/zfs_module.c
+++ sys/boot/efi/boot1/zfs_module.c
@@ -91,7 +91,8 @@
}
static EFI_STATUS
-try_load(dev_info_t *devinfo, const char *loader_path, void **bufp, size_t *bufsize)
+try_load(dev_info_t *devinfo, const char *filepath, void **bufp,
+ size_t *bufsize)
{
spa_t *spa;
struct zfsmount zfsmount;
@@ -102,32 +103,42 @@
EFI_STATUS status;
spa = devinfo->devdata;
- if (zfs_spa_init(spa) != 0) {
- /* Init failed, don't report this loudly. */
+
+ DPRINTF("try_load: spa: %s, MediaId: %d, devpath: %d.%d\n",
+ spa->spa_name, devinfo->dev->Media->MediaId, devinfo->devpath->Type,
+ devinfo->devpath->SubType);
+
+ if ((err = zfs_spa_init(spa)) != 0) {
+ DPRINTF("Failed to load pool '%s' (%d)\n", spa->spa_name, err);
return (EFI_NOT_FOUND);
}
- if (zfs_mount(spa, 0, &zfsmount) != 0) {
- /* Mount failed, don't report this loudly. */
+ if ((err = zfs_mount(spa, 0, &zfsmount)) != 0) {
+ DPRINTF("Failed to mount pool '%s' (%d)\n", spa->spa_name, err);
return (EFI_NOT_FOUND);
}
- if ((err = zfs_lookup(&zfsmount, loader_path, &dn)) != 0) {
- printf("Failed to lookup %s on pool %s (%d)\n", loader_path,
+ if ((err = zfs_lookup(&zfsmount, filepath, &dn)) != 0) {
+ if (err == ENOENT) {
+ DPRINTF("Failed to find '%s' on pool '%s' (%d)\n",
+ filepath, spa->spa_name, err);
+ return (EFI_NOT_FOUND);
+ }
+ printf("Failed to lookup '%s' on pool '%s' (%d)\n", filepath,
spa->spa_name, err);
return (EFI_INVALID_PARAMETER);
}
if ((err = zfs_dnode_stat(spa, &dn, &st)) != 0) {
- printf("Failed to lookup %s on pool %s (%d)\n", loader_path,
+ printf("Failed to stat '%s' on pool '%s' (%d)\n", filepath,
spa->spa_name, err);
return (EFI_INVALID_PARAMETER);
}
if ((status = bs->AllocatePool(EfiLoaderData, (UINTN)st.st_size, &buf))
!= EFI_SUCCESS) {
- printf("Failed to allocate load buffer for pool %s (%lu)\n",
- spa->spa_name, EFI_ERROR_CODE(status));
+ printf("Failed to allocate load buffer %zu for pool '%s' for '%s' "
+ "(%lu)\n", st.st_size, spa->spa_name, filepath, EFI_ERROR_CODE(status));
return (EFI_INVALID_PARAMETER);
}
@@ -145,19 +156,16 @@
}
static EFI_STATUS
-load(const char *loader_path, dev_info_t **devinfop, void **bufp,
+load(const char *filepath, dev_info_t **devinfop, void **bufp,
size_t *bufsize)
{
dev_info_t *devinfo;
- EFI_STATUS status;
for (devinfo = devices; devinfo != NULL; devinfo = devinfo->next) {
- status = try_load(devinfo, loader_path, bufp, bufsize);
- if (status == EFI_SUCCESS) {
+ if (try_load(devinfo, filepath, bufp, bufsize) ==
+ EFI_SUCCESS) {
*devinfop = devinfo;
return (EFI_SUCCESS);
- } else if (status != EFI_NOT_FOUND) {
- return (status);
}
}
Index: sys/boot/efi/include/efidevp.h
===================================================================
--- sys/boot/efi/include/efidevp.h
+++ sys/boot/efi/include/efidevp.h
@@ -40,9 +40,7 @@
#define EFI_DP_TYPE_MASK 0x7F
#define EFI_DP_TYPE_UNPACKED 0x80
-//#define END_DEVICE_PATH_TYPE 0xff
#define END_DEVICE_PATH_TYPE 0x7f
-//#define END_DEVICE_PATH_TYPE_UNPACKED 0x7f
#define END_ENTIRE_DEVICE_PATH_SUBTYPE 0xff
#define END_INSTANCE_DEVICE_PATH_SUBTYPE 0x01
@@ -56,8 +54,9 @@
#define DevicePathSubType(a) ( (a)->SubType )
#define DevicePathNodeLength(a) ( ((a)->Length[0]) | ((a)->Length[1] << 8) )
#define NextDevicePathNode(a) ( (EFI_DEVICE_PATH *) ( ((UINT8 *) (a)) + DevicePathNodeLength(a)))
-//#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE_UNPACKED )
-#define IsDevicePathEndType(a) ( DevicePathType(a) == END_DEVICE_PATH_TYPE )
+#define IsDevicePathType(a, t) ( DevicePathType(a) == t )
+#define IsDevicePathEndType(a) IsDevicePathType(a, END_DEVICE_PATH_TYPE)
+#define IsDevicePathMessaging(a) IsDevicePathType(a, MESSAGING_DEVICE_PATH)
#define IsDevicePathEndSubType(a) ( (a)->SubType == END_ENTIRE_DEVICE_PATH_SUBTYPE )
#define IsDevicePathEnd(a) ( IsDevicePathEndType(a) && IsDevicePathEndSubType(a) )
#define IsDevicePathUnpacked(a) ( (a)->Type & EFI_DP_TYPE_UNPACKED )
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 30, 1:00 AM (14 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
32422832
Default Alt Text
D5108.id12824.diff (10 KB)
Attached To
Mode
D5108: Improve EFI multi device boot support
Attached
Detach File
Event Timeline
Log In to Comment