Skip to contentSkip to conversation

add bootable partition support

RFC PATCH New Rob Herring 1 participant 6 messages Mar 6, 2012

lore
Share & tools
lore
#0 lore raw

cover add bootable partition support

From: Rob Herring <[email protected]>

The primary goal of this series is to enable using the 1st bootable partition as the default partition for disk boot related commands. Every command that takes a "<dev>[:<part>]" option duplicates the same parsing code, so this series consolidates the parsing code to a single function.

There are obviously other block device commands that need to be converted still. I will do these once there is some basic agreement on the initial support.

Rob

Rob Herring (5):
disk/part: check bootable flag for DOS partitions disk/part: introduce get_device_and_partition
cmd_ext2: use common get_device_and_partition function
cmd_fat: use common get_device_and_partition function
cmd_scsi: use common get_device_and_partition function

 common/cmd_ext2.c |   71 +++++++++++----------------------------------------
 common/cmd_fat.c  |   72 +++++++++++++++++++---------------------------------
 common/cmd_scsi.c |   58 ++++++++----------------------------------
 disk/part.c       |   60 ++++++++++++++++++++++++++++++++++++++++++++
 disk/part_dos.c   |   11 ++++++-
 include/part.h    |    5 +++
 6 files changed, 127 insertions(+), 150 deletions(-)
Signature · 1 line
1.7.5.4
#1 lore raw

RFC PATCH 1/5 disk/part: check bootable flag for DOS partitions

From: Rob Herring <[email protected]>

Determine which partitions are bootable/active. In the partition listing, print "Boot" for partitions with the bootable/active flag set.

---
 disk/part_dos.c |   11 +++++++++--
 include/part.h  |    1 +
 2 files changed, 10 insertions(+), 2 deletions(-)
disk/part_dos.c +9 -2
index b5bcb37..1620c1d 100644
@@ -61,14 +61,20 @@ static inline int is_extended(int part_type)
 	    part_type == 0x85);
 }
 
+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)
 {
 	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",
+	printf("%5d\t\t%10d\t%10d\t%2x%s%s\n",
 		part_num, lba_start, lba_size, p->sys_ind,
-		(is_extended (p->sys_ind) ? " Extd" : ""));
+		(is_extended(p->sys_ind) ? " Extd" : ""),
+		(is_bootable(p) ? " Boot" : ""));
 }
 
 static int test_block_type(unsigned char *buffer)
@@ -223,6 +229,7 @@ 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);
 			return 0;
 		}
 
include/part.h +1 -0
index 1827767..79a3493 100644
@@ -93,6 +93,7 @@ typedef struct disk_partition {
 	ulong	blksz;		/* block size in bytes			*/
 	uchar	name[32];	/* partition name			*/
 	uchar	type[32];	/* string type description		*/
+	int	bootable;	/* Active/Bootable flag is set		*/
 } disk_partition_t;
 
 /* Misc _get_dev functions */
Signature · 1 line
1.7.5.4
#2 lore raw

RFC PATCH 2/5 disk/part: introduce get_device_and_partition

In reply to Rob Herring

From: Rob Herring <[email protected]>

All block device related commands (scsiboot, fatload, ext2ls, etc.) have simliar duplicated device and partition parsing and selection code. This adds a common function to replace various implementations.

The new function has some enhancements over current versions. If no device or partition is specified on the command line, the bootdevice env variable will be used (scsiboot does this). If the partition is not specified and the device has partitions, then the first bootable partition will be used.

---
 disk/part.c    |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/part.h |    4 +++
 2 files changed, 64 insertions(+), 0 deletions(-)
disk/part.c +60 -0
index f07a17f..e892c8d 100644
@@ -291,6 +291,7 @@ void init_part (block_dev_desc_t * dev_desc)
 	    return;
 	}
 #endif
+	dev_desc->part_type = PART_TYPE_UNKNOWN;
 }
 
 
@@ -435,4 +436,63 @@ void print_part (block_dev_desc_t * dev_desc)
 # error nor CONFIG_EFI_PARTITION configured!
 #endif
 
+int get_device_and_partition(const char *ifname, const char *dev_str,
+			     block_dev_desc_t **dev_desc,
+			     disk_partition_t *info)
+{
+	int ret;
+	char *ep;
+	int dev;
+	block_dev_desc_t *desc;
+	int part = 1;
+	int do_scan_part = 1;
+	char *part_str;
+
+	if (dev_str)
+		dev = simple_strtoul(dev_str, &ep, 16);
+
+	if (!dev_str || (dev_str == ep)) {
+		dev_str = getenv("bootdevice");
+		if (dev_str)
+			dev = simple_strtoul(dev_str, &ep, 16);
+		if (!dev_str || dev_str == ep)
+			goto err;
+	}
+
+	desc = get_dev(ifname, dev);
+	if (!desc || (desc->type == DEV_TYPE_UNKNOWN))
+		goto err;
+
+	if (desc->part_type == PART_TYPE_UNKNOWN)
+		return 0;
+
+	part_str = strchr(dev_str, ':');
+	if (part_str) {
+		part = (int)simple_strtoul(++part_str, NULL, 16);
+		do_scan_part = 0;
+	}
+
+	while ((ret = get_partition_info(desc, part, info)) == 0 &&
+	       !info->bootable && do_scan_part)
+		part++;
+
+	if (ret) {
+		puts("** Invalid partition, use `dev[:part]' **\n");
+		return -1;
+	}
+	if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) {
+		printf("** Invalid partition type \"%.32s\""
+			" (expect \"" BOOT_PART_TYPE "\")\n",
+			info->type);
+		return -1;
+	}
+
+	*dev_desc = desc;
+	return part;
+
+ err:
+	puts("** Invalid boot device, use `dev[:part]' **\n");
+	return -1;
+}
+
 #endif
include/part.h +4 -0
index 79a3493..e44ca49 100644
@@ -129,6 +129,10 @@ static inline void  init_part (block_dev_desc_t *dev_desc) {}
 static inline void dev_print(block_dev_desc_t *dev_desc) {}
 #endif
 
+int get_device_and_partition(const char *ifname, const char *dev_str,
+			     block_dev_desc_t **dev_desc,
+			     disk_partition_t *info);
+
 #ifdef CONFIG_MAC_PARTITION
 /* disk/part_mac.c */
 int get_partition_info_mac (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
Signature · 1 line
1.7.5.4
#3 lore raw

RFC PATCH 3/5 cmd_ext2: use common get_device_and_partition function

In reply to Rob Herring

From: Rob Herring <[email protected]>

Convert ext2ls and ext2load to use common device and partition parsing function.

---
 common/cmd_ext2.c |   71 ++++++++++++-----------------------------------------
 1 files changed, 16 insertions(+), 55 deletions(-)
common/cmd_ext2.c +16 -55
index 35fb361..84dafd6 100644
@@ -59,34 +59,24 @@
 int do_ext2ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	char *filename = "/";
-	int dev=0;
-	int part=1;
+	int dev;
+	int part;
 	char *ep;
-	block_dev_desc_t *dev_desc=NULL;
+	block_dev_desc_t *dev_desc;
+	disk_partition_t info;
 	int part_length;
 
-	if (argc < 3)
+	if (argc < 2)
 		return cmd_usage(cmdtp);
 
-	dev = (int)simple_strtoul (argv[2], &ep, 16);
-	dev_desc = get_dev(argv[1],dev);
-
-	if (dev_desc == NULL) {
-		printf ("\n** Block device %s %d not supported\n", argv[1], dev);
+	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info);
+	if (part < 0)
 		return 1;
-	}
-
-	if (*ep) {
-		if (*ep != ':') {
-			puts ("\n** Invalid boot device, use `dev[:part]' **\n");
-			return 1;
-		}
-		part = (int)simple_strtoul(++ep, NULL, 16);
-	}
 
 	if (argc == 4)
 		filename = argv[3];
 
+	dev = dev_desc->dev;
 	PRINTF("Using device %s %d:%d, directory: %s\n", argv[1], dev, part, filename);
 
 	if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) {
@@ -126,11 +116,11 @@ int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
 	char *filename = NULL;
 	char *ep;
-	int dev, part = 1;
+	int dev, part;
 	ulong addr = 0, part_length;
 	int filelen;
 	disk_partition_t info;
-	block_dev_desc_t *dev_desc = NULL;
+	block_dev_desc_t *dev_desc;
 	char buf [12];
 	unsigned long count;
 	char *addr_str;
@@ -171,43 +161,14 @@ int do_ext2load (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 		return 1;
 	}
 
-	dev = (int)simple_strtoul (argv[2], &ep, 16);
-	dev_desc = get_dev(argv[1],dev);
-	if (dev_desc==NULL) {
-		printf ("** Block device %s %d not supported\n", argv[1], dev);
+	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info);
+	if (part < 0)
 		return 1;
-	}
-	if (*ep) {
-		if (*ep != ':') {
-			puts ("** Invalid boot device, use `dev[:part]' **\n");
-			return 1;
-		}
-		part = (int)simple_strtoul(++ep, NULL, 16);
-	}
-
-	PRINTF("Using device %s%d, partition %d\n", argv[1], dev, part);
-
-	if (part != 0) {
-		if (get_partition_info (dev_desc, part, &info)) {
-			printf ("** Bad partition %d **\n", part);
-			return 1;
-		}
-
-		if (strncmp((char *)info.type, BOOT_PART_TYPE, sizeof(info.type)) != 0) {
-			printf ("** Invalid partition type \"%.32s\""
-				" (expect \"" BOOT_PART_TYPE "\")\n",
-				info.type);
-			return 1;
-		}
-		printf ("Loading file \"%s\" "
-			"from %s device %d:%d (%.32s)\n",
-			filename,
-			argv[1], dev, part, info.name);
-	} else {
-		printf ("Loading file \"%s\" from %s device %d\n",
-			filename, argv[1], dev);
-	}
 
+	dev = dev_desc->dev;
+	printf("Loading file \"%s\" from %s device %d%c%c\n",
+		filename, argv[1], dev,
+		part ? ':' : ' ', part ? part + '0' : ' ');
 
 	if ((part_length = ext2fs_set_blk_dev(dev_desc, part)) == 0) {
 		printf ("** Bad partition - %s %d:%d **\n",  argv[1], dev, part);
Signature · 1 line
1.7.5.4
#4 lore raw

RFC PATCH 4/5 cmd_fat: use common get_device_and_partition function

In reply to Rob Herring

From: Rob Herring <[email protected]>

Convert fatload, fatls, and fatinfo to use common device and partition parsing function. With the common function "dev:part" can come from the environment and a '-' can be used in that case.

---
 common/cmd_fat.c |   72 +++++++++++++++++++----------------------------------
 1 files changed, 26 insertions(+), 46 deletions(-)
common/cmd_fat.c +26 -46
index 0220494..be617fe 100644
@@ -40,29 +40,21 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	unsigned long count;
 	char buf [12];
 	block_dev_desc_t *dev_desc=NULL;
-	int dev=0;
-	int part=1;
+	disk_partition_t info;
+	int part, dev;
 	char *ep;
 
 	if (argc < 5) {
-		printf( "usage: fatload <interface> <dev[:part]> "
+		printf("usage: fatload <interface> [<dev[:part]>] "
 			"<addr> <filename> [bytes]\n");
 		return 1;
 	}
 
-	dev = (int)simple_strtoul(argv[2], &ep, 16);
-	dev_desc = get_dev(argv[1],dev);
-	if (dev_desc == NULL) {
-		puts("\n** Invalid boot device **\n");
+	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info);
+	if (part < 0)
 		return 1;
-	}
-	if (*ep) {
-		if (*ep != ':') {
-			puts("\n** Invalid boot device, use `dev[:part]' **\n");
-			return 1;
-		}
-		part = (int)simple_strtoul(++ep, NULL, 16);
-	}
+
+	dev = dev_desc->dev;
 	if (fat_register_device(dev_desc,part)!=0) {
 		printf("\n** Unable to use %s %d:%d for fatload **\n",
 			argv[1], dev, part);
@@ -93,7 +85,7 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 U_BOOT_CMD(
 	fatload,	6,	0,	do_fat_fsload,
 	"load binary file from a dos filesystem",
-	"<interface> <dev[:part]>  <addr> <filename> [bytes]\n"
+	"<interface> [<dev[:part]>]  <addr> <filename> [bytes]\n"
 	"    - load binary file 'filename' from 'dev' on 'interface'\n"
 	"      to address 'addr' from dos filesystem"
 );
@@ -106,24 +98,18 @@ int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	int part=1;
 	char *ep;
 	block_dev_desc_t *dev_desc=NULL;
+	disk_partition_t info;
 
-	if (argc < 3) {
-		printf("usage: fatls <interface> <dev[:part]> [directory]\n");
+	if (argc < 2) {
+		printf("usage: fatls <interface> [<dev[:part]>] [directory]\n");
 		return 0;
 	}
-	dev = (int)simple_strtoul(argv[2], &ep, 16);
-	dev_desc = get_dev(argv[1],dev);
-	if (dev_desc == NULL) {
-		puts("\n** Invalid boot device **\n");
+
+	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info);
+	if (part < 0)
 		return 1;
-	}
-	if (*ep) {
-		if (*ep != ':') {
-			puts("\n** Invalid boot device, use `dev[:part]' **\n");
-			return 1;
-		}
-		part = (int)simple_strtoul(++ep, NULL, 16);
-	}
+
+	dev = dev_desc->dev;
 	if (fat_register_device(dev_desc,part)!=0) {
 		printf("\n** Unable to use %s %d:%d for fatls **\n",
 			argv[1], dev, part);
@@ -142,7 +128,7 @@ int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 U_BOOT_CMD(
 	fatls,	4,	1,	do_fat_ls,
 	"list files in a directory (default /)",
-	"<interface> <dev[:part]> [directory]\n"
+	"<interface> [<dev[:part]>] [directory]\n"
 	"    - list files from 'dev' on 'interface' in a 'directory'"
 );
 
@@ -151,25 +137,19 @@ int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 	int dev=0;
 	int part=1;
 	char *ep;
-	block_dev_desc_t *dev_desc=NULL;
+	block_dev_desc_t *dev_desc;
+	disk_partition_t info;
 
 	if (argc < 2) {
-		printf("usage: fatinfo <interface> <dev[:part]>\n");
+		printf("usage: fatinfo <interface> [<dev[:part]>]\n");
 		return 0;
 	}
-	dev = (int)simple_strtoul(argv[2], &ep, 16);
-	dev_desc = get_dev(argv[1],dev);
-	if (dev_desc == NULL) {
-		puts("\n** Invalid boot device **\n");
+
+	part = get_device_and_partition(argv[1], argv[2], &dev_desc, &info);
+	if (part < 0)
 		return 1;
-	}
-	if (*ep) {
-		if (*ep != ':') {
-			puts("\n** Invalid boot device, use `dev[:part]' **\n");
-			return 1;
-		}
-		part = (int)simple_strtoul(++ep, NULL, 16);
-	}
+
+	dev = dev_desc->dev;
 	if (fat_register_device(dev_desc,part)!=0) {
 		printf("\n** Unable to use %s %d:%d for fatinfo **\n",
 			argv[1], dev, part);
@@ -181,6 +161,6 @@ int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 U_BOOT_CMD(
 	fatinfo,	3,	1,	do_fat_fsinfo,
 	"print information about filesystem",
-	"<interface> <dev[:part]>\n"
+	"<interface> [<dev[:part]>]\n"
 	"    - print information about filesystem from 'dev' on 'interface'"
 );
Signature · 1 line
1.7.5.4
#5 lore raw

RFC PATCH 5/5 cmd_scsi: use common get_device_and_partition function

In reply to Rob Herring

From: Rob Herring <[email protected]>

Convert scsiboot to use common device and partition parsing function.

---
 common/cmd_scsi.c |   58 ++++++++++------------------------------------------
 1 files changed, 11 insertions(+), 47 deletions(-)
common/cmd_scsi.c +11 -47
index fa10751..dcf8b84 100644
@@ -206,64 +206,28 @@ block_dev_desc_t * scsi_get_dev(int dev)
  */
 int do_scsiboot (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
 {
-	char *boot_device = NULL;
-	char *ep;
-	int dev, part = 0;
-	ulong addr, cnt;
+	int dev, part;
+	ulong addr = CONFIG_SYS_LOAD_ADDR;
+	ulong cnt;
+	block_dev_desc_t *dev_desc;
 	disk_partition_t info;
 	image_header_t *hdr;
 #if defined(CONFIG_FIT)
 	const void *fit_hdr = NULL;
 #endif
 
-	switch (argc) {
-	case 1:
-		addr = CONFIG_SYS_LOAD_ADDR;
-		boot_device = getenv ("bootdevice");
-		break;
-	case 2:
-		addr = simple_strtoul(argv[1], NULL, 16);
-		boot_device = getenv ("bootdevice");
-		break;
-	case 3:
-		addr = simple_strtoul(argv[1], NULL, 16);
-		boot_device = argv[2];
-		break;
-	default:
+	if (argc > 3)
 		return cmd_usage(cmdtp);
-	}
 
-	if (!boot_device) {
-		puts ("\n** No boot device **\n");
-		return 1;
-	}
-
-	dev = simple_strtoul(boot_device, &ep, 16);
-	printf("booting from dev %d\n",dev);
-	if (scsi_dev_desc[dev].type == DEV_TYPE_UNKNOWN) {
-		printf ("\n** Device %d not available\n", dev);
-		return 1;
-	}
+	if (argc > 1)
+		addr = simple_strtoul(argv[1], NULL, 16);
 
-	if (*ep) {
-		if (*ep != ':') {
-			puts ("\n** Invalid boot device, use `dev[:part]' **\n");
-			return 1;
-		}
-		part = simple_strtoul(++ep, NULL, 16);
-	}
-	if (get_partition_info (&scsi_dev_desc[dev], part, &info)) {
-		printf("error reading partinfo\n");
+	part = get_device_and_partition("scsi", (argc == 3) ? argv[2] : NULL,
+					&dev_desc, &info);
+	if (part < 0)
 		return 1;
-	}
-	if ((strncmp((char *)(info.type), BOOT_PART_TYPE, sizeof(info.type)) != 0) &&
-	    (strncmp((char *)(info.type), BOOT_PART_COMP, sizeof(info.type)) != 0)) {
-		printf ("\n** Invalid partition type \"%.32s\""
-			" (expect \"" BOOT_PART_TYPE "\")\n",
-			info.type);
-		return 1;
-	}
 
+	dev = dev_desc->dev;
 	printf ("\nLoading from SCSI device %d, partition %d: "
 		"Name: %.32s  Type: %.32s\n",
 		dev, part, info.name, info.type);
Signature · 1 line
1.7.5.4