Skip to content

Commit 3ce5725

Browse files
committed
fix(esp_partition): read-only and encrypted partition support
1 parent 5c8a10e commit 3ce5725

File tree

5 files changed

+325
-166
lines changed

5 files changed

+325
-166
lines changed

components/esp_partition/host_test/partition_bdl_test/main/partition_bdl_test.c

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,10 +119,76 @@ TEST(partition_bdl, test_two_partitions_bdl_ops)
119119
TEST_ESP_OK(part_blockdev_2->ops->release(part_blockdev_2));
120120
}
121121

122+
TEST(partition_bdl, test_partition_bdl_limits)
123+
{
124+
// Limits tested:
125+
// - geometry alignment with parameter size for all ops
126+
// - dst buffer size check when reading
127+
// Partition boundaries and other checks are provided by underlying partition APIs and are not verified here
128+
129+
esp_blockdev_handle_t part_blockdev = NULL;
130+
TEST_ESP_OK(esp_partition_get_blockdev(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage1", &part_blockdev));
131+
132+
//artifitial setup setup for this test only
133+
part_blockdev->geometry.erase_size = 512;
134+
part_blockdev->geometry.read_size = 4;
135+
part_blockdev->geometry.write_size = 16;
136+
137+
const size_t data_size = part_blockdev->geometry.erase_size;
138+
uint8_t test_data[data_size];
139+
uint8_t test_data_err[data_size-3];
140+
const off_t target_addr_err = 3;
141+
142+
//correct addr, wrong length
143+
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_SIZE, part_blockdev->ops->erase(part_blockdev, 0, data_size+3));
144+
//wrong addr, correct length
145+
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_SIZE, part_blockdev->ops->erase(part_blockdev, target_addr_err, part_blockdev->geometry.erase_size));
146+
147+
//correct addr, correct dst buff, wrong length
148+
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_SIZE, part_blockdev->ops->read(part_blockdev, test_data, data_size, 0, data_size+3));
149+
//wrong addr, correct dst buff, correct length
150+
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_SIZE, part_blockdev->ops->read(part_blockdev, test_data, data_size, target_addr_err, data_size));
151+
//correct addr, wrong dst buff, correct length
152+
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, part_blockdev->ops->read(part_blockdev, test_data_err, sizeof(test_data_err), 0, data_size));
153+
154+
//correct addr, wrong length
155+
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_SIZE, part_blockdev->ops->write(part_blockdev, test_data, 0, data_size+3));
156+
//wrong addr, correct length
157+
TEST_ASSERT_EQUAL(ESP_ERR_INVALID_SIZE, part_blockdev->ops->write(part_blockdev, test_data, target_addr_err, data_size));
158+
159+
//release the BDL objects
160+
TEST_ESP_OK(part_blockdev->ops->release(part_blockdev));
161+
}
162+
163+
TEST(partition_bdl, test_bdl_partition_readonly)
164+
{
165+
//storage3 is readonly partition
166+
esp_blockdev_handle_t part_blockdev = NULL;
167+
TEST_ESP_OK(esp_partition_get_blockdev(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_ANY, "storage3", &part_blockdev));
168+
169+
//test flags
170+
TEST_ASSERT_EQUAL(1, part_blockdev->device_flags.read_only);
171+
TEST_ASSERT_EQUAL(0, part_blockdev->geometry.write_size);
172+
TEST_ASSERT_EQUAL(0, part_blockdev->geometry.erase_size);
173+
TEST_ASSERT_EQUAL(0, part_blockdev->geometry.recommended_write_size);
174+
TEST_ASSERT_EQUAL(0, part_blockdev->geometry.recommended_erase_size);
175+
176+
uint8_t dummy_test_buff[1024];
177+
178+
//write & erase must fail and read must work normally
179+
TEST_ASSERT_EQUAL(ESP_ERR_NOT_SUPPORTED, part_blockdev->ops->erase(part_blockdev, 0, sizeof(dummy_test_buff)));
180+
TEST_ASSERT_EQUAL(ESP_ERR_NOT_SUPPORTED, part_blockdev->ops->write(part_blockdev, dummy_test_buff, 0, sizeof(dummy_test_buff)));
181+
TEST_ESP_OK(part_blockdev->ops->read(part_blockdev, dummy_test_buff, sizeof(dummy_test_buff), 0, sizeof(dummy_test_buff)));
182+
183+
TEST_ESP_OK(part_blockdev->ops->release(part_blockdev));
184+
}
185+
122186
TEST_GROUP_RUNNER(partition_bdl)
123187
{
124188
RUN_TEST_CASE(partition_bdl, test_partition_bdl_ops);
125189
RUN_TEST_CASE(partition_bdl, test_two_partitions_bdl_ops);
190+
RUN_TEST_CASE(partition_bdl, test_partition_bdl_limits);
191+
RUN_TEST_CASE(partition_bdl, test_bdl_partition_readonly);
126192
}
127193

128194
static void run_all_tests(void)

components/esp_partition/host_test/partition_bdl_test/partition_table.csv

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@
33
nvs, data, nvs, 0x9000, 0x6000,
44
phy_init, data, phy, 0xf000, 0x1000,
55
factory, app, factory, 0x10000, 1M,
6-
storage1, data, , 0x110000, 512K
7-
storage2, data, , 0x190000, 512K,
6+
storage1, data, , 0x110000, 512K,
7+
storage2, data, , 0x190000, 128K,
8+
storage3, data, , 0x1B0000, 128K, readonly

components/esp_partition/partition.c

Lines changed: 35 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -635,12 +635,16 @@ esp_err_t esp_partition_copy(const esp_partition_t* dest_part, uint32_t dest_off
635635

636636
static esp_err_t esp_partition_blockdev_read(esp_blockdev_handle_t dev_handle, uint8_t* dst_buf, size_t dst_buf_size, uint64_t src_addr, size_t data_read_len)
637637
{
638+
if (dev_handle->geometry.read_size == 0) {
639+
return ESP_ERR_NOT_SUPPORTED;
640+
}
641+
638642
//the simplest boundary check. Should be replaced by auxiliary geometry mapping function
639-
if (src_addr % dev_handle->geometry.read_size != 0 || data_read_len % dev_handle->geometry.read_size) {
643+
if (src_addr % dev_handle->geometry.read_size != 0 || data_read_len % dev_handle->geometry.read_size != 0) {
640644
return ESP_ERR_INVALID_SIZE;
641645
}
642646

643-
if (dst_buf_size > data_read_len) {
647+
if (dst_buf_size < data_read_len) {
644648
return ESP_ERR_INVALID_ARG;
645649
}
646650

@@ -655,8 +659,12 @@ static esp_err_t esp_partition_blockdev_read(esp_blockdev_handle_t dev_handle, u
655659

656660
static esp_err_t esp_partition_blockdev_write(esp_blockdev_handle_t dev_handle, const uint8_t* src_buf, uint64_t dst_addr, size_t data_write_len)
657661
{
662+
if (dev_handle->device_flags.read_only || dev_handle->geometry.write_size == 0) {
663+
return ESP_ERR_NOT_SUPPORTED;
664+
}
665+
658666
//the simplest boundary check. Should be replaced by auxiliary geometry mapping function
659-
if (dst_addr % dev_handle->geometry.write_size != 0 || data_write_len % dev_handle->geometry.write_size) {
667+
if (dst_addr % dev_handle->geometry.write_size != 0 || data_write_len % dev_handle->geometry.write_size != 0) {
660668
return ESP_ERR_INVALID_SIZE;
661669
}
662670

@@ -671,8 +679,12 @@ static esp_err_t esp_partition_blockdev_write(esp_blockdev_handle_t dev_handle,
671679

672680
static esp_err_t esp_partition_blockdev_erase(esp_blockdev_handle_t dev_handle, uint64_t start_addr, size_t erase_len)
673681
{
682+
if (dev_handle->device_flags.read_only || dev_handle->geometry.erase_size == 0) {
683+
return ESP_ERR_NOT_SUPPORTED;
684+
}
685+
674686
//the simplest boundary check. Should be replaced by auxiliary geometry mapping function
675-
if (start_addr % dev_handle->geometry.erase_size != 0 || erase_len % dev_handle->geometry.erase_size) {
687+
if (start_addr % dev_handle->geometry.erase_size != 0 || erase_len % dev_handle->geometry.erase_size != 0) {
676688
return ESP_ERR_INVALID_SIZE;
677689
}
678690

@@ -710,16 +722,29 @@ esp_err_t esp_partition_ptr_get_blockdev(const esp_partition_t* partition, esp_b
710722

711723
ESP_BLOCKDEV_FLAGS_INST_CONFIG_DEFAULT(out->device_flags);
712724

713-
out->geometry.disk_size = partition->size;
714-
out->geometry.write_size = 1;
725+
if(partition->readonly) {
726+
out->device_flags.read_only = 1;
727+
out->geometry.write_size = 0;
728+
out->geometry.erase_size = 0;
729+
out->geometry.recommended_write_size = 0;
730+
out->geometry.recommended_erase_size = 0;
731+
}
732+
else {
733+
if (partition->encrypted) {
734+
out->geometry.write_size = 16;
735+
out->geometry.recommended_write_size = 16;
736+
} else {
737+
out->geometry.write_size = 1;
738+
out->geometry.recommended_write_size = 1;
739+
}
740+
out->geometry.erase_size = partition->erase_size;
741+
out->geometry.recommended_erase_size = partition->erase_size;
742+
}
715743
out->geometry.read_size = 1;
716-
out->geometry.erase_size = partition->erase_size;
717-
out->geometry.recommended_write_size = 1;
718744
out->geometry.recommended_read_size = 1;
719-
out->geometry.recommended_erase_size = partition->erase_size;
745+
out->geometry.disk_size = partition->size;
720746

721747
out->ops = &s_bdl_ops;
722-
723748
*out_bdl_handle_ptr = out;
724749

725750
return ESP_OK;

0 commit comments

Comments
 (0)