-
Notifications
You must be signed in to change notification settings - Fork 918
Add a sample to read the partition table #627
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Changes from 14 commits
01001fa
a0ceb2b
d2883d1
1015067
8b87449
c5aa4c1
2496fe7
5681d71
0f96a36
9bdba25
7d9edfa
87eddec
bbb1656
8f3564d
ee6d8d6
b463a69
555ded5
9bce48c
b5c2fbe
0889622
8dd6b0e
b53dfbc
4822ae3
c5fd635
c88a23c
869bf75
4005c6f
8d1d467
ce5b409
d9909f9
ce6dda8
7edee22
1066f75
b118961
c37dcbe
9c19b3c
cda403e
a0e81bd
ff8d2b4
9eb7c33
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
add_executable(partition_info partition_info.c) | ||
|
||
target_link_libraries(partition_info PRIVATE | ||
pico_stdlib | ||
pico_bootrom | ||
) | ||
|
||
# add a partition table | ||
pico_embed_pt_in_binary(partition_info ${CMAKE_CURRENT_LIST_DIR}/pt.json) | ||
|
||
# create map/bin/hex/uf2 file etc. | ||
pico_add_extra_outputs(partition_info) | ||
|
||
# add url via pico_set_program_url | ||
example_auto_set_url(partition_info) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,161 @@ | ||
/** | ||
* Copyright (c) 2023 Raspberry Pi (Trading) Ltd. | ||
* | ||
* SPDX-License-Identifier: BSD-3-Clause | ||
*/ | ||
#include <stdio.h> | ||
#include <pico/stdlib.h> | ||
#include <pico/bootrom.h> | ||
#include "boot/picobin.h" | ||
oyama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
#define PART_LOC_FIRST(x) ( ((x) & PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_FIRST_SECTOR_LSB ) | ||
#define PART_LOC_LAST(x) ( ((x) & PICOBIN_PARTITION_LOCATION_LAST_SECTOR_BITS) >> PICOBIN_PARTITION_LOCATION_LAST_SECTOR_LSB ) | ||
|
||
#define PARTITION_LOCATION_AND_FLAGS_SIZE 2 | ||
#define PARTITION_ID_SIZE 2 | ||
#define PARTITION_NAME_MAX 127 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @will-v-pi Is it worth hoisting any of these defines into pico-sdk, or is it fine for each project to define them itself? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It'll probably be sensible to add them to |
||
#define PARTITION_TABLE_FIXED_INFO_SIZE (4 + PARTITION_TABLE_MAX_PARTITIONS * (PARTITION_LOCATION_AND_FLAGS_SIZE + PARTITION_ID_SIZE)) | ||
|
||
/* | ||
* Stores partition table information and data read status | ||
*/ | ||
typedef struct { | ||
uint32_t table[PARTITION_TABLE_FIXED_INFO_SIZE]; | ||
uint32_t fields; | ||
int partition_count; | ||
uint32_t unpartitioned_space_first_sector; | ||
uint32_t unpartitioned_space_last_sector; | ||
uint32_t flags_and_permissions; | ||
int current_partition; | ||
size_t idx; | ||
int status; | ||
} pico_partition_table_t; | ||
|
||
/* | ||
* Stores information on each partition | ||
*/ | ||
typedef struct { | ||
uint32_t first_sector; | ||
uint32_t last_sector; | ||
uint32_t flags_and_permissions; | ||
uint64_t partition_id; | ||
char name[PARTITION_NAME_MAX + 1]; // name length is indicated by 7 bits | ||
lurch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} pico_partition_t; | ||
|
||
|
||
/* | ||
* Read the partition table information. | ||
* | ||
* See the RP2350 datasheet 5.1.2, 5.4.8.16 for flags and structures that can be specified. | ||
*/ | ||
int pico_partitions_open(pico_partition_table_t *pt) { | ||
// Reads a fixed size fields | ||
oyama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
int rc = rom_get_partition_table_info(pt->table, sizeof(pt->table), | ||
(PT_INFO_PT_INFO | | ||
PT_INFO_PARTITION_LOCATION_AND_FLAGS | | ||
PT_INFO_PARTITION_ID)); | ||
lurch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (rc < 0) { | ||
pt->status = rc; | ||
oyama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
return rc; | ||
} | ||
|
||
size_t pos = 0; | ||
pt->fields = pt->table[pos++]; | ||
pt->partition_count = pt->table[pos++] & 0x000000FF; | ||
uint32_t location = pt->table[pos++]; | ||
pt->unpartitioned_space_first_sector = PART_LOC_FIRST(location); | ||
pt->unpartitioned_space_last_sector = PART_LOC_LAST(location); | ||
lurch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pt->flags_and_permissions = pt->table[pos++]; | ||
pt->current_partition = 0; | ||
pt->idx = pos; | ||
pt->status = 0; | ||
|
||
return 0; | ||
} | ||
|
||
/* | ||
* Extract each partition information | ||
*/ | ||
bool pico_partitions_next(pico_partition_table_t *pt, pico_partition_t *p) { | ||
if (pt->current_partition >= pt->partition_count) { | ||
return false; | ||
} | ||
|
||
size_t idx = pt->idx; | ||
oyama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
uint32_t location = pt->table[idx++]; | ||
p->first_sector = PART_LOC_FIRST(location); | ||
p->last_sector = PART_LOC_LAST(location); | ||
p->flags_and_permissions = pt->table[idx++]; | ||
|
||
if (p->flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_ID_BITS) { | ||
uint32_t id_low = pt->table[idx++]; | ||
uint32_t id_high = pt->table[idx++]; | ||
p->partition_id = ((uint64_t)id_high << 32) | id_low; | ||
} else { | ||
p->partition_id = 0; | ||
} | ||
pt->idx = idx; | ||
|
||
if (p->flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS) { | ||
// Read variable length fields | ||
uint32_t name_buf[(PARTITION_NAME_MAX + 1) / sizeof(uint32_t)] = {0}; | ||
lurch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
int rc = rom_get_partition_table_info(name_buf, sizeof(name_buf), | ||
(pt->current_partition << 24 | | ||
PT_INFO_SINGLE_PARTITION | | ||
PT_INFO_PARTITION_NAME)); | ||
if (rc < 0) { | ||
pt->status = rc; | ||
return false; | ||
} | ||
uint32_t __attribute__((unused)) fields = name_buf[0]; | ||
uint8_t *name_buf_u8 = (uint8_t *)&name_buf[1]; | ||
uint8_t name_length = *name_buf_u8++; | ||
lurch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
memcpy(p->name, name_buf_u8, name_length); | ||
p->name[name_length] = '\0'; | ||
} else { | ||
p->name[0] = '\0'; | ||
} | ||
|
||
pt->current_partition++; | ||
return true; | ||
} | ||
|
||
int main() { | ||
stdio_init_all(); | ||
|
||
pico_partition_table_t pt; | ||
pico_partitions_open(&pt); | ||
oyama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
printf("un-partitioned_space: S(%s%s) NSBOOT(%s%s) NS(%s%s)\n", | ||
(pt.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_S_R_BITS ? "r" : ""), | ||
(pt.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_S_W_BITS ? "w" : ""), | ||
(pt.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NSBOOT_R_BITS ? "r" : ""), | ||
(pt.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS ? "w" : ""), | ||
(pt.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NS_R_BITS ? "r" : ""), | ||
(pt.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NS_W_BITS ? "w" : "")); | ||
printf("partitions:\n"); | ||
lurch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
pico_partition_t p; | ||
while (pico_partitions_next(&pt, &p)) { | ||
printf("%3d:", pt.current_partition - 1); | ||
printf(" %08x->%08x S(%s%s) NSBOOT(%s%s) NS(%s%s)", | ||
p.first_sector * 4096, (p.last_sector + 1) * 4096, | ||
lurch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
(p.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_S_R_BITS ? "r" : ""), | ||
(p.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_S_W_BITS ? "w" : ""), | ||
(p.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NSBOOT_R_BITS ? "r" : ""), | ||
(p.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NSBOOT_W_BITS ? "w" : ""), | ||
(p.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NS_R_BITS ? "r" : ""), | ||
(p.flags_and_permissions & PICOBIN_PARTITION_PERMISSION_NS_W_BITS ? "w" : "")); | ||
if (p.flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_ID_BITS) { | ||
printf(", id=%016llx", p.partition_id); | ||
} | ||
if (p.flags_and_permissions & PICOBIN_PARTITION_FLAGS_HAS_NAME_BITS) { | ||
lurch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
printf(", \"%s\"", p.name); | ||
} | ||
printf("\n"); | ||
} | ||
if (pt.status != 0) { | ||
panic("rom_get_partition_table_info returned %d", pt.status); | ||
} | ||
|
||
return 0; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
{ | ||
"version": [1, 0], | ||
"unpartitioned": { | ||
"families": ["absolute"], | ||
"permissions": { | ||
"secure": "rw", | ||
"nonsecure": "rw", | ||
"bootloader": "rw" | ||
} | ||
}, | ||
"partitions": [ | ||
{ | ||
"name": "Firmware", | ||
"id": 1, | ||
"start": 0, | ||
"size": "512K", | ||
oyama marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"families": ["rp2350-arm-ns", "rp2350-arm-s", "rp2350-riscv"], | ||
lurch marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"permissions": { | ||
"secure": "rw", | ||
"nonsecure": "rw", | ||
"bootloader": "rw" | ||
} | ||
}, | ||
{ | ||
"name": "Data", | ||
"id": 2, | ||
"size": "512K", | ||
"families": ["data"], | ||
"permissions": { | ||
"secure": "rw", | ||
"nonsecure": "rw", | ||
"bootloader": "rw" | ||
} | ||
}, | ||
{ | ||
"name": "Read only Data", | ||
"id": 3, | ||
"size": "512K", | ||
"families": ["data"], | ||
"permissions": { | ||
"secure": "r", | ||
"nonsecure": "r", | ||
"bootloader": "r" | ||
} | ||
} | ||
] | ||
} |
Uh oh!
There was an error while loading. Please reload this page.