Skip to content

Commit e08e4a2

Browse files
committed
Add metadata info for partition tables
1 parent 2795c20 commit e08e4a2

File tree

2 files changed

+140
-40
lines changed

2 files changed

+140
-40
lines changed

bintool/metadata.h

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,55 @@ struct partition_table_item : public single_byte_size_item {
225225
partition_table_item() = default;
226226

227227
explicit partition_table_item(uint32_t unpartitioned_flags, bool singleton) : unpartitioned_flags(unpartitioned_flags), singleton(singleton) {}
228-
template <typename I> static std::shared_ptr<item> parse(I it, I end, uint32_t header) {
229-
return nullptr;
228+
template <typename I> static std::shared_ptr<item> parse(I& it, I end, uint32_t header) {
229+
uint32_t size = decode_size(header);
230+
uint8_t singleton_count = header >> 24;
231+
bool singleton = singleton_count & 0x80;
232+
uint8_t partition_count = singleton_count & 0x0f;
233+
uint32_t unpartitioned_flags = *it++;
234+
235+
auto pt = std::make_shared<partition_table_item>(unpartitioned_flags, singleton);
236+
237+
std::vector<uint32_t> data;
238+
for (unsigned int i=2; i < size; i++) {
239+
data.push_back(*it++);
240+
}
241+
int i=0;
242+
while (i < data.size()) {
243+
partition new_p;
244+
uint32_t permissions_locations = data[i++];
245+
new_p.permissions = (permissions_locations & PICOBIN_PARTITION_PERMISSIONS_BITS) >> PICOBIN_PARTITION_PERMISSIONS_LSB;
246+
new_p.first_sector = (permissions_locations & PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB;
247+
new_p.last_sector = (permissions_locations & PICOBIN_PARTITION_LOCATION_LAST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB;
248+
249+
uint32_t permissions_flags = data[i++];
250+
uint8_t permissions2 = (permissions_flags & PICOBIN_PARTITION_PERMISSIONS_BITS) >> PICOBIN_PARTITION_PERMISSIONS_LSB;
251+
if (new_p.permissions != permissions2) {
252+
printf("Permissions mismatch %02x %02x\n", new_p.permissions, permissions2);
253+
assert(false);
254+
}
255+
new_p.flags = permissions_flags & (~PICOBIN_PARTITION_PERMISSIONS_BITS);
256+
257+
if (new_p.flags & PICOBIN_PARTITION_FLAGS_HAS_ID_BITS) {
258+
new_p.id = (uint64_t)data[i++] | ((uint64_t)data[i++] << 32);
259+
}
260+
261+
uint8_t num_extra_families = (new_p.flags & PICOBIN_PARTITION_FLAGS_ACCEPTS_NUM_EXTRA_FAMILIES_BITS) >> PICOBIN_PARTITION_FLAGS_ACCEPTS_NUM_EXTRA_FAMILIES_LSB;
262+
for (int fam=0; fam < num_extra_families; fam++) {
263+
new_p.extra_families.push_back(data[i++]);
264+
}
265+
266+
if (new_p.flags & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS) {
267+
auto bytes = words_to_lsb_bytes(data.begin() + i++, data.end());
268+
int name_size = bytes[0];
269+
// This works neatly - accounts for the size byte at the start
270+
i += name_size / 4;
271+
new_p.name = std::string((char*)(bytes.data() + 1), name_size);
272+
}
273+
274+
pt->partitions.push_back(new_p);
275+
}
276+
return pt;
230277
}
231278

232279
std::vector<uint32_t> to_words(item_writer_context& ctx) const override {
@@ -574,7 +621,7 @@ struct block {
574621
i = image_type_item::parse(it, end, header);
575622
break;
576623
case PICOBIN_BLOCK_ITEM_PARTITION_TABLE:
577-
i = ignored_item::parse(it, end, header);
624+
i = partition_table_item::parse(it, end, header);
578625
break;
579626
case PICOBIN_BLOCK_ITEM_1BS_VECTOR_TABLE:
580627
i = vector_table_item::parse(it, end, header);

main.cpp

Lines changed: 90 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -876,9 +876,6 @@ struct partition_info_command : public cmd {
876876
string get_doc() const override {
877877
return "Print the device's partition table.";
878878
}
879-
880-
void print_permissions(unsigned int p) const;
881-
void insert_default_families(uint32_t flags_and_permissions, vector<std::string> &family_ids) const;
882879
};
883880
#endif
884881

@@ -923,9 +920,6 @@ struct partition_create_command : public cmd {
923920
string get_doc() const override {
924921
return "Create a partition table from json";
925922
}
926-
927-
void print_permissions(unsigned int p) const;
928-
void insert_default_families(uint32_t flags_and_permissions, vector<std::string> &family_ids) const;
929923
};
930924

931925

@@ -2922,6 +2916,39 @@ std::shared_ptr<memory_access> get_bi_access(memory_access &raw_access) {
29222916
return std::make_shared<remapped_memory_access>(raw_access, rmap);
29232917
}
29242918

2919+
string str_permissions(unsigned int p) {
2920+
static_assert(PICOBIN_PARTITION_PERMISSION_S_R_BITS == (1u << 26), "");
2921+
static_assert(PICOBIN_PARTITION_PERMISSION_S_W_BITS == (1u << 27), "");
2922+
static_assert(PICOBIN_PARTITION_PERMISSION_NS_W_BITS == (1u << 29), "");
2923+
static_assert(PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS == (1u << 31), "");
2924+
2925+
std::stringstream ss;
2926+
ss << " S(";
2927+
unsigned int r = (p >> 26) & 3;
2928+
if (r & 1) ss << "r";
2929+
if (r & 2) ss << "w"; else if (!r) ss << "-";
2930+
ss << ") NSBOOT(";
2931+
r = (p >> 30) & 3;
2932+
if (r & 1) ss << "r";
2933+
if (r & 2) ss << "w"; else if (!r) ss << "-";
2934+
ss << ") NS(";
2935+
r = (p >> 28) & 3;
2936+
if (r & 1) ss << "r";
2937+
if (r & 2) ss << "w"; else if (!r) ss << "-";
2938+
ss << ")";
2939+
2940+
return ss.str();
2941+
}
2942+
2943+
void insert_default_families(uint32_t flags_and_permissions, vector<std::string> &family_ids) {
2944+
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_ABSOLUTE_BITS) family_ids.emplace_back(absolute_family_name);
2945+
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2040_BITS) family_ids.emplace_back(rp2040_family_name);
2946+
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_ARM_S_BITS) family_ids.emplace_back(rp2350_arm_s_family_name);
2947+
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_ARM_NS_BITS) family_ids.emplace_back(rp2350_arm_ns_family_name);
2948+
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_RISCV_BITS) family_ids.emplace_back(rp2350_riscv_family_name);
2949+
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_DATA_BITS) family_ids.emplace_back(data_family_name);
2950+
}
2951+
29252952
#if HAS_LIBUSB
29262953
void info_guts(memory_access &raw_access, picoboot::connection *con) {
29272954
#else
@@ -3006,6 +3033,61 @@ void info_guts(memory_access &raw_access, void *con) {
30063033
}
30073034
}
30083035

3036+
// Partition Table
3037+
auto partition_table = best_block->get_item<partition_table_item>();
3038+
if (partition_table != nullptr) {
3039+
info_pair("partition table", partition_table->singleton ? "singleton" : "non-singleton");
3040+
std::stringstream unpartitioned;
3041+
unpartitioned << str_permissions(partition_table->unpartitioned_flags);
3042+
std::vector<std::string> family_ids;
3043+
insert_default_families(partition_table->unpartitioned_flags, family_ids);
3044+
unpartitioned << ", uf2 { " << cli::join(family_ids, ", ") << " }";
3045+
info_pair("un-partitioned space", unpartitioned.str());
3046+
3047+
for (int i=0; i < partition_table->partitions.size(); i++) {
3048+
std::stringstream pstring;
3049+
std::stringstream pname;
3050+
auto partition = partition_table->partitions[i];
3051+
uint32_t flags = partition.flags;
3052+
uint64_t id = partition.id;
3053+
pname << "partition " << i;
3054+
if ((flags & PICOBIN_PARTITION_FLAGS_LINK_TYPE_BITS) ==
3055+
PICOBIN_PARTITION_FLAGS_LINK_TYPE_AS_BITS(A_PARTITION)) {
3056+
pname << " (B w/ " << ((flags & PICOBIN_PARTITION_FLAGS_LINK_VALUE_BITS)
3057+
>> PICOBIN_PARTITION_FLAGS_LINK_VALUE_LSB)
3058+
<< ")";
3059+
} else if ((flags & PICOBIN_PARTITION_FLAGS_LINK_TYPE_BITS) ==
3060+
PICOBIN_PARTITION_FLAGS_LINK_TYPE_AS_BITS(OWNER_PARTITION)) {
3061+
pname << " (A ob/ " << ((flags & PICOBIN_PARTITION_FLAGS_LINK_VALUE_BITS)
3062+
>> PICOBIN_PARTITION_FLAGS_LINK_VALUE_LSB)
3063+
<< ")";
3064+
} else {
3065+
pname << " (A)";
3066+
}
3067+
pstring << hex_string(partition.first_sector * 4096, 8, false) << "->" << hex_string((partition.last_sector + 1) * 4096, 8, false);
3068+
unsigned int p = partition.permissions;
3069+
pstring << str_permissions(p << PICOBIN_PARTITION_PERMISSIONS_LSB);
3070+
if (flags & PICOBIN_PARTITION_FLAGS_HAS_ID_BITS) {
3071+
pstring << ", id=" << hex_string(id, 16, false);
3072+
}
3073+
uint32_t num_extra_families = partition.extra_families.size();
3074+
family_ids.clear();
3075+
insert_default_families(flags, family_ids);
3076+
for (auto family : partition.extra_families) {
3077+
family_ids.emplace_back(hex_string(family));
3078+
}
3079+
if (flags & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS) {
3080+
pstring << ", \"";
3081+
pstring << partition.name;
3082+
pstring << '"';
3083+
}
3084+
pstring << ", uf2 { " << cli::join(family_ids, ", ") << " }";
3085+
pstring << ", arm_boot " << !(flags & PICOBIN_PARTITION_FLAGS_IGNORED_DURING_ARM_BOOT_BITS);
3086+
pstring << ", riscv_boot " << !(flags & PICOBIN_PARTITION_FLAGS_IGNORED_DURING_RISCV_BOOT_BITS);
3087+
info_pair(pname.str(), pstring.str());
3088+
}
3089+
}
3090+
30093091
// Version
30103092
auto version = best_block->get_item<version_item>();
30113093
if (version != nullptr) {
@@ -5606,7 +5688,7 @@ bool partition_info_command::execute(device_map &devices) {
56065688
printf("the partition table is empty\n");
56075689
}
56085690
printf("un-partitioned_space : ");
5609-
print_permissions(unpartitioned.permissions_and_flags);
5691+
fos << str_permissions(unpartitioned.permissions_and_flags);
56105692
std::vector<std::string> family_ids;
56115693
insert_default_families(unpartitioned.permissions_and_flags, family_ids);
56125694
printf(", uf2 { %s }\n", cli::join(family_ids, ", ").c_str());
@@ -5646,7 +5728,7 @@ bool partition_info_command::execute(device_map &devices) {
56465728
return -1;
56475729
}
56485730
unsigned int p = location_and_permissions & flags_and_permissions;
5649-
print_permissions(p);
5731+
fos << str_permissions(p);
56505732
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_ID_BITS) {
56515733
printf(", id=%016" PRIx64, id);
56525734
}
@@ -6714,35 +6796,6 @@ bool coprodis_command::execute(device_map &devices) {
67146796

67156797

67166798
#if HAS_LIBUSB
6717-
void partition_info_command::insert_default_families(uint32_t flags_and_permissions, vector<std::string> &family_ids) const {
6718-
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_ABSOLUTE_BITS) family_ids.emplace_back(absolute_family_name);
6719-
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2040_BITS) family_ids.emplace_back(rp2040_family_name);
6720-
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_ARM_S_BITS) family_ids.emplace_back(rp2350_arm_s_family_name);
6721-
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_ARM_NS_BITS) family_ids.emplace_back(rp2350_arm_ns_family_name);
6722-
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_RP2350_RISCV_BITS) family_ids.emplace_back(rp2350_riscv_family_name);
6723-
if (flags_and_permissions & PICOBIN_PARTITION_FLAGS_ACCEPTS_DEFAULT_FAMILY_DATA_BITS) family_ids.emplace_back(data_family_name);
6724-
}
6725-
6726-
void partition_info_command::print_permissions(unsigned int p) const {
6727-
static_assert(PICOBIN_PARTITION_PERMISSION_S_R_BITS == (1u << 26), "");
6728-
static_assert(PICOBIN_PARTITION_PERMISSION_S_W_BITS == (1u << 27), "");
6729-
static_assert(PICOBIN_PARTITION_PERMISSION_NS_W_BITS == (1u << 29), "");
6730-
static_assert(PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS == (1u << 31), "");
6731-
printf(" S(");
6732-
unsigned int r = (p >> 26) & 3;
6733-
if (r & 1) printf("r");
6734-
if (r & 2) printf("w"); else if (!r) printf("-");
6735-
printf(") NSBOOT(");
6736-
r = (p >> 30) & 3;
6737-
if (r & 1) printf("r");
6738-
if (r & 2) printf("w"); else if (!r) printf("-");
6739-
printf(") NS(");
6740-
r = (p >> 28) & 3;
6741-
if (r & 1) printf("r");
6742-
if (r & 2) printf("w"); else if (!r) printf("-");
6743-
printf(")");
6744-
}
6745-
67466799
static void check_otp_write_error(picoboot::command_failure &e, bool ecc) {
67476800
if (e.get_code() == PICOBOOT_UNSUPPORTED_MODIFICATION) {
67486801
if (ecc) fail(ERROR_NOT_POSSIBLE, "Attempted to modify OTP ECC row(s)\n");

0 commit comments

Comments
 (0)