[U-Boot] [PATCH v2] efi: Export mbr partition for EFI.

While MBR partition isn't supposed to work in a EFI environment some board rely partially or fully on MBR (BeagleBone, RPI and probably others). This export the MBR partition as logical partition which is useful to efi application that cannot read raw disks.
Signed-off-by: Emmanuel Vadot manu@bidouilliste.com --- Changes in v2: * Pass correct arg to efi_disk_create_mbr
lib/efi_loader/efi_disk.c | 59 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 9 deletions(-)
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 39e602a868..097bb544d7 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -197,11 +197,13 @@ static void efi_disk_add_dev(const char *name, const char *if_typename, const struct blk_desc *desc, int dev_index, - lbaint_t offset) + disk_partition_t *info, + int logical_partition) { struct efi_disk_obj *diskobj; struct efi_device_path_file_path *dp; int objlen = sizeof(*diskobj) + (sizeof(*dp) * 2); + static int mediaid;
/* Don't add empty devices */ if (!desc->lba) @@ -218,16 +220,26 @@ static void efi_disk_add_dev(const char *name, diskobj->ops = block_io_disk_template; diskobj->ifname = if_typename; diskobj->dev_index = dev_index; - diskobj->offset = offset; + if (info) + diskobj->offset = info->start; + diskobj->desc = desc;
/* Fill in EFI IO Media info (for read/write callbacks) */ diskobj->media.removable_media = desc->removable; diskobj->media.media_present = 1; - diskobj->media.block_size = desc->blksz; - diskobj->media.io_align = desc->blksz; - diskobj->media.last_block = desc->lba - offset; + diskobj->media.media_id = mediaid++; diskobj->ops.media = &diskobj->media; + if (logical_partition) { + diskobj->media.logical_partition = 1; + diskobj->media.block_size = info->blksz; + diskobj->media.io_align = info->blksz; + diskobj->media.last_block = info->size - 1; + } else { + diskobj->media.block_size = desc->blksz; + diskobj->media.io_align = desc->blksz; + diskobj->media.last_block = desc->lba; + }
/* Fill in device path */ dp = (void*)&diskobj[1]; @@ -262,8 +274,33 @@ static int efi_disk_create_eltorito(struct blk_desc *desc, while (!part_get_info(desc, part, &info)) { snprintf(devname, sizeof(devname), "%s:%d", pdevname, part); - efi_disk_add_dev(devname, if_typename, desc, diskid, - info.start); + efi_disk_add_dev(devname, if_typename, desc, diskid, 0, 0); + part++; + disks++; + } +#endif + + return disks; +} + +static int efi_disk_create_mbr(struct blk_desc *desc, + const char *if_typename, + int diskid) +{ + int disks = 0; +#if CONFIG_IS_ENABLED(DOS_PARTITION) + char devname[32] = { 0 }; /* dp->str is u16[32] long */ + disk_partition_t info; + int part = 1; + + if (desc->part_type != PART_TYPE_DOS) + return 0; + + while (!part_get_info(desc, part, &info)) { + snprintf(devname, sizeof(devname), "%s%d:%d", if_typename, + diskid, part); + + efi_disk_add_dev(devname, if_typename, desc, diskid, &info, 1); part++; disks++; } @@ -296,9 +333,11 @@ int efi_disk_register(void) const char *if_typename = dev->driver->name;
printf("Scanning disk %s...\n", dev->name); - efi_disk_add_dev(dev->name, if_typename, desc, desc->devnum, 0); + efi_disk_add_dev(dev->name, if_typename, desc, desc->devnum, + NULL, 0); disks++;
+ disks += efi_disk_create_mbr(desc, if_typename, desc->devnum); /* * El Torito images show up as block devices in an EFI world, * so let's create them here @@ -332,15 +371,17 @@ int efi_disk_register(void)
snprintf(devname, sizeof(devname), "%s%d", if_typename, i); - efi_disk_add_dev(devname, if_typename, desc, i, 0); + efi_disk_add_dev(devname, if_typename, desc, i, 0, 0); disks++;
+ disks += efi_disk_create_mbr(desc, if_typename, i); /* * El Torito images show up as block devices * in an EFI world, so let's create them here */ disks += efi_disk_create_eltorito(desc, if_typename, i, devname); + } } #endif

On 20.06.17 08:35, Emmanuel Vadot wrote:
While MBR partition isn't supposed to work in a EFI environment some
It actually is supposed to work :). I've used it on edk2 based systems a few times already.
board rely partially or fully on MBR (BeagleBone, RPI and probably others). This export the MBR partition as logical partition which is useful to efi application that cannot read raw disks.
Signed-off-by: Emmanuel Vadot manu@bidouilliste.com
I think we should do whatever edk2 does here to stay compatible. Ard, can you please enlighten me what that would be? Does edk2 expose logical partitions as raw disks?
Thanks,
Alex
Changes in v2:
- Pass correct arg to efi_disk_create_mbr
lib/efi_loader/efi_disk.c | 59 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 9 deletions(-)
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 39e602a868..097bb544d7 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -197,11 +197,13 @@ static void efi_disk_add_dev(const char *name, const char *if_typename, const struct blk_desc *desc, int dev_index,
lbaint_t offset)
disk_partition_t *info,
int logical_partition)
{ struct efi_disk_obj *diskobj; struct efi_device_path_file_path *dp; int objlen = sizeof(*diskobj) + (sizeof(*dp) * 2);
static int mediaid;
/* Don't add empty devices */ if (!desc->lba)
@@ -218,16 +220,26 @@ static void efi_disk_add_dev(const char *name, diskobj->ops = block_io_disk_template; diskobj->ifname = if_typename; diskobj->dev_index = dev_index;
- diskobj->offset = offset;
if (info)
diskobj->offset = info->start;
diskobj->desc = desc;
/* Fill in EFI IO Media info (for read/write callbacks) */ diskobj->media.removable_media = desc->removable; diskobj->media.media_present = 1;
- diskobj->media.block_size = desc->blksz;
- diskobj->media.io_align = desc->blksz;
- diskobj->media.last_block = desc->lba - offset;
diskobj->media.media_id = mediaid++; diskobj->ops.media = &diskobj->media;
if (logical_partition) {
diskobj->media.logical_partition = 1;
diskobj->media.block_size = info->blksz;
diskobj->media.io_align = info->blksz;
diskobj->media.last_block = info->size - 1;
} else {
diskobj->media.block_size = desc->blksz;
diskobj->media.io_align = desc->blksz;
diskobj->media.last_block = desc->lba;
}
/* Fill in device path */ dp = (void*)&diskobj[1];
@@ -262,8 +274,33 @@ static int efi_disk_create_eltorito(struct blk_desc *desc, while (!part_get_info(desc, part, &info)) { snprintf(devname, sizeof(devname), "%s:%d", pdevname, part);
efi_disk_add_dev(devname, if_typename, desc, diskid,
info.start);
efi_disk_add_dev(devname, if_typename, desc, diskid, 0, 0);
part++;
disks++;
- }
+#endif
- return disks;
+}
+static int efi_disk_create_mbr(struct blk_desc *desc,
const char *if_typename,
int diskid)
+{
- int disks = 0;
+#if CONFIG_IS_ENABLED(DOS_PARTITION)
- char devname[32] = { 0 }; /* dp->str is u16[32] long */
- disk_partition_t info;
- int part = 1;
- if (desc->part_type != PART_TYPE_DOS)
return 0;
- while (!part_get_info(desc, part, &info)) {
snprintf(devname, sizeof(devname), "%s%d:%d", if_typename,
diskid, part);
part++; disks++; }efi_disk_add_dev(devname, if_typename, desc, diskid, &info, 1);
@@ -296,9 +333,11 @@ int efi_disk_register(void) const char *if_typename = dev->driver->name;
printf("Scanning disk %s...\n", dev->name);
efi_disk_add_dev(dev->name, if_typename, desc, desc->devnum, 0);
efi_disk_add_dev(dev->name, if_typename, desc, desc->devnum,
NULL, 0);
disks++;
disks += efi_disk_create_mbr(desc, if_typename, desc->devnum);
/*
- El Torito images show up as block devices in an EFI world,
- so let's create them here
@@ -332,15 +371,17 @@ int efi_disk_register(void)
snprintf(devname, sizeof(devname), "%s%d", if_typename, i);
efi_disk_add_dev(devname, if_typename, desc, i, 0);
efi_disk_add_dev(devname, if_typename, desc, i, 0, 0); disks++;
disks += efi_disk_create_mbr(desc, if_typename, i); /* * El Torito images show up as block devices * in an EFI world, so let's create them here */ disks += efi_disk_create_eltorito(desc, if_typename, i, devname);
} } #endif

On 20 June 2017 at 13:55, Alexander Graf agraf@suse.de wrote:
On 20.06.17 08:35, Emmanuel Vadot wrote:
While MBR partition isn't supposed to work in a EFI environment some
It actually is supposed to work :). I've used it on edk2 based systems a few times already.
Correct. Even though UEFI reinvented everything including partitioning, the spec mandates support for MBR, GPT and El Torito for platforms that have the ability to boot from SSD/HDD drives and/or optical drives.
board rely partially or fully on MBR (BeagleBone, RPI and probably others). This export the MBR partition as logical partition which is useful to efi application that cannot read raw disks.
Signed-off-by: Emmanuel Vadot manu@bidouilliste.com
I think we should do whatever edk2 does here to stay compatible. Ard, can you please enlighten me what that would be? Does edk2 expose logical partitions as raw disks?
The UEFI partition driver consumes block and disk I/O protocols of raw devices and produces the same protocols for each individual partition that it recognizes.
I hope this answers your question, otherwise could you elaborate?
Changes in v2:
- Pass correct arg to efi_disk_create_mbr
lib/efi_loader/efi_disk.c | 59 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 50 insertions(+), 9 deletions(-)
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index 39e602a868..097bb544d7 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -197,11 +197,13 @@ static void efi_disk_add_dev(const char *name, const char *if_typename, const struct blk_desc *desc, int dev_index,
lbaint_t offset)
disk_partition_t *info,
{ struct efi_disk_obj *diskobj; struct efi_device_path_file_path *dp; int objlen = sizeof(*diskobj) + (sizeof(*dp) * 2);int logical_partition)
static int mediaid; /* Don't add empty devices */ if (!desc->lba)
@@ -218,16 +220,26 @@ static void efi_disk_add_dev(const char *name, diskobj->ops = block_io_disk_template; diskobj->ifname = if_typename; diskobj->dev_index = dev_index;
diskobj->offset = offset;
if (info)
diskobj->offset = info->start;
diskobj->desc = desc; /* Fill in EFI IO Media info (for read/write callbacks) */ diskobj->media.removable_media = desc->removable; diskobj->media.media_present = 1;
diskobj->media.block_size = desc->blksz;
diskobj->media.io_align = desc->blksz;
diskobj->media.last_block = desc->lba - offset;
diskobj->media.media_id = mediaid++; diskobj->ops.media = &diskobj->media;
if (logical_partition) {
diskobj->media.logical_partition = 1;
diskobj->media.block_size = info->blksz;
diskobj->media.io_align = info->blksz;
diskobj->media.last_block = info->size - 1;
} else {
diskobj->media.block_size = desc->blksz;
diskobj->media.io_align = desc->blksz;
diskobj->media.last_block = desc->lba;
} /* Fill in device path */ dp = (void*)&diskobj[1];
@@ -262,8 +274,33 @@ static int efi_disk_create_eltorito(struct blk_desc *desc, while (!part_get_info(desc, part, &info)) { snprintf(devname, sizeof(devname), "%s:%d", pdevname, part);
efi_disk_add_dev(devname, if_typename, desc, diskid,
info.start);
efi_disk_add_dev(devname, if_typename, desc, diskid, 0,
0);
part++;
disks++;
}
+#endif
return disks;
+}
+static int efi_disk_create_mbr(struct blk_desc *desc,
const char *if_typename,
int diskid)
+{
int disks = 0;
+#if CONFIG_IS_ENABLED(DOS_PARTITION)
char devname[32] = { 0 }; /* dp->str is u16[32] long */
disk_partition_t info;
int part = 1;
if (desc->part_type != PART_TYPE_DOS)
return 0;
while (!part_get_info(desc, part, &info)) {
snprintf(devname, sizeof(devname), "%s%d:%d", if_typename,
diskid, part);
efi_disk_add_dev(devname, if_typename, desc, diskid,
&info, 1); part++; disks++; } @@ -296,9 +333,11 @@ int efi_disk_register(void) const char *if_typename = dev->driver->name; printf("Scanning disk %s...\n", dev->name);
efi_disk_add_dev(dev->name, if_typename, desc,
desc->devnum, 0);
efi_disk_add_dev(dev->name, if_typename, desc,
desc->devnum,
NULL, 0); disks++;
disks += efi_disk_create_mbr(desc, if_typename,
desc->devnum); /* * El Torito images show up as block devices in an EFI world, * so let's create them here @@ -332,15 +371,17 @@ int efi_disk_register(void) snprintf(devname, sizeof(devname), "%s%d", if_typename, i);
efi_disk_add_dev(devname, if_typename, desc, i,
0);
efi_disk_add_dev(devname, if_typename, desc, i, 0,
0); disks++;
disks += efi_disk_create_mbr(desc, if_typename,
i); /* * El Torito images show up as block devices * in an EFI world, so let's create them here */ disks += efi_disk_create_eltorito(desc, if_typename, i, devname);
#endif} }

On 20.06.17 14:02, Ard Biesheuvel wrote:
On 20 June 2017 at 13:55, Alexander Graf agraf@suse.de wrote:
On 20.06.17 08:35, Emmanuel Vadot wrote:
While MBR partition isn't supposed to work in a EFI environment some
It actually is supposed to work :). I've used it on edk2 based systems a few times already.
Correct. Even though UEFI reinvented everything including partitioning, the spec mandates support for MBR, GPT and El Torito for platforms that have the ability to boot from SSD/HDD drives and/or optical drives.
board rely partially or fully on MBR (BeagleBone, RPI and probably others). This export the MBR partition as logical partition which is useful to efi application that cannot read raw disks.
Signed-off-by: Emmanuel Vadot manu@bidouilliste.com
I think we should do whatever edk2 does here to stay compatible. Ard, can you please enlighten me what that would be? Does edk2 expose logical partitions as raw disks?
The UEFI partition driver consumes block and disk I/O protocols of raw devices and produces the same protocols for each individual partition that it recognizes.
I hope this answers your question, otherwise could you elaborate?
This basically answers my question, yes.
So we really should just provide block devices for *every* partition type we support, not just MBR as is done in this patch.
Emmanuel, could you please extend the patch to cover all partition label types?
Thanks,
Alex

On Tue, 20 Jun 2017 14:08:08 +0200 Alexander Graf agraf@suse.de wrote:
On 20.06.17 14:02, Ard Biesheuvel wrote:
On 20 June 2017 at 13:55, Alexander Graf agraf@suse.de wrote:
On 20.06.17 08:35, Emmanuel Vadot wrote:
While MBR partition isn't supposed to work in a EFI environment some
It actually is supposed to work :). I've used it on edk2 based systems a few times already.
Correct. Even though UEFI reinvented everything including partitioning, the spec mandates support for MBR, GPT and El Torito for platforms that have the ability to boot from SSD/HDD drives and/or optical drives.
board rely partially or fully on MBR (BeagleBone, RPI and probably others). This export the MBR partition as logical partition which is useful to efi application that cannot read raw disks.
Signed-off-by: Emmanuel Vadot manu@bidouilliste.com
I think we should do whatever edk2 does here to stay compatible. Ard, can you please enlighten me what that would be? Does edk2 expose logical partitions as raw disks?
The UEFI partition driver consumes block and disk I/O protocols of raw devices and produces the same protocols for each individual partition that it recognizes.
I hope this answers your question, otherwise could you elaborate?
This basically answers my question, yes.
So we really should just provide block devices for *every* partition type we support, not just MBR as is done in this patch.
Emmanuel, could you please extend the patch to cover all partition label types?
Thanks,
Alex
I'll add GPT too, do we support/care about other schemes ?

On 20.06.17 14:11, Emmanuel Vadot wrote:
On Tue, 20 Jun 2017 14:08:08 +0200 Alexander Graf agraf@suse.de wrote:
On 20.06.17 14:02, Ard Biesheuvel wrote:
On 20 June 2017 at 13:55, Alexander Graf agraf@suse.de wrote:
On 20.06.17 08:35, Emmanuel Vadot wrote:
While MBR partition isn't supposed to work in a EFI environment some
It actually is supposed to work :). I've used it on edk2 based systems a few times already.
Correct. Even though UEFI reinvented everything including partitioning, the spec mandates support for MBR, GPT and El Torito for platforms that have the ability to boot from SSD/HDD drives and/or optical drives.
board rely partially or fully on MBR (BeagleBone, RPI and probably others). This export the MBR partition as logical partition which is useful to efi application that cannot read raw disks.
Signed-off-by: Emmanuel Vadot manu@bidouilliste.com
I think we should do whatever edk2 does here to stay compatible. Ard, can you please enlighten me what that would be? Does edk2 expose logical partitions as raw disks?
The UEFI partition driver consumes block and disk I/O protocols of raw devices and produces the same protocols for each individual partition that it recognizes.
I hope this answers your question, otherwise could you elaborate?
This basically answers my question, yes.
So we really should just provide block devices for *every* partition type we support, not just MBR as is done in this patch.
Emmanuel, could you please extend the patch to cover all partition label types?
Thanks,
Alex
I'll add GPT too, do we support/care about other schemes ?
Don't we have a generic partition table layer that can just provide them for every type we support?
Alex
participants (3)
-
Alexander Graf
-
Ard Biesheuvel
-
Emmanuel Vadot