disk: "part" command and dependencies
v3 cover disk: "part" command and dependencies
From: Stephen Warren <[email protected]>
This series:
a) Fixes some issues in Rob Herring's get_device_and_partition series.
b) Implements a new "part" command, for dumping partition tables and UUIDs.
The series is based on a merge of u-boot-tegra/master, u-boot-usb/master, and u-boot/ext4, although only u-boot/ext4 is likely to contribute any context to the diffs here; my usage of the other branches was just a convenience for testing.
Stephen Warren (8):
disk: parameterize get_device_and_partition's loop count
disk: fix get_device_and_partition() bootable search
disk: introduce get_device()
disk: get_device_and_partition() enhancements
disk: part_efi: range-check partition number
disk: part_efi: parse and store partition UUID
disk: part_msdos: parse and store partition UUID
cmd_part: add partition-related command
common/Makefile | 1 + common/cmd_disk.c | 2 +- common/cmd_ext4.c | 2 +- common/cmd_ext_common.c | 4 +- common/cmd_fat.c | 8 +- common/cmd_part.c | 105 ++++++++++++++++++++++ common/cmd_reiser.c | 4 +- common/cmd_zfs.c | 4 +- disk/part.c | 223 ++++++++++++++++++++++++++++++++++++----------- disk/part_dos.c | 15 +++- disk/part_dos.h | 2 +- disk/part_efi.c | 32 +++++++ include/part.h | 17 +++- 13 files changed, 346 insertions(+), 73 deletions(-) create mode 100644 common/cmd_part.c
PATCH v3 1/8 disk: parameterize get_device_and_partition's loop count
From: Stephen Warren <[email protected]>
Create #define MAX_SEARCH_PARTITIONS to indicate how many partition IDs get_device_and_partition()'s automatic mode should search through. Also, search 1..n not 1..n-1 - it's unlikely anyone has this many partitions, but given the loop is 1-based, including the limit seems more consistent.
---
v3: New patch.
--- disk/part.c | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-)
disk/part.c +2 -1
@@ -435,6 +435,7 @@ void print_part (block_dev_desc_t * dev_desc)#endif +#define MAX_SEARCH_PARTITIONS 16int get_device_and_partition (const char *ifname,const char *dev_str,block_dev_desc_t **dev_desc,disk_partition_t *info)
@@ -484,7 +485,7 @@ int get_device_and_partition(const char *ifname, const char *dev_str, }else {/* find the first bootable partition. If none are bootable, * fall back to the first valid partition */ -for (p =1 ; p <16 ; p++) { +for (p =1 ; p <=MAX_SEARCH_PARTITIONS ; p++) { ret =get_partition_info (desc, p, info);if (ret)continue ;
Signature · 1 line
1.7.0.4
PATCH v3 2/8 disk: fix get_device_and_partition() bootable search
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
The existing get_device_and_partition() bootable search loop attempts to save the current best known partition in variable best_part. However, it's actually just saving a copy of the (static) "info" variable, and hence ends up not doing anything much useful if no bootable partition is found. Fix this by reworking the loop to:
a) When reading information about a partition, always read into the caller-supplied buffer; that way, if we find a bootable partition, there's no need to copy any information.
b) Save the first known valid partition's structure content rather than pointer in the search loop, and restore the structure content rather than the pointer when the loop exits.
---
v3: New patch.
--- disk/part.c | 38 +++++++++++++++++++++++++++++--------- 1 files changed, 29 insertions(+), 9 deletions(-)
disk/part.c +29 -9
@@ -447,7 +447,7 @@ int get_device_and_partition(const char *ifname, const char *dev_str,int p;int part =0 ;char *part_str; -disk_partition_t *best_part =NULL ; +disk_partition_t tmpinfo;if (dev_str) dev =simple_strtoul (dev_str, &ep,16 );
@@ -483,24 +483,44 @@ int get_device_and_partition(const char *ifname, const char *dev_str, part = (int )simple_strtoul (++part_str,NULL ,16 ); ret =get_partition_info (desc, part, info); }else { -/* find the first bootable partition. If none are bootable, -* fall back to the first valid partition */ +/* +* Find the first bootable partition. +* If none are bootable, fall back to the first valid partition. +*/ for (p =1 ; p <=MAX_SEARCH_PARTITIONS ; p++) { - ret =get_partition_info (desc, p, info); + ret =get_partition_info (*dev_desc, p, info);if (ret)continue ; -if (!best_part || info->bootable) { - best_part = info; +/* +* 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; } - info = best_part; -if (part) +/* 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; ret =0 ; + } }if (ret) {printf ("** Invalid partition %d, use `dev[:part]' **\n" , part);
Signature · 1 line
1.7.0.4
PATCH v3 2/8 disk: fix get_device_and_partition() bootable search
Quoted 15 lines · Stephen Warren
From: Stephen Warren <[email protected]>
The existing
get_device_and_partition()bootable search loop attempts to save the current best known partition in variablebest_part. However, it's actually just saving a copy of the (static) "info" variable, and hence ends up not doing anything much useful if no bootable partition is found. Fix this by reworking the loop to:a) When reading information about a partition, always read into the caller-supplied buffer; that way, if we find a bootable partition, there's no need to copy any information.
b) Save the first known valid partition's structure content rather than pointer in the search loop, and restore the structure content rather than the pointer when the loop exits.
Quoted 3 lines
Signed-off-by Stephen Warren <[email protected]>---
v3: New patch.
You might as well squash these into my original commits.
Rob
Quoted 71 lines
--- disk/part.c | 38 +++++++++++++++++++++++++++++--------- 1 files changed, 29 insertions(+), 9 deletions(-)disk/part.c +29
-9@@ -447,7 +447,7 @@ int get_device_and_partition(const char *ifname, const char *dev_str,int p;int part =0 ;char *part_str; -disk_partition_t *best_part =NULL ; +disk_partition_t tmpinfo;if (dev_str) dev =simple_strtoul (dev_str, &ep,16 );@@ -483,24 +483,44 @@ int get_device_and_partition(const char *ifname, const char *dev_str, part = (int )simple_strtoul (++part_str,NULL ,16 ); ret =get_partition_info (desc, part, info); }else { -/* find the first bootable partition. If none are bootable, -* fall back to the first valid partition */ +/* +* Find the first bootable partition. +* If none are bootable, fall back to the first valid partition. +*/ for (p =1 ; p <=MAX_SEARCH_PARTITIONS ; p++) { - ret =get_partition_info (desc, p, info); + ret =get_partition_info (*dev_desc, p, info);if (ret)continue ; -if (!best_part || info->bootable) { - best_part = info; +/* +* 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; } - info = best_part; -if (part) +/* 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; ret =0 ; + } }if (ret) {printf ("** Invalid partition %d, use `dev[:part]' **\n" , part);
PATCH v3 3/8 disk: introduce get_device()
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
This patch introduces function get_device(). This looks up a block_dev_desc_t from an interface name (e.g. mmc) and device number (e.g. 0). This function is essentially the non-partition-specific prefix of get_device_and_partition().
---
v3: New patch.
--- disk/part.c | 22 ++++++++++++++++++++++ include/part.h | 5 +++++ 2 files changed, 27 insertions(+), 0 deletions(-)
disk/part.c +22 -0
@@ -435,6 +435,28 @@ void print_part (block_dev_desc_t * dev_desc)#endif +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 MAX_SEARCH_PARTITIONS 16 int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc,
include/part.h +5 -0
@@ -112,6 +112,8 @@ int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_tvoid print_part (block_dev_desc_t *dev_desc);void init_part (block_dev_desc_t *dev_desc);void dev_print (block_dev_desc_t *dev_desc); +int get_device (const char *ifname,const char *dev_str, +block_dev_desc_t **dev_desc);int get_device_and_partition (const char *ifname,const char *dev_str,block_dev_desc_t **dev_desc,disk_partition_t *info);
@@ -131,6 +133,9 @@ static inline int get_partition_info (block_dev_desc_t * dev_desc, int part,static inline void print_part (block_dev_desc_t *dev_desc) {}static inline void init_part (block_dev_desc_t *dev_desc) {}static inline void dev_print (block_dev_desc_t *dev_desc) {} +static inline int get_device (const char *ifname,const char *dev_str, +block_dev_desc_t **dev_desc) +{return -1 ; } static inline int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc,
Signature · 1 line
1.7.0.4
PATCH v3 3/8 disk: introduce get_device()
Quoted 6 lines · Stephen Warren
From: Stephen Warren <[email protected]>
This patch introduces function
get_device(). This looks up ablock_dev_desc_tfrom an interface name (e.g. mmc) and device number (e.g. 0). This function is essentially the non-partition-specific prefix ofget_device_and_partition().
Then shouldn't get_device_and_partition just call get_device. Perhaps create get_partition() and then get_device_and_partition is just a wrapper.
Rob
Quoted 66 lines
Signed-off-by Stephen Warren <[email protected]>---
v3: New patch.--- disk/part.c | 22 ++++++++++++++++++++++ include/part.h | 5 +++++ 2 files changed, 27 insertions(+), 0 deletions(-)disk/part.c +22
-0@@ -435,6 +435,28 @@ void print_part (block_dev_desc_t * dev_desc)#endif +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 MAX_SEARCH_PARTITIONS 16 int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc,include/part.h +5
-0@@ -112,6 +112,8 @@ int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_tvoid print_part (block_dev_desc_t *dev_desc);void init_part (block_dev_desc_t *dev_desc);void dev_print (block_dev_desc_t *dev_desc); +int get_device (const char *ifname,const char *dev_str, +block_dev_desc_t **dev_desc);int get_device_and_partition (const char *ifname,const char *dev_str,block_dev_desc_t **dev_desc,disk_partition_t *info);@@ -131,6 +133,9 @@ static inline int get_partition_info (block_dev_desc_t * dev_desc, int part,static inline void print_part (block_dev_desc_t *dev_desc) {}static inline void init_part (block_dev_desc_t *dev_desc) {}static inline void dev_print (block_dev_desc_t *dev_desc) {} +static inline int get_device (const char *ifname,const char *dev_str, +block_dev_desc_t **dev_desc) +{return -1 ; } static inline int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc,
PATCH v3 3/8 disk: introduce get_device()
Quoted 11 lines · Rob Herring
Quoted 6 lines · Stephen Warren
From: Stephen Warren <[email protected]>
This patch introduces function
get_device(). This looks up ablock_dev_desc_tfrom an interface name (e.g. mmc) and device number (e.g. 0). This function is essentially the non-partition-specific prefix ofget_device_and_partition().Then shouldn't
get_device_and_partitionjust callget_device. Perhaps createget_partition()and thenget_device_and_partitionis just a wrapper.
I should read all the way through the series before replying...
Anyway, I would squash it all unless you want to have restructuring with current functionality and then enhancements.
Rob
Quoted 69 lines
Rob
Quoted 66 lines
Signed-off-by Stephen Warren <[email protected]>---
v3: New patch.--- disk/part.c | 22 ++++++++++++++++++++++ include/part.h | 5 +++++ 2 files changed, 27 insertions(+), 0 deletions(-)disk/part.c +22
-0@@ -435,6 +435,28 @@ void print_part (block_dev_desc_t * dev_desc)#endif +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 MAX_SEARCH_PARTITIONS 16 int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc,include/part.h +5
-0@@ -112,6 +112,8 @@ int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_tvoid print_part (block_dev_desc_t *dev_desc);void init_part (block_dev_desc_t *dev_desc);void dev_print (block_dev_desc_t *dev_desc); +int get_device (const char *ifname,const char *dev_str, +block_dev_desc_t **dev_desc);int get_device_and_partition (const char *ifname,const char *dev_str,block_dev_desc_t **dev_desc,disk_partition_t *info);@@ -131,6 +133,9 @@ static inline int get_partition_info (block_dev_desc_t * dev_desc, int part,static inline void print_part (block_dev_desc_t *dev_desc) {}static inline void init_part (block_dev_desc_t *dev_desc) {}static inline void dev_print (block_dev_desc_t *dev_desc) {} +static inline int get_device (const char *ifname,const char *dev_str, +block_dev_desc_t **dev_desc) +{return -1 ; } static inline int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc,
PATCH v3 3/8 disk: introduce get_device()
Quoted 9 lines · Rob Herring
Quoted 8 lines · Rob Herring
Quoted 6 lines · Stephen Warren
From: Stephen Warren <[email protected]>
This patch introduces function
get_device(). This looks up ablock_dev_desc_tfrom an interface name (e.g. mmc) and device number (e.g. 0). This function is essentially the non-partition-specific prefix ofget_device_and_partition().
Quoted 8 lines
Quoted 3 lines
Then shouldn't
get_device_and_partitionjust callget_device. Perhaps createget_partition()and thenget_device_and_partitionis just a wrapper.I should read all the way through the series before replying...
Anyway, I would squash it all unless you want to have restructuring with current functionality and then enhancements.
OK, I'm happy to squash everything together, and repost a series with both your and my patches; I separated it out to hopefully make working out what changes I made a little easier.
I did wonder about creating separate get_device, get_partition, and get_device_or_partition functions, the latter probably using a common implementation. I guess if I squash my changes into your original patches, then creating those 3 separate functions would end up being less churn. So, unless there are objections, I'll do that.
PATCH v3 3/8 disk: introduce get_device()
In reply to Rob HerringQuoted 9 lines · Rob Herring
Quoted 8 lines · Rob Herring
Quoted 6 lines · Stephen Warren
From: Stephen Warren <[email protected]>
This patch introduces function
get_device(). This looks up ablock_dev_desc_tfrom an interface name (e.g. mmc) and device number (e.g. 0). This function is essentially the non-partition-specific prefix ofget_device_and_partition().
Quoted 8 lines
Quoted 3 lines
Then shouldn't
get_device_and_partitionjust callget_device. Perhaps createget_partition()and thenget_device_and_partitionis just a wrapper.I should read all the way through the series before replying...
Anyway, I would squash it all unless you want to have restructuring with current functionality and then enhancements.
IMHO, restucture and then enhancements makes the most sense since it means we can bisect a latent bug easier. So no need for a v4 to squash patches down.
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: not available Type: application/pgp-signature Size: 836 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20120919/f37541a1/attachment.pgp>
PATCH v3 3/8 disk: introduce get_device()
In reply to Stephen WarrenQuoted 20 lines · Stephen Warren
From: Stephen Warren <[email protected]>
This patch introduces function
get_device(). This looks up ablock_dev_desc_tfrom an interface name (e.g. mmc) and device number (e.g. 0). This function is essentially the non-partition-specific prefix ofget_device_and_partition().Signed-off-by Stephen Warren <[email protected]>---
v3: New patch.--- disk/part.c | 22 ++++++++++++++++++++++ include/part.h | 5 +++++ 2 files changed, 27 insertions(+), 0 deletions(-)disk/part.c +0
-0
disk/part.c void print_part (block_dev_desc_t * dev_desc) · line 443
Quoted 9 lines
disk/part.c +6
-0@@ -435,6 +435,28 @@ void print_part (block_dev_desc_t * dev_desc)#endif +int get_device (const char *ifname,const char *dev_str, +block_dev_desc_t **dev_desc) +{ +char *ep; +int dev; +
Why don't you look up bootdevice here? That would be more consistent behavior.
Rob
Quoted 43 lines
disk/part.c +16
-0+ 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 MAX_SEARCH_PARTITIONS 16 int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc,include/part.h +5
-0@@ -112,6 +112,8 @@ int get_partition_info (block_dev_desc_t * dev_desc, int part, disk_partition_tvoid print_part (block_dev_desc_t *dev_desc);void init_part (block_dev_desc_t *dev_desc);void dev_print (block_dev_desc_t *dev_desc); +int get_device (const char *ifname,const char *dev_str, +block_dev_desc_t **dev_desc);int get_device_and_partition (const char *ifname,const char *dev_str,block_dev_desc_t **dev_desc,disk_partition_t *info);@@ -131,6 +133,9 @@ static inline int get_partition_info (block_dev_desc_t * dev_desc, int part,static inline void print_part (block_dev_desc_t *dev_desc) {}static inline void init_part (block_dev_desc_t *dev_desc) {}static inline void dev_print (block_dev_desc_t *dev_desc) {} +static inline int get_device (const char *ifname,const char *dev_str, +block_dev_desc_t **dev_desc) +{return -1 ; } static inline int get_device_and_partition(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc,
PATCH v3 3/8 disk: introduce get_device()
Quoted 8 lines · Rob Herring
Quoted 6 lines · Stephen Warren
From: Stephen Warren <[email protected]>
This patch introduces function
get_device(). This looks up ablock_dev_desc_tfrom an interface name (e.g. mmc) and device number (e.g. 0). This function is essentially the non-partition-specific prefix ofget_device_and_partition().
Quoted 9 lines
disk/part.c void print_part (block_dev_desc_t * dev_desc) · line 443
Quoted 6 lines
disk/part.c +6
-0+int get_device (const char *ifname,const char *dev_str, +block_dev_desc_t **dev_desc) +{ +char *ep; +int dev; +Why don't you look up bootdevice here? That would be more consistent behavior.
bootdevice names a partition (or can name a partition), whereas this function is about retrieving a device handle and never a partition handle.
I'm not sure it makes semantic sense to always fall back to bootdevice for commands that call get_device() directly. I'd far prefer people to always just pass the device they want to a command rather than relying implicitly on environment variables.
If we did read bootdevice here, we'd end up having to read/parse it in both get_device() and get_device_and_partition(), here to extract just the device portion and in get_device_and_partition() to extract just the partition portion. And we'd have to make sure the code here only allowed the user to specify a partition /if/ this function was called from get_device_and_partition() and not if a command called it directly. That all seems a bit complex.
PATCH v3 4/8 disk: get_device_and_partition() enhancements
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
Rework get_device_and_partition to:
a) Make use of get_device().
b) Add parameter to indicate whether returning a whole device is acceptable, or whether a partition is mandatory.
c) Make error-checking of the user's device-/partition-specification more complete. In particular, if strtoul() doesn't convert all characters, it's an error rather than just ignored.
d) Require user to explicitly specify "N:auto" as the device/partition specification to get the automatic "search for a bootable partition" mode of operation; Rob's patch changed the behaviour of some syntaxes from defaulting to partition 1.
The resultant device/partition returned by the function will be as follows, based on whether the disk has a partition table (ptable) or not, and whether the calling command allows the whole device to be returned or not.
(D and P are integers, P >= 1)
D
D:
No ptable:
!allow_whole_dev: error
allow_whole_dev: device D
ptable:
device D partition 1
D:0
!allow_whole_dev: error
allow_whole_dev: device D
D:P
No ptable: error
ptable: device D partition P
D:auto
No ptable:
!allow_whole_dev: error
allow_whole_dev: device D
ptable:
first partition in device D with bootable flag set. If none, first valid paratition in device D.
Note: In order to review this patch, it's probably easiest to simply look at the file contents post-application, rather than reading the patch itself.
---
v3: New patch.
--- common/cmd_disk.c | 2 +- common/cmd_ext4.c | 2 +- common/cmd_ext_common.c | 4 +- common/cmd_fat.c | 8 +- common/cmd_reiser.c | 4 +- common/cmd_zfs.c | 4 +- disk/part.c | 151 ++++++++++++++++++++++++++++++++++------------- include/part.h | 9 ++- 8 files changed, 127 insertions(+), 57 deletions(-)
common/cmd_disk.c +1 -1
@@ -31,7 +31,7 @@ int common_diskboot(cmd_tbl_t *cmdtp, const char *intf, int argc,bootstage_mark (BOOTSTAGE_ID_IDE_BOOT_DEVICE ); part =get_device_and_partition (intf, (argc ==3 ) ? argv[2 ] :NULL , - &dev_desc, &info); + &dev_desc, &info,1 );if (part <0 ) {bootstage_error (BOOTSTAGE_ID_IDE_TYPE );return 1 ;
common/cmd_ext4.c +1 -1
@@ -87,7 +87,7 @@ int do_ext4_write(cmd_tbl_t *cmdtp, int flag, int argc,if (argc <6 )return cmd_usage (cmdtp); - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
common/cmd_ext_common.c +2 -2
@@ -108,7 +108,7 @@ int do_ext_load(cmd_tbl_t *cmdtp, int flag, int argc,return 1 ; } - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
@@ -166,7 +166,7 @@ int do_ext_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])if (argc <2 )return cmd_usage (cmdtp); - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
common/cmd_fat.c +4 -4
@@ -49,7 +49,7 @@ int do_fat_fsload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])return 1 ; } - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
@@ -101,7 +101,7 @@ int do_fat_ls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])return 0 ; } - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
@@ -139,7 +139,7 @@ int do_fat_fsinfo (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])return 0 ; } - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
@@ -175,7 +175,7 @@ static int do_fat_fswrite(cmd_tbl_t *cmdtp, int flag,if (argc <5 )return cmd_usage (cmdtp); - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
common/cmd_reiser.c +2 -2
@@ -57,7 +57,7 @@ int do_reiserls (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])if (argc <3 )return CMD_RET_USAGE ; - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
@@ -140,7 +140,7 @@ int do_reiserload (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])return 1 ; } - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
common/cmd_zfs.c +2 -2
@@ -94,7 +94,7 @@ static int do_zfs_load(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])return 1 ; } - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
@@ -160,7 +160,7 @@ static int do_zfs_ls(cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])if (argc ==4 ) filename = argv[3 ]; - part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info); + part =get_device_and_partition (argv[1 ], argv[2 ], &dev_desc, &info,1 );if (part <0 )return 1 ;
disk/part.c +110 -41
197 lines not on this page · raw message
include/part.h +5 -4
@@ -114,9 +114,9 @@ void init_part (block_dev_desc_t *dev_desc);void dev_print (block_dev_desc_t *dev_desc);int get_device (const char *ifname,const char *dev_str,block_dev_desc_t **dev_desc); -int get_device_and_partition (const char *ifname,const char *dev_str, +int get_device_and_partition (const char *ifname,const char *dev_part_str,block_dev_desc_t **dev_desc, -disk_partition_t *info); +disk_partition_t *info,int allow_whole_dev);#else static inline block_dev_desc_t *get_dev (const char *ifname,int dev) {return NULL ; }
@@ -137,9 +137,10 @@ static inline int get_device(const char *ifname, const char *dev_str, block_dev_desc_t **dev_desc) {return -1 ; }static inline int get_device_and_partition (const char *ifname, -const char *dev_str, +const char *dev_part_str,block_dev_desc_t **dev_desc, -disk_partition_t *info) +disk_partition_t *info, +int allow_whole_dev) { *dev_desc =NULL ;return -1 ; }#endif
Signature · 1 line
1.7.0.4
PATCH v3 5/8 disk: part_efi: range-check partition number
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
Enhance get_partition_info_efi() to range-check the partition number. This prevents invalid partitions being accessed, and prevents access beyond the end of the gpt_pte[] array.
---
v3: No change.
v2: New patch.
--- disk/part_efi.c | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
disk/part_efi.c +7 -0
@@ -173,6 +173,13 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,return -1 ; } +if (part >le32_to_int (gpt_head->num_partition_entries) || + !is_pte_valid (&gpt_pte[part -1 ])) { +printf ("%s: *** ERROR: Invalid partition number %d ***\n" , + __func__, part); +return -1 ; + } +/* The ulong casting limits the maximum disk size to 2 TB */ info->start = (ulong )le64_to_int (gpt_pte[part -1 ].starting_lba);/* The ending LBA is inclusive, to calculate size, add 1 to it */
Signature · 1 line
1.7.0.4
PATCH v3 6/8 disk: part_efi: parse and store partition UUID
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
Each EFI partition table entry contains a UUID. Extend U-Boot's struct disk_partition to be able to store this information, and modify get_partition_info_efi() to fill it in.
The implementation of uuid_string() was derived from the Linux kernel, tag v3.6-rc4 file lib/vsprintf.c function uuid_string().
---
v3: Provided pointer to source of uuid_string() code in commit description.
v2: Add #ifdef CONFIG_PARTITION_UUIDS around all new code and struct fields.
--- disk/part.c | 5 +++++ disk/part_efi.c | 25 +++++++++++++++++++++++++ include/part.h | 3 +++ 3 files changed, 33 insertions(+), 0 deletions(-)
disk/part.c +5 -0
@@ -296,6 +296,11 @@ void init_part (block_dev_desc_t * dev_desc)int get_partition_info (block_dev_desc_t *dev_desc,int part ,disk_partition_t *info) { +#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 :
disk/part_efi.c +25 -0
@@ -154,6 +154,28 @@ void print_part_efi(block_dev_desc_t * dev_desc)return ; } +#ifdef CONFIG_PARTITION_UUIDS +static void uuid_string (unsigned char *uuid,char *str) +{ +static const u8 le[16 ] = {3 ,2 ,1 ,0 ,5 ,4 ,7 ,6 ,8 ,9 ,10 ,11 , +12 ,13 ,14 ,15 }; +int i; + +for (i =0 ; i <16 ; i++) { +sprintf (str,"%02x" , uuid[le[i]]); + str +=2 ; +switch (i) { +case 3 : +case 5 : +case 7 : +case 9 : + *str++ ='-' ; +break ; + } + } +} +#endif +int get_partition_info_efi (block_dev_desc_t * dev_desc,int part,disk_partition_t * info) {
@@ -190,6 +212,9 @@ int get_partition_info_efi(block_dev_desc_t * dev_desc, int part,sprintf ((char *)info->name,"%s" ,print_efiname (&gpt_pte[part -1 ]));sprintf ((char *)info->type,"U-Boot" ); +#ifdef CONFIG_PARTITION_UUIDS +uuid_string (gpt_pte[part -1 ].unique_partition_guid.b, info->uuid); +#endif debug ("%s: start 0x%lX, size 0x%lX, name %s" , __func__, info->start, info->size, info->name);
include/part.h +3 -0
@@ -94,6 +94,9 @@ typedef struct disk_partition {uchar name[32 ];/* partition name */ uchar type[32 ];/* string type description */ int bootable;/* Active/Bootable flag is set */ +#ifdef CONFIG_PARTITION_UUIDS +char uuid[37 ];/* filesystem UUID as string, if exists */ +#endif } disk_partition_t;/* Misc _get_dev functions */
Signature · 1 line
1.7.0.4
PATCH v3 7/8 disk: part_msdos: parse and store partition UUID
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
The MSDOS/MBR partition table includes a 32-bit unique ID, often referred to as the NT disk signature. When combined with a partition number within the table, this can form a unique ID similar in concept to EFI/GPT's partition UUID.
This patch generates UUIDs in the format 0002dd75-01, which matches the format expected by the Linux kernel.
---
v3: No change.
v2: New patch.
--- disk/part_dos.c | 15 ++++++++++++--- disk/part_dos.h | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-)
disk/part_dos.c +12 -3
@@ -169,7 +169,8 @@ 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) { ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, dev_desc->blksz);dos_partition_t *pt;
@@ -188,6 +189,11 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_partreturn -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++) {
@@ -229,6 +235,9 @@ 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 ; }
@@ -247,7 +256,7 @@ static int get_partition_info_extended (block_dev_desc_t *dev_desc, int ext_partreturn 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 ;
@@ -261,7 +270,7 @@ void print_part_dos (block_dev_desc_t *dev_desc)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 ); }
disk/part_dos.h +1 -1
@@ -24,7 +24,7 @@#ifndef _DISK_PART_DOS_H#define _DISK_PART_DOS_H - +#define DOS_PART_DISKSIG_OFFSET 0x1b8#define DOS_PART_TBL_OFFSET 0x1be#define DOS_PART_MAGIC_OFFSET 0x1fe#define DOS_PBR_FSTYPE_OFFSET 0x36
Signature · 1 line
1.7.0.4
PATCH v3 8/8 cmd_part: add partition-related command
In reply to Stephen WarrenFrom: Stephen Warren <[email protected]>
This implements the following:
part uuid mmc 0:1
-> print partition UUID
part uuid mmc 0:1 uuid
-> set environment variable to partition UUID
part list mmc 0
-> list the partitions on the specified device
"part uuid" can be useful when writing a bootcmd which searches all known devices for something bootable, and then wants the kernel to use the same partition as the root device, e.g.:
part uuid ${devtype} ${devnum}:${rootpart} uuid
setenv bootargs root=PARTUUID=${uuid} ...
---
v3:
* Rebased on top of u-boot/ext4 and Rob Herring's get_device_and_partition patches.
* Implemented "part list" sub-command.
v2:
* validate that CONFIG_PARTITION_UUID is defined when CONFIG_CMD_PART is
--- common/Makefile | 1 + common/cmd_part.c | 105 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 0 deletions(-) create mode 100644 common/cmd_part.c
common/Makefile +1 -0
@@ -136,6 +136,7 @@ COBJS-$(CONFIG_CMD_NAND) += cmd_nand.o COBJS-$(CONFIG_CMD_NET) += cmd_net.o COBJS-$(CONFIG_CMD_ONENAND) += cmd_onenand.o COBJS-$(CONFIG_CMD_OTP) += cmd_otp.o +COBJS-$(CONFIG_CMD_PART) += cmd_part.o ifdef CONFIG_PCI COBJS-$(CONFIG_CMD_PCI) += cmd_pci.o endif
common/cmd_part.c new file +105 -0
105 lines not on this page · raw message
Signature · 1 line
1.7.0.4