Page MenuHomeFreeBSD

D5108.id12824.diff
No OneTemporary

D5108.id12824.diff

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

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)

Event Timeline