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>
This commit is contained in:
parent
4a12a97c14
commit
8c3df0bf2e
@ -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';
|
||||
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user