diff options
author | H. Nikolaus Schaller <hns@goldelico.com> | 2013-01-10 16:42:11 +0100 |
---|---|---|
committer | H. Nikolaus Schaller <hns@goldelico.com> | 2013-01-10 16:42:11 +0100 |
commit | 1d18c95643416cc9f1577755922e6593b508e8da (patch) | |
tree | 3d30910058cbfbddc388357d29307aaa0a615e90 /u-boot/disk | |
parent | 2f7f1bd2415b74d98cfb8e0a0cd5e6436261de4a (diff) | |
download | bootable_bootloader_goldelico_gta04-1d18c95643416cc9f1577755922e6593b508e8da.zip bootable_bootloader_goldelico_gta04-1d18c95643416cc9f1577755922e6593b508e8da.tar.gz bootable_bootloader_goldelico_gta04-1d18c95643416cc9f1577755922e6593b508e8da.tar.bz2 |
made ext4 and new general ls/load commands work
Diffstat (limited to 'u-boot/disk')
-rwxr-xr-x[-rw-r--r--] | u-boot/disk/part.c | 365 | ||||
-rwxr-xr-x[-rw-r--r--] | u-boot/disk/part_dos.c | 80 | ||||
-rwxr-xr-x[-rw-r--r--] | u-boot/disk/part_dos.h | 9 |
3 files changed, 329 insertions, 125 deletions
diff --git a/u-boot/disk/part.c b/u-boot/disk/part.c index 13723f2..4646f68 100644..100755 --- a/u-boot/disk/part.c +++ b/u-boot/disk/part.c @@ -24,6 +24,7 @@ #include <common.h> #include <command.h> #include <ide.h> +#include <malloc.h> #include <part.h> #undef PART_DEBUG @@ -34,13 +35,15 @@ #define PRINTF(fmt,args...) #endif +/* Rather than repeat this expression each time, add a define for it */ #if (defined(CONFIG_CMD_IDE) || \ - defined(CONFIG_CMD_MG_DISK) || \ defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_SCSI) || \ defined(CONFIG_CMD_USB) || \ defined(CONFIG_MMC) || \ defined(CONFIG_SYSTEMACE) ) +#define HAVE_BLOCK_DEVICE +#endif struct block_drvr { char *name; @@ -66,25 +69,26 @@ static const struct block_drvr block_drvr[] = { #if defined(CONFIG_SYSTEMACE) { .name = "ace", .get_dev = systemace_get_dev, }, #endif -#if defined(CONFIG_CMD_MG_DISK) - { .name = "mgd", .get_dev = mg_disk_get_dev, }, -#endif { }, }; DECLARE_GLOBAL_DATA_PTR; -block_dev_desc_t *get_dev(char* ifname, int dev) +#ifdef HAVE_BLOCK_DEVICE +block_dev_desc_t *get_dev(const char *ifname, int dev) { const struct block_drvr *drvr = block_drvr; block_dev_desc_t* (*reloc_get_dev)(int dev); char *name; + if (!ifname) + return NULL; + name = drvr->name; #ifdef CONFIG_NEEDS_MANUAL_RELOC name += gd->reloc_off; #endif - while (name) { + while (drvr->name) { name = drvr->name; reloc_get_dev = drvr->get_dev; #ifdef CONFIG_NEEDS_MANUAL_RELOC @@ -98,19 +102,13 @@ block_dev_desc_t *get_dev(char* ifname, int dev) return NULL; } #else -block_dev_desc_t *get_dev(char* ifname, int dev) +block_dev_desc_t *get_dev(const char *ifname, int dev) { return NULL; } #endif -#if (defined(CONFIG_CMD_IDE) || \ - defined(CONFIG_CMD_MG_DISK) || \ - defined(CONFIG_CMD_SATA) || \ - defined(CONFIG_CMD_SCSI) || \ - defined(CONFIG_CMD_USB) || \ - defined(CONFIG_MMC) || \ - defined(CONFIG_SYSTEMACE) ) +#ifdef HAVE_BLOCK_DEVICE /* ------------------------------------------------------------------------- */ /* @@ -240,19 +238,7 @@ void dev_print (block_dev_desc_t *dev_desc) } #endif -#if (defined(CONFIG_CMD_IDE) || \ - defined(CONFIG_CMD_MG_DISK) || \ - defined(CONFIG_CMD_SATA) || \ - defined(CONFIG_CMD_SCSI) || \ - defined(CONFIG_CMD_USB) || \ - defined(CONFIG_MMC) || \ - defined(CONFIG_SYSTEMACE) ) - -#if defined(CONFIG_MAC_PARTITION) || \ - defined(CONFIG_DOS_PARTITION) || \ - defined(CONFIG_ISO_PARTITION) || \ - defined(CONFIG_AMIGA_PARTITION) || \ - defined(CONFIG_EFI_PARTITION) +#ifdef HAVE_BLOCK_DEVICE void init_part (block_dev_desc_t * dev_desc) { @@ -291,63 +277,15 @@ void init_part (block_dev_desc_t * dev_desc) return; } #endif + dev_desc->part_type = PART_TYPE_UNKNOWN; } -int get_partition_info (block_dev_desc_t *dev_desc, int part - , disk_partition_t *info) -{ - switch (dev_desc->part_type) { -#ifdef CONFIG_MAC_PARTITION - case PART_TYPE_MAC: - if (get_partition_info_mac(dev_desc,part,info) == 0) { - PRINTF ("## Valid MAC partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_DOS_PARTITION - case PART_TYPE_DOS: - if (get_partition_info_dos(dev_desc,part,info) == 0) { - PRINTF ("## Valid DOS partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_ISO_PARTITION - case PART_TYPE_ISO: - if (get_partition_info_iso(dev_desc,part,info) == 0) { - PRINTF ("## Valid ISO boot partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_AMIGA_PARTITION - case PART_TYPE_AMIGA: - if (get_partition_info_amiga(dev_desc, part, info) == 0) - { - PRINTF ("## Valid Amiga partition found ##\n"); - return (0); - } - break; -#endif - -#ifdef CONFIG_EFI_PARTITION - case PART_TYPE_EFI: - if (get_partition_info_efi(dev_desc,part,info) == 0) { - PRINTF ("## Valid EFI partition found ##\n"); - return (0); - } - break; -#endif - default: - break; - } - return (-1); -} +#if defined(CONFIG_MAC_PARTITION) || \ + defined(CONFIG_DOS_PARTITION) || \ + defined(CONFIG_ISO_PARTITION) || \ + defined(CONFIG_AMIGA_PARTITION) || \ + defined(CONFIG_EFI_PARTITION) static void print_part_header (const char *type, block_dev_desc_t * dev_desc) { @@ -382,6 +320,8 @@ static void print_part_header (const char *type, block_dev_desc_t * dev_desc) dev_desc->dev, type); } +#endif /* any CONFIG_..._PARTITION */ + void print_part (block_dev_desc_t * dev_desc) { @@ -428,11 +368,266 @@ void print_part (block_dev_desc_t * dev_desc) puts ("## Unknown partition table\n"); } +#endif /* HAVE_BLOCK_DEVICE */ -#else /* neither MAC nor DOS nor ISO nor AMIGA nor EFI partition configured */ -# error neither CONFIG_MAC_PARTITION nor CONFIG_DOS_PARTITION -# error nor CONFIG_ISO_PARTITION nor CONFIG_AMIGA_PARTITION -# error nor CONFIG_EFI_PARTITION configured! +int get_partition_info(block_dev_desc_t *dev_desc, int part + , disk_partition_t *info) +{ +#ifdef HAVE_BLOCK_DEVICE + +#ifdef CONFIG_PARTITION_UUIDS + /* The common case is no UUID support */ + info->uuid[0] = 0; #endif + switch (dev_desc->part_type) { +#ifdef CONFIG_MAC_PARTITION + case PART_TYPE_MAC: + if (get_partition_info_mac(dev_desc, part, info) == 0) { + PRINTF("## Valid MAC partition found ##\n"); + return 0; + } + break; #endif + +#ifdef CONFIG_DOS_PARTITION + case PART_TYPE_DOS: + if (get_partition_info_dos(dev_desc, part, info) == 0) { + PRINTF("## Valid DOS partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_ISO_PARTITION + case PART_TYPE_ISO: + if (get_partition_info_iso(dev_desc, part, info) == 0) { + PRINTF("## Valid ISO boot partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_AMIGA_PARTITION + case PART_TYPE_AMIGA: + if (get_partition_info_amiga(dev_desc, part, info) == 0) { + PRINTF("## Valid Amiga partition found ##\n"); + return 0; + } + break; +#endif + +#ifdef CONFIG_EFI_PARTITION + case PART_TYPE_EFI: + if (get_partition_info_efi(dev_desc, part, info) == 0) { + PRINTF("## Valid EFI partition found ##\n"); + return 0; + } + break; +#endif + default: + break; + } +#endif /* HAVE_BLOCK_DEVICE */ + + return -1; +} + +int get_device(const char *ifname, const char *dev_str, + block_dev_desc_t **dev_desc) +{ + char *ep; + int dev; + + dev = simple_strtoul(dev_str, &ep, 16); + if (*ep) { + printf("** Bad device specification %s %s **\n", + ifname, dev_str); + return -1; + } + + *dev_desc = get_dev(ifname, dev); + if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) { + printf("** Bad device %s %s **\n", ifname, dev_str); + return -1; + } + + return dev; +} + +#define PART_UNSPECIFIED -2 +#define PART_AUTO -1 +#define MAX_SEARCH_PARTITIONS 16 +int get_device_and_partition(const char *ifname, const char *dev_part_str, + block_dev_desc_t **dev_desc, + disk_partition_t *info, int allow_whole_dev) +{ + int ret = -1; + const char *part_str; + char *dup_str = NULL; + const char *dev_str; + int dev; + char *ep; + int p; + int part; + disk_partition_t tmpinfo; + + /* If no dev_part_str, use bootdevice environment variable */ + if (!dev_part_str || !strlen(dev_part_str) || + !strcmp(dev_part_str, "-")) + dev_part_str = getenv("bootdevice"); + + /* If still no dev_part_str, it's an error */ + if (!dev_part_str) { + printf("** No device specified **\n"); + goto cleanup; + } + + /* Separate device and partition ID specification */ + part_str = strchr(dev_part_str, ':'); + if (part_str) { + dup_str = strdup(dev_part_str); + dup_str[part_str - dev_part_str] = 0; + dev_str = dup_str; + part_str++; + } else { + dev_str = dev_part_str; + } + + /* Look up the device */ + dev = get_device(ifname, dev_str, dev_desc); + if (dev < 0) + goto cleanup; + + /* Convert partition ID string to number */ + if (!part_str || !*part_str) { + part = PART_UNSPECIFIED; + } else if (!strcmp(part_str, "auto")) { + part = PART_AUTO; + } else { + /* Something specified -> use exactly that */ + part = (int)simple_strtoul(part_str, &ep, 16); + /* + * Less than whole string converted, + * or request for whole device, but caller requires partition. + */ + if (*ep || (part == 0 && !allow_whole_dev)) { + printf("** Bad partition specification %s %s **\n", + ifname, dev_part_str); + goto cleanup; + } + } + + /* + * No partition table on device, + * or user requested partition 0 (entire device). + */ + if (((*dev_desc)->part_type == PART_TYPE_UNKNOWN) || + (part == 0)) { + if (!(*dev_desc)->lba) { + printf("** Bad device size - %s %s **\n", ifname, + dev_str); + goto cleanup; + } + + /* + * If user specified a partition ID other than 0, + * or the calling command only accepts partitions, + * it's an error. + */ + if ((part > 0) || (!allow_whole_dev)) { + printf("** No partition table - %s %s **\n", ifname, + dev_str); + goto cleanup; + } + + info->start = 0; + info->size = (*dev_desc)->lba; + info->blksz = (*dev_desc)->blksz; + info->bootable = 0; + strcpy((char *)info->type, BOOT_PART_TYPE); + strcpy((char *)info->name, "Whole Disk"); +#ifdef CONFIG_PARTITION_UUIDS + info->uuid[0] = 0; +#endif + + ret = 0; + goto cleanup; + } + + /* + * Now there's known to be a partition table, + * not specifying a partition means to pick partition 1. + */ + if (part == PART_UNSPECIFIED) + part = 1; + + /* + * If user didn't specify a partition number, or did specify something + * other than "auto", use that partition number directly. + */ + if (part != PART_AUTO) { + ret = get_partition_info(*dev_desc, part, info); + if (ret) { + printf("** Invalid partition %d **\n", part); + goto cleanup; + } + } else { + /* + * Find the first bootable partition. + * If none are bootable, fall back to the first valid partition. + */ + part = 0; + for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) { + ret = get_partition_info(*dev_desc, p, info); + if (ret) + continue; + + /* + * First valid partition, or new better partition? + * If so, save partition ID. + */ + if (!part || info->bootable) + part = p; + + /* Best possible partition? Stop searching. */ + if (info->bootable) + break; + + /* + * We now need to search further for best possible. + * If we what we just queried was the best so far, + * save the info since we over-write it next loop. + */ + if (part == p) + tmpinfo = *info; + } + /* If we found any acceptable partition */ + if (part) { + /* + * If we searched all possible partition IDs, + * return the first valid partition we found. + */ + if (p == MAX_SEARCH_PARTITIONS + 1) + *info = tmpinfo; + } else { + printf("** No valid partitions found **\n"); + ret = -1; + goto cleanup; + } + } + if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) { + printf("** Invalid partition type \"%.32s\"" + " (expect \"" BOOT_PART_TYPE "\")\n", + info->type); + ret = -1; + goto cleanup; + } + + ret = part; + goto cleanup; + +cleanup: + free(dup_str); + return ret; +} diff --git a/u-boot/disk/part_dos.c b/u-boot/disk/part_dos.c index 2de1bb8..3fe901b 100644..100755 --- a/u-boot/disk/part_dos.c +++ b/u-boot/disk/part_dos.c @@ -36,7 +36,6 @@ #include "part_dos.h" #if defined(CONFIG_CMD_IDE) || \ - defined(CONFIG_CMD_MG_DISK) || \ defined(CONFIG_CMD_SATA) || \ defined(CONFIG_CMD_SCSI) || \ defined(CONFIG_CMD_USB) || \ @@ -61,14 +60,21 @@ static inline int is_extended(int part_type) part_type == 0x85); } -static void print_one_part (dos_partition_t *p, int ext_part_sector, int part_num) +static inline int is_bootable(dos_partition_t *p) +{ + return p->boot_ind == 0x80; +} + +static void print_one_part(dos_partition_t *p, int ext_part_sector, + int part_num, unsigned int disksig) { int lba_start = ext_part_sector + le32_to_int (p->start4); int lba_size = le32_to_int (p->size4); - printf ("%5d\t\t%10d\t%10d\t%2x%s\n", - part_num, lba_start, lba_size, p->sys_ind, - (is_extended (p->sys_ind) ? " Extd" : "")); + printf("%3d\t%-10d\t%-10d\t%08x-%02x\t%02x%s%s\n", + part_num, lba_start, lba_size, disksig, part_num, p->sys_ind, + (is_extended(p->sys_ind) ? " Extd" : ""), + (is_bootable(p) ? " Boot" : "")); } static int test_block_type(unsigned char *buffer) @@ -87,22 +93,24 @@ static int test_block_type(unsigned char *buffer) int test_part_dos (block_dev_desc_t *dev_desc) { - unsigned char buffer[DEFAULT_SECTOR_SIZE]; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); - if ((dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) || - (buffer[DOS_PART_MAGIC_OFFSET + 0] != 0x55) || - (buffer[DOS_PART_MAGIC_OFFSET + 1] != 0xaa) ) { - return (-1); - } - return (0); + if (dev_desc->block_read(dev_desc->dev, 0, 1, (ulong *) buffer) != 1) + return -1; + + if (test_block_type(buffer) != DOS_MBR) + return -1; + + return 0; } /* Print a partition that is relative to its Extended partition table */ -static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_sector, int relative, - int part_num) +static void print_partition_extended(block_dev_desc_t *dev_desc, + int ext_part_sector, int relative, + int part_num, unsigned int disksig) { - unsigned char buffer[DEFAULT_SECTOR_SIZE]; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); dos_partition_t *pt; int i; @@ -112,17 +120,16 @@ static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_s return; } i=test_block_type(buffer); - if(i==-1) { + if (i != DOS_MBR) { printf ("bad MBR sector signature 0x%02x%02x\n", buffer[DOS_PART_MAGIC_OFFSET], buffer[DOS_PART_MAGIC_OFFSET + 1]); return; } - if(i==DOS_PBR) { - printf (" 1\t\t 0\t%10ld\t%2x\n", - dev_desc->lba, buffer[DOS_PBR_MEDIA_TYPE_OFFSET]); - return; - } + + if (!ext_part_sector) + disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]); + /* Print all primary/logical partitions */ pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); for (i = 0; i < 4; i++, pt++) { @@ -133,7 +140,7 @@ static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_s if ((pt->sys_ind != 0) && (ext_part_sector == 0 || !is_extended (pt->sys_ind)) ) { - print_one_part (pt, ext_part_sector, part_num); + print_one_part(pt, ext_part_sector, part_num, disksig); } /* Reverse engr the fdisk part# assignment rule! */ @@ -149,10 +156,9 @@ static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_s if (is_extended (pt->sys_ind)) { int lba_start = le32_to_int (pt->start4) + relative; - print_partition_extended (dev_desc, lba_start, - ext_part_sector == 0 ? lba_start - : relative, - part_num); + print_partition_extended(dev_desc, lba_start, + ext_part_sector == 0 ? lba_start : relative, + part_num, disksig); } } @@ -164,9 +170,10 @@ static void print_partition_extended (block_dev_desc_t *dev_desc, int ext_part_s */ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part_sector, int relative, int part_num, - int which_part, disk_partition_t *info) + int which_part, disk_partition_t *info, + unsigned int disksig) { - unsigned char buffer[DEFAULT_SECTOR_SIZE]; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz); dos_partition_t *pt; int i; @@ -183,6 +190,11 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part return -1; } +#ifdef CONFIG_PARTITION_UUIDS + if (!ext_part_sector) + disksig = le32_to_int(&buffer[DOS_PART_DISKSIG_OFFSET]); +#endif + /* Print all primary/logical partitions */ pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET); for (i = 0; i < 4; i++, pt++) { @@ -223,6 +235,10 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part } /* sprintf(info->type, "%d, pt->sys_ind); */ sprintf ((char *)info->type, "U-Boot"); + info->bootable = is_bootable(pt); +#ifdef CONFIG_PARTITION_UUIDS + sprintf(info->uuid, "%08x-%02x", disksig, part_num); +#endif return 0; } @@ -241,7 +257,7 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part return get_partition_info_extended (dev_desc, lba_start, ext_part_sector == 0 ? lba_start : relative, - part_num, which_part, info); + part_num, which_part, info, disksig); } } return -1; @@ -249,13 +265,13 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_part void print_part_dos (block_dev_desc_t *dev_desc) { - printf ("Partition Start Sector Num Sectors Type\n"); - print_partition_extended (dev_desc, 0, 0, 1); + printf("Part\tStart Sector\tNum Sectors\tUUID\t\tType\n"); + print_partition_extended(dev_desc, 0, 0, 1, 0); } int get_partition_info_dos (block_dev_desc_t *dev_desc, int part, disk_partition_t * info) { - return get_partition_info_extended (dev_desc, 0, 0, 1, part, info); + return get_partition_info_extended(dev_desc, 0, 0, 1, part, info, 0); } diff --git a/u-boot/disk/part_dos.h b/u-boot/disk/part_dos.h index 195a32c..7b77c1d 100644..100755 --- a/u-boot/disk/part_dos.h +++ b/u-boot/disk/part_dos.h @@ -24,14 +24,7 @@ #ifndef _DISK_PART_DOS_H #define _DISK_PART_DOS_H - -#ifdef CONFIG_ISO_PARTITION -/* Make the buffers bigger if ISO partition support is enabled -- CD-ROMS - have 2048 byte blocks */ -#define DEFAULT_SECTOR_SIZE 2048 -#else -#define DEFAULT_SECTOR_SIZE 512 -#endif +#define DOS_PART_DISKSIG_OFFSET 0x1b8 #define DOS_PART_TBL_OFFSET 0x1be #define DOS_PART_MAGIC_OFFSET 0x1fe #define DOS_PBR_FSTYPE_OFFSET 0x36 |