[U-Boot] [PATCH 5/8] efi_loader: Add el torito support

Alexander Graf agraf at suse.de
Mon Apr 11 16:16:18 CEST 2016


When loading an el torito image, uEFI exposes said image as a raw
block device to the payload.

Let's do the same by creating new block devices with added offsets for
the respective el torito partitions.

Signed-off-by: Alexander Graf <agraf at suse.de>
---
 cmd/bootefi.c             | 14 ++++++++++++++
 lib/efi_loader/efi_disk.c | 35 +++++++++++++++++++++++++++++++++++
 2 files changed, 49 insertions(+)

diff --git a/cmd/bootefi.c b/cmd/bootefi.c
index 3add632..0d09aa1 100644
--- a/cmd/bootefi.c
+++ b/cmd/bootefi.c
@@ -194,12 +194,26 @@ U_BOOT_CMD(
 
 void efi_set_bootdev(const char *dev, const char *devnr)
 {
+	__maybe_unused struct blk_desc *desc;
 	char devname[16] = { 0 }; /* dp->str is u16[16] long */
 	char *colon;
 
 	/* Assemble the condensed device name we use in efi_disk.c */
 	snprintf(devname, sizeof(devname), "%s%s", dev, devnr);
 	colon = strchr(devname, ':');
+
+#ifdef CONFIG_ISO_PARTITION
+	/* For ISOs we create partition block devices */
+	desc = blk_get_dev(dev, simple_strtol(devnr, NULL, 10));
+	if (desc && (desc->type != DEV_TYPE_UNKNOWN) &&
+	    (desc->part_type == PART_TYPE_ISO)) {
+		if (!colon)
+			snprintf(devname, sizeof(devname), "%s%s:1", dev,
+				 devnr);
+		colon = NULL;
+	}
+#endif
+
 	if (colon)
 		*colon = '\0';
 
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c
index e30e728..b3d56a8 100644
--- a/lib/efi_loader/efi_disk.c
+++ b/lib/efi_loader/efi_disk.c
@@ -27,6 +27,8 @@ struct efi_disk_obj {
 	struct efi_block_io_media media;
 	/* EFI device path to this block device */
 	struct efi_device_path_file_path *dp;
+	/* Offset into disk for simple partitions */
+	lbaint_t offset;
 };
 
 static efi_status_t efi_disk_open_block(void *handle, efi_guid_t *protocol,
@@ -81,6 +83,7 @@ static efi_status_t EFIAPI efi_disk_rw_blocks(struct efi_block_io *this,
 		return EFI_EXIT(EFI_DEVICE_ERROR);
 	blksz = desc->blksz;
 	blocks = buffer_size / blksz;
+	lba += diskobj->offset;
 
 #ifdef DEBUG_EFI
 	printf("EFI: %s:%d blocks=%x lba=%"PRIx64" blksz=%x dir=%d\n", __func__,
@@ -159,6 +162,7 @@ static void efi_disk_add_dev(char *name,
 	diskobj->ops = block_io_disk_template;
 	diskobj->ifname = cur_drvr->name;
 	diskobj->dev_index = dev_index;
+	diskobj->offset = offset;
 
 	/* Fill in EFI IO Media info (for read/write callbacks) */
 	diskobj->media.removable_media = desc->removable;
@@ -184,6 +188,31 @@ static void efi_disk_add_dev(char *name,
 	list_add_tail(&diskobj->parent.link, &efi_obj_list);
 }
 
+static int efi_disk_create_eltorito(struct blk_desc *desc,
+				    const struct block_drvr *cur_drvr,
+				    int diskid)
+{
+	int disks = 0;
+#ifdef CONFIG_ISO_PARTITION
+	char devname[16] = { 0 }; /* dp->str is u16[16] long */
+	disk_partition_t info;
+	int part = 1;
+
+	if (desc->part_type != PART_TYPE_ISO)
+		return 0;
+
+	while (!part_get_info(desc, part, &info)) {
+		snprintf(devname, sizeof(devname), "%s%d:%d", cur_drvr->name,
+			 diskid, part);
+		efi_disk_add_dev(devname, cur_drvr, desc, diskid, info.start);
+		part++;
+		disks++;
+	}
+#endif
+
+	return disks;
+}
+
 /*
  * U-Boot doesn't have a list of all online disk devices. So when running our
  * EFI payload, we scan through all of the potentially available ones and
@@ -214,6 +243,12 @@ int efi_disk_register(void)
 				 cur_drvr->name, i);
 			efi_disk_add_dev(devname, cur_drvr, desc, i, 0);
 			disks++;
+
+			/*
+			 * El Torito images show up as block devices
+			 * in an EFI world, so let's create them here
+			 */
+			disks += efi_disk_create_eltorito(desc, cur_drvr, i);
 		}
 	}
 	printf("Found %d disks\n", disks);
-- 
1.8.5.6



More information about the U-Boot mailing list