add bootable partition support
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
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
@@ -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
@@ -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
RFC PATCH 2/5 disk/part: introduce get_device_and_partition
In reply to Rob HerringFrom: 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
@@ -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
@@ -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
RFC PATCH 3/5 cmd_ext2: use common get_device_and_partition function
In reply to Rob HerringFrom: 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
@@ -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
RFC PATCH 4/5 cmd_fat: use common get_device_and_partition function
In reply to Rob HerringFrom: 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
@@ -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
RFC PATCH 5/5 cmd_scsi: use common get_device_and_partition function
In reply to Rob HerringFrom: 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
@@ -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