[U-Boot] [PATCH 0/3] EFI Partition handling

This series focusses on the EFI Partition handling and provides: - fixes to endianness issues - cleanup of the lbaint_t handling - cleanup of a type that requires u64 - improved clarification of the code by cleaning up the casting - verified support of CONFIG_SYS_64BIT_LBA Also, added new feature: - get_partition_info_efi_by_name(): find a partition entry by name
Tested on ARMv7 and ARMv8. (not tested on Big Endian...)
Steve Rae (3): disk: part_efi: resolve endianness issues disk: part_efi: clarify lbaint_t usage disk: part_efi: add get_partition_info_efi_by_name()
disk/part_dos.c | 5 ++-- disk/part_efi.c | 73 +++++++++++++++++++++++++++++++++++------------------- fs/fat/fat_write.c | 2 +- include/part.h | 11 ++++++++ 4 files changed, 62 insertions(+), 29 deletions(-)

Tested on little endian ARMv7 and ARMv8 configurations
Signed-off-by: Steve Rae srae@broadcom.com ---
disk/part_efi.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/disk/part_efi.c b/disk/part_efi.c index c74b7b9..8c89740 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -279,7 +279,7 @@ int write_gpt_table(block_dev_desc_t *dev_desc, gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
if (dev_desc->block_write(dev_desc->dev, - le32_to_cpu(gpt_h->last_usable_lba + 1), + le32_to_cpu(gpt_h->last_usable_lba) + 1, pte_blk_cnt, gpt_e) != pte_blk_cnt) goto err;
@@ -300,6 +300,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, { u32 offset = (u32)le32_to_cpu(gpt_h->first_usable_lba); ulong start; + u32 last_usable_lba = (u32)le32_to_cpu(gpt_h->last_usable_lba); int i, k; size_t efiname_len, dosname_len; #ifdef CONFIG_PARTITION_UUIDS @@ -321,7 +322,7 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, gpt_e[i].starting_lba = cpu_to_le64(offset); offset += partitions[i].size; } - if (offset >= gpt_h->last_usable_lba) { + if (offset >= last_usable_lba) { printf("Partitions layout exceds disk size\n"); return -1; }

On Mon, May 26, 2014 at 11:52:22AM -0700, Steve Rae wrote:
Tested on little endian ARMv7 and ARMv8 configurations
Signed-off-by: Steve Rae srae@broadcom.com
Applied to u-boot/master, thanks!

- update the comments regarding lbaint_t usage - cleanup casting of values related to the lbaint_t type - cleanup of a type that requires a u64
Tested on little endian ARMv7 and ARMv8 configurations
Signed-off-by: Steve Rae srae@broadcom.com ---
disk/part_dos.c | 5 +++-- disk/part_efi.c | 51 ++++++++++++++++++++++++++------------------------- fs/fat/fat_write.c | 2 +- 3 files changed, 30 insertions(+), 28 deletions(-)
diff --git a/disk/part_dos.c b/disk/part_dos.c index 05c3933..b0c3af5 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -199,8 +199,9 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part (part_num == which_part) && (is_extended(pt->sys_ind) == 0)) { info->blksz = 512; - info->start = ext_part_sector + le32_to_int (pt->start4); - info->size = le32_to_int (pt->size4); + info->start = (lbaint_t)(ext_part_sector + + le32_to_int(pt->start4)); + info->size = (lbaint_t)le32_to_int(pt->size4); switch(dev_desc->if_type) { case IF_TYPE_IDE: case IF_TYPE_SATA: diff --git a/disk/part_efi.c b/disk/part_efi.c index 8c89740..78a3782 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -6,13 +6,9 @@ */
/* - * Problems with CONFIG_SYS_64BIT_LBA: - * - * struct disk_partition.start in include/part.h is sized as ulong. - * When CONFIG_SYS_64BIT_LBA is activated, lbaint_t changes from ulong to uint64_t. - * For now, it is cast back to ulong at assignment. - * - * This limits the maximum size of addressable storage to < 2 Terra Bytes + * NOTE: + * when CONFIG_SYS_64BIT_LBA is not defined, lbaint_t is 32 bits; this + * limits the maximum size of addressable storage to < 2 Terra Bytes */ #include <asm/unaligned.h> #include <common.h> @@ -43,8 +39,8 @@ static inline u32 efi_crc32(const void *buf, u32 len)
static int pmbr_part_valid(struct partition *part); static int is_pmbr_valid(legacy_mbr * mbr); -static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba, - gpt_header * pgpt_head, gpt_entry ** pgpt_pte); +static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba, + gpt_header *pgpt_head, gpt_entry **pgpt_pte); static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc, gpt_header * pgpt_head); static int is_pte_valid(gpt_entry * pte); @@ -169,10 +165,10 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, return -1; }
- /* The ulong casting limits the maximum disk size to 2 TB */ - info->start = (u64)le64_to_cpu(gpt_pte[part - 1].starting_lba); + /* The 'lbaint_t' casting may limit the maximum disk size to 2 TB */ + info->start = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].starting_lba); /* The ending LBA is inclusive, to calculate size, add 1 to it */ - info->size = ((u64)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1) + info->size = (lbaint_t)le64_to_cpu(gpt_pte[part - 1].ending_lba) + 1 - info->start; info->blksz = dev_desc->blksz;
@@ -279,12 +275,14 @@ int write_gpt_table(block_dev_desc_t *dev_desc, gpt_h->header_crc32 = cpu_to_le32(calc_crc32);
if (dev_desc->block_write(dev_desc->dev, - le32_to_cpu(gpt_h->last_usable_lba) + 1, + (lbaint_t)le64_to_cpu(gpt_h->last_usable_lba) + + 1, pte_blk_cnt, gpt_e) != pte_blk_cnt) goto err;
if (dev_desc->block_write(dev_desc->dev, - le32_to_cpu(gpt_h->my_lba), 1, gpt_h) != 1) + (lbaint_t)le64_to_cpu(gpt_h->my_lba), 1, + gpt_h) != 1) goto err;
debug("GPT successfully written to block device!\n"); @@ -298,9 +296,10 @@ int write_gpt_table(block_dev_desc_t *dev_desc, int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, disk_partition_t *partitions, int parts) { - u32 offset = (u32)le32_to_cpu(gpt_h->first_usable_lba); - ulong start; - u32 last_usable_lba = (u32)le32_to_cpu(gpt_h->last_usable_lba); + lbaint_t offset = (lbaint_t)le64_to_cpu(gpt_h->first_usable_lba); + lbaint_t start; + lbaint_t last_usable_lba = (lbaint_t) + le64_to_cpu(gpt_h->last_usable_lba); int i, k; size_t efiname_len, dosname_len; #ifdef CONFIG_PARTITION_UUIDS @@ -364,7 +363,8 @@ int gpt_fill_pte(gpt_header *gpt_h, gpt_entry *gpt_e, gpt_e[i].partition_name[k] = (efi_char16_t)(partitions[i].name[k]);
- debug("%s: name: %s offset[%d]: 0x%x size[%d]: 0x" LBAF "\n", + debug("%s: name: %s offset[%d]: 0x" LBAF + " size[%d]: 0x" LBAF "\n", __func__, partitions[i].name, i, offset, i, partitions[i].size); } @@ -488,12 +488,12 @@ static int is_pmbr_valid(legacy_mbr * mbr) * Description: returns 1 if valid, 0 on error. * If valid, returns pointers to PTEs. */ -static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba, - gpt_header * pgpt_head, gpt_entry ** pgpt_pte) +static int is_gpt_valid(block_dev_desc_t *dev_desc, u64 lba, + gpt_header *pgpt_head, gpt_entry **pgpt_pte) { u32 crc32_backup = 0; u32 calc_crc32; - unsigned long long lastlba; + u64 lastlba;
if (!dev_desc || !pgpt_head) { printf("%s: Invalid Argument(s)\n", __func__); @@ -501,7 +501,8 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba, }
/* Read GPT Header from device */ - if (dev_desc->block_read(dev_desc->dev, lba, 1, pgpt_head) != 1) { + if (dev_desc->block_read(dev_desc->dev, (lbaint_t)lba, 1, pgpt_head) + != 1) { printf("*** ERROR: Can't read GPT header ***\n"); return 0; } @@ -540,7 +541,7 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba, }
/* Check the first_usable_lba and last_usable_lba are within the disk. */ - lastlba = (unsigned long long)dev_desc->lba; + lastlba = (u64)dev_desc->lba; if (le64_to_cpu(pgpt_head->first_usable_lba) > lastlba) { printf("GPT: first_usable_lba incorrect: %llX > %llX\n", le64_to_cpu(pgpt_head->first_usable_lba), lastlba); @@ -548,7 +549,7 @@ static int is_gpt_valid(block_dev_desc_t * dev_desc, unsigned long long lba, } if (le64_to_cpu(pgpt_head->last_usable_lba) > lastlba) { printf("GPT: last_usable_lba incorrect: %llX > %llX\n", - (u64) le64_to_cpu(pgpt_head->last_usable_lba), lastlba); + le64_to_cpu(pgpt_head->last_usable_lba), lastlba); return 0; }
@@ -625,7 +626,7 @@ static gpt_entry *alloc_read_gpt_entries(block_dev_desc_t * dev_desc, /* Read GPT Entries from device */ blk_cnt = BLOCK_CNT(count, dev_desc); if (dev_desc->block_read (dev_desc->dev, - le64_to_cpu(pgpt_head->partition_entry_lba), + (lbaint_t)le64_to_cpu(pgpt_head->partition_entry_lba), (lbaint_t) (blk_cnt), pte) != blk_cnt) {
diff --git a/fs/fat/fat_write.c b/fs/fat/fat_write.c index ba7e3ae..24ed5d3 100644 --- a/fs/fat/fat_write.c +++ b/fs/fat/fat_write.c @@ -947,7 +947,7 @@ static int do_fat_write(const char *filename, void *buffer,
total_sector = bs.total_sect; if (total_sector == 0) - total_sector = cur_part_info.size; + total_sector = (int)cur_part_info.size; /* cast of lbaint_t */
if (mydata->fatsize == 32) mydata->fatlength = bs.fat32_length;

On Mon, May 26, 2014 at 11:52:23AM -0700, Steve Rae wrote:
- update the comments regarding lbaint_t usage
- cleanup casting of values related to the lbaint_t type
- cleanup of a type that requires a u64
Tested on little endian ARMv7 and ARMv8 configurations
Signed-off-by: Steve Rae srae@broadcom.com
Applied to u-boot/master, thanks!

Add function to find a GPT table entry by name.
Tested on little endian ARMv7 and ARMv8 configurations
Signed-off-by: Steve Rae srae@broadcom.com ---
disk/part_efi.c | 21 ++++++++++++++++++++- include/part.h | 11 +++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-)
diff --git a/disk/part_efi.c b/disk/part_efi.c index 78a3782..612f092 100644 --- a/disk/part_efi.c +++ b/disk/part_efi.c @@ -181,7 +181,7 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, UUID_STR_FORMAT_GUID); #endif
- debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s", __func__, + debug("%s: start 0x" LBAF ", size 0x" LBAF ", name %s\n", __func__, info->start, info->size, info->name);
/* Remember to free pte */ @@ -189,6 +189,25 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part, return 0; }
+int get_partition_info_efi_by_name(block_dev_desc_t *dev_desc, + const char *name, disk_partition_t *info) +{ + int ret; + int i; + for (i = 1; i < GPT_ENTRY_NUMBERS; i++) { + ret = get_partition_info_efi(dev_desc, i, info); + if (ret != 0) { + /* no more entries in table */ + return -1; + } + if (strcmp(name, (const char *)info->name) == 0) { + /* matched */ + return 0; + } + } + return -2; +} + int test_part_efi(block_dev_desc_t * dev_desc) { ALLOC_CACHE_ALIGN_BUFFER_PAD(legacy_mbr, legacymbr, 1, dev_desc->blksz); diff --git a/include/part.h b/include/part.h index f2c8c64..a496a4a 100644 --- a/include/part.h +++ b/include/part.h @@ -180,6 +180,17 @@ int test_part_amiga (block_dev_desc_t *dev_desc); #include <part_efi.h> /* disk/part_efi.c */ int get_partition_info_efi (block_dev_desc_t * dev_desc, int part, disk_partition_t *info); +/** + * get_partition_info_efi_by_name() - Find the specified GPT partition table entry + * + * @param dev_desc - block device descriptor + * @param gpt_name - the specified table entry name + * @param info - returns the disk partition info + * + * @return - '0' on match, '-1' on no match, otherwise error + */ +int get_partition_info_efi_by_name(block_dev_desc_t *dev_desc, + const char *name, disk_partition_t *info); void print_part_efi (block_dev_desc_t *dev_desc); int test_part_efi (block_dev_desc_t *dev_desc);

On Mon, May 26, 2014 at 11:52:24AM -0700, Steve Rae wrote:
Add function to find a GPT table entry by name.
Tested on little endian ARMv7 and ARMv8 configurations
Signed-off-by: Steve Rae srae@broadcom.com
Applied to u-boot/master, thanks!
participants (2)
-
Steve Rae
-
Tom Rini