Commit 8c3df0bf2e530c6e6f592f5144ef4f456c9e0260

Authored by Alexander Graf
Committed by Tom Rini
1 parent 4a12a97c14

efi_loader: Add el torito support

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@suse.de>

Showing 2 changed files with 49 additions and 0 deletions Side-by-side Diff

... ... @@ -194,12 +194,26 @@
194 194  
195 195 void efi_set_bootdev(const char *dev, const char *devnr)
196 196 {
  197 + __maybe_unused struct blk_desc *desc;
197 198 char devname[16] = { 0 }; /* dp->str is u16[16] long */
198 199 char *colon;
199 200  
200 201 /* Assemble the condensed device name we use in efi_disk.c */
201 202 snprintf(devname, sizeof(devname), "%s%s", dev, devnr);
202 203 colon = strchr(devname, ':');
  204 +
  205 +#ifdef CONFIG_ISO_PARTITION
  206 + /* For ISOs we create partition block devices */
  207 + desc = blk_get_dev(dev, simple_strtol(devnr, NULL, 10));
  208 + if (desc && (desc->type != DEV_TYPE_UNKNOWN) &&
  209 + (desc->part_type == PART_TYPE_ISO)) {
  210 + if (!colon)
  211 + snprintf(devname, sizeof(devname), "%s%s:1", dev,
  212 + devnr);
  213 + colon = NULL;
  214 + }
  215 +#endif
  216 +
203 217 if (colon)
204 218 *colon = '\0';
205 219  
lib/efi_loader/efi_disk.c
... ... @@ -27,6 +27,8 @@
27 27 struct efi_block_io_media media;
28 28 /* EFI device path to this block device */
29 29 struct efi_device_path_file_path *dp;
  30 + /* Offset into disk for simple partitions */
  31 + lbaint_t offset;
30 32 };
31 33  
32 34 static efi_status_t efi_disk_open_block(void *handle, efi_guid_t *protocol,
... ... @@ -81,6 +83,7 @@
81 83 return EFI_EXIT(EFI_DEVICE_ERROR);
82 84 blksz = desc->blksz;
83 85 blocks = buffer_size / blksz;
  86 + lba += diskobj->offset;
84 87  
85 88 #ifdef DEBUG_EFI
86 89 printf("EFI: %s:%d blocks=%x lba=%"PRIx64" blksz=%x dir=%d\n", __func__,
... ... @@ -159,6 +162,7 @@
159 162 diskobj->ops = block_io_disk_template;
160 163 diskobj->ifname = cur_drvr->name;
161 164 diskobj->dev_index = dev_index;
  165 + diskobj->offset = offset;
162 166  
163 167 /* Fill in EFI IO Media info (for read/write callbacks) */
164 168 diskobj->media.removable_media = desc->removable;
... ... @@ -184,6 +188,31 @@
184 188 list_add_tail(&diskobj->parent.link, &efi_obj_list);
185 189 }
186 190  
  191 +static int efi_disk_create_eltorito(struct blk_desc *desc,
  192 + const struct block_drvr *cur_drvr,
  193 + int diskid)
  194 +{
  195 + int disks = 0;
  196 +#ifdef CONFIG_ISO_PARTITION
  197 + char devname[16] = { 0 }; /* dp->str is u16[16] long */
  198 + disk_partition_t info;
  199 + int part = 1;
  200 +
  201 + if (desc->part_type != PART_TYPE_ISO)
  202 + return 0;
  203 +
  204 + while (!part_get_info(desc, part, &info)) {
  205 + snprintf(devname, sizeof(devname), "%s%d:%d", cur_drvr->name,
  206 + diskid, part);
  207 + efi_disk_add_dev(devname, cur_drvr, desc, diskid, info.start);
  208 + part++;
  209 + disks++;
  210 + }
  211 +#endif
  212 +
  213 + return disks;
  214 +}
  215 +
187 216 /*
188 217 * U-Boot doesn't have a list of all online disk devices. So when running our
189 218 * EFI payload, we scan through all of the potentially available ones and
... ... @@ -214,6 +243,12 @@
214 243 cur_drvr->name, i);
215 244 efi_disk_add_dev(devname, cur_drvr, desc, i, 0);
216 245 disks++;
  246 +
  247 + /*
  248 + * El Torito images show up as block devices
  249 + * in an EFI world, so let's create them here
  250 + */
  251 + disks += efi_disk_create_eltorito(desc, cur_drvr, i);
217 252 }
218 253 }
219 254 printf("Found %d disks\n", disks);