diff options
Diffstat (limited to 'disk')
-rw-r--r-- | disk/part.c | 25 | ||||
-rw-r--r-- | disk/part_dos.c | 26 | ||||
-rw-r--r-- | disk/part_efi.c | 73 |
3 files changed, 92 insertions, 32 deletions
diff --git a/disk/part.c b/disk/part.c index 2827089..baceb19 100644 --- a/disk/part.c +++ b/disk/part.c @@ -86,7 +86,7 @@ block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart) block_dev_desc_t *dev_desc = reloc_get_dev(dev); if (!dev_desc) return NULL; - if (hwpart == -1) + if (hwpart == 0 && !select_hwpart) return dev_desc; if (!select_hwpart) return NULL; @@ -102,7 +102,7 @@ block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart) block_dev_desc_t *get_dev(const char *ifname, int dev) { - return get_dev_hwpart(ifname, dev, -1); + return get_dev_hwpart(ifname, dev, 0); } #else block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart) @@ -460,7 +460,7 @@ int get_device(const char *ifname, const char *dev_hwpart_str, hwpart_str++; } else { dev_str = dev_hwpart_str; - hwpart = -1; + hwpart = 0; } dev = simple_strtoul(dev_str, &ep, 16); @@ -510,6 +510,25 @@ int get_device_and_partition(const char *ifname, const char *dev_part_str, int part; disk_partition_t tmpinfo; + /* + * Special-case a psuedo block device "hostfs", to allow access to the + * host's own filesystem. + */ + if (0 == strcmp(ifname, "hostfs")) { + *dev_desc = NULL; + info->start = 0; + info->size = 0; + info->blksz = 0; + info->bootable = 0; + strcpy((char *)info->type, BOOT_PART_TYPE); + strcpy((char *)info->name, "Sandbox host"); +#ifdef CONFIG_PARTITION_UUIDS + info->uuid[0] = 0; +#endif + + return 0; + } + /* If no dev_part_str, use bootdevice environment variable */ if (!dev_part_str || !strlen(dev_part_str) || !strcmp(dev_part_str, "-")) diff --git a/disk/part_dos.c b/disk/part_dos.c index 05c3933..cf1a36e 100644 --- a/disk/part_dos.c +++ b/disk/part_dos.c @@ -21,6 +21,8 @@ #ifdef HAVE_BLOCK_DEVICE +#define DOS_PART_DEFAULT_SECTOR 512 + /* Convert char[4] in little endian format to the host format integer */ static inline int le32_to_int(unsigned char *le32) @@ -168,6 +170,7 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); dos_partition_t *pt; int i; + int dos_type; if (dev_desc->block_read (dev_desc->dev, ext_part_sector, 1, (ulong *) buffer) != 1) { printf ("** Can't read partition table on %d:%d **\n", @@ -198,9 +201,10 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part (pt->sys_ind != 0) && (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->blksz = DOS_PART_DEFAULT_SECTOR; + 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: @@ -252,6 +256,22 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part part_num, which_part, info, disksig); } } + + /* Check for DOS PBR if no partition is found */ + dos_type = test_block_type(buffer); + + if (dos_type == DOS_PBR) { + info->start = 0; + info->size = dev_desc->lba; + info->blksz = DOS_PART_DEFAULT_SECTOR; + info->bootable = 0; + sprintf ((char *)info->type, "U-Boot"); +#ifdef CONFIG_PARTITION_UUIDS + info->uuid[0] = 0; +#endif + return 0; + } + return -1; } diff --git a/disk/part_efi.c b/disk/part_efi.c index c74b7b9..612f092 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; @@ -185,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 */ @@ -193,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); @@ -279,12 +294,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,8 +315,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; + 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 @@ -321,7 +340,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; } @@ -363,7 +382,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); } @@ -487,12 +507,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__); @@ -500,7 +520,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; } @@ -539,7 +560,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); @@ -547,7 +568,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; } @@ -624,7 +645,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) { |