fix(esp_partition): Support reading unencrypted partitions by the bootloader

- When flash encryption is enable to support reading a partition that is not
marked as "encrypted", the `esp_partition_read()` API of bootloader build
should be redirected to the `bootloader_flash_read()` API.
This commit is contained in:
harshal.patil 2025-01-09 14:14:56 +05:30
parent eb05db30fc
commit 4c38499303
No known key found for this signature in database
GPG Key ID: 67334E837530B75C
2 changed files with 52 additions and 5 deletions

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*
@ -74,6 +74,18 @@ const esp_partition_t* esp_partition_find_first(esp_partition_type_t type, esp_p
esp_err_t esp_partition_read(const esp_partition_t *partition,
size_t src_offset, void *dst, size_t size)
{
assert(partition != NULL);
if (src_offset > partition->size) {
return ESP_ERR_INVALID_ARG;
}
if (size > partition->size - src_offset) {
return ESP_ERR_INVALID_SIZE;
}
if (!partition->encrypted) {
return bootloader_flash_read(partition->address + src_offset, dst, size, false);
}
const void *buf;
// log call to mmap

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2024 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2024-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -215,7 +215,7 @@ esp_err_t nvs_bootloader_page_visitor_get_namespaces(nvs_bootloader_page_visitor
// iterate over all entries with state written
// if the entry is namespace entry, then iterate the read_list and populate the namespace index by matching the namespace name
uint8_t start_index = 0;
nvs_bootloader_single_entry_t item = {0};
WORD_ALIGNED_ATTR nvs_bootloader_single_entry_t item = {0};
// repeat finding single entry items on the page until all entries are processed or error occurs
while (ret == ESP_OK) {
@ -275,7 +275,7 @@ esp_err_t nvs_bootloader_page_visitor_get_key_value_pairs(nvs_bootloader_page_vi
// if the entry is not a namespace entry, then iterate the read_list and populate the value by matching the namespace index, key name and value type
uint8_t next_index = 0; // index of the next entry to read, updated to the next entry by the read_next_single_entry_item
uint8_t current_index = 0; // index of the actual entry being processed
nvs_bootloader_single_entry_t item = {0};
WORD_ALIGNED_ATTR nvs_bootloader_single_entry_t item = {0};
// repeat finding single entry items on the page until all entries are processed or error occurs
while (ret == ESP_OK) {
@ -546,7 +546,42 @@ esp_err_t nvs_bootloader_read_entries_block(const esp_partition_t *partition,
size_t data_offset = page_index * NVS_CONST_PAGE_SIZE + NVS_CONST_PAGE_ENTRY_DATA_OFFSET + entry_index * NVS_CONST_ENTRY_SIZE ;
return esp_partition_read(partition, data_offset, block, block_len);
if (data_offset & 3 || block_len & 3 || (intptr_t) block & 3) {
/* For the bootloader build, the esp_partition_read() API internally is calls bootloader_flash_read() that
* requires the src_address, length and the destination address to be word aligned.
* src_address: NVS keys and values are always stored at a word aligned offset
* length: Reading bytes of length divisible by 4 at a time (BOOTLOADER_FLASH_READ_LEN)
* destination address: Using a word aligned buffer to read the flash contents (bootloader_flash_read_buffer)
*/
#define BOOTLOADER_FLASH_READ_LEN 32 // because it satisfies the above conditions
WORD_ALIGNED_ATTR uint8_t bootloader_flash_read_buffer[BOOTLOADER_FLASH_READ_LEN] = { 0 };
size_t block_data_len = block_len / BOOTLOADER_FLASH_READ_LEN * BOOTLOADER_FLASH_READ_LEN;
size_t remaining_data_len = block_len % BOOTLOADER_FLASH_READ_LEN;
/* Process block data */
if (block_data_len > 0) {
for (size_t data_processed = 0; data_processed < block_data_len; data_processed += BOOTLOADER_FLASH_READ_LEN) {
ret = esp_partition_read(partition, data_offset + data_processed, bootloader_flash_read_buffer, BOOTLOADER_FLASH_READ_LEN);
if (ret != ESP_OK) {
return ret;
}
memcpy(block + data_processed, bootloader_flash_read_buffer, BOOTLOADER_FLASH_READ_LEN);
}
}
/* Process remaining data */
if (remaining_data_len) {
ret = esp_partition_read(partition, data_offset + block_data_len, bootloader_flash_read_buffer, BOOTLOADER_FLASH_READ_LEN);
if (ret != ESP_OK) {
return ret;
}
memcpy(block + block_data_len, bootloader_flash_read_buffer, remaining_data_len);
}
} else {
ret = esp_partition_read(partition, data_offset, block, block_len);
}
return ret;
}
// validates item's header