mirror of
https://github.com/espressif/esp-idf
synced 2025-03-10 01:29:21 -04:00
For the SoCs that support configurable MMU page size, it is possible that the bootloader and application are built with different MMU page size configuration. This mismatch is not supported at the moment and application verification fails (at bootup or during OTA update). Configuring MMU page size helps to optimize the flash space by having smaller alignment and padding (secure) requirements. Please note that the MMU page size is tied with the flash size configuration at the moment (`ESPTOOLPY_FLASHSIZE_XMB`). This MR ensures that application verification happens using the MMU page size configured in its binary header. Thus, bootloader and application can now have different MMU page sizes and different combinations shall be supported.
150 lines
5.2 KiB
C
150 lines
5.2 KiB
C
/*
|
|
* SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <sys/param.h>
|
|
#include <string.h>
|
|
#include "esp_app_desc.h"
|
|
#include "sdkconfig.h"
|
|
|
|
#include "esp_log.h"
|
|
|
|
// startup_internal.h is necessary for startup function definition, which does not exist on Linux (TODO: IDF-9950)
|
|
#if !CONFIG_IDF_TARGET_LINUX
|
|
#include "esp_private/startup_internal.h"
|
|
|
|
static const char *TAG = "app_init";
|
|
#endif
|
|
|
|
// Application version info
|
|
#if defined(__APPLE__) && CONFIG_IDF_TARGET_LINUX
|
|
const __attribute__((weak)) __attribute__((section("__RODATA_DESC,.rodata_desc"))) esp_app_desc_t esp_app_desc = {
|
|
#else
|
|
const __attribute__((weak)) __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
|
|
#endif /* #if defined(__APPLE__) && CONFIG_IDF_TARGET_LINUX */
|
|
.magic_word = ESP_APP_DESC_MAGIC_WORD,
|
|
#ifdef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
|
|
.version = "",
|
|
#else
|
|
.version = PROJECT_VER,
|
|
#endif
|
|
|
|
#ifdef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
|
|
.project_name = "",
|
|
#else
|
|
.project_name = PROJECT_NAME,
|
|
#endif
|
|
.idf_ver = IDF_VER,
|
|
|
|
// On Linux we just initialize the hash to some known value for testing
|
|
#if CONFIG_IDF_TARGET_LINUX
|
|
.app_elf_sha256 = { 0xDE, 0xAD, 0xBE, 0xEF, 0x47, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B},
|
|
#endif
|
|
|
|
#ifdef CONFIG_BOOTLOADER_APP_SECURE_VERSION
|
|
.secure_version = CONFIG_BOOTLOADER_APP_SECURE_VERSION,
|
|
#else
|
|
.secure_version = 0,
|
|
#endif
|
|
|
|
#ifdef CONFIG_APP_COMPILE_TIME_DATE
|
|
.time = __TIME__,
|
|
.date = __DATE__,
|
|
#else
|
|
.time = "",
|
|
.date = "",
|
|
#endif
|
|
.min_efuse_blk_rev_full = CONFIG_ESP_EFUSE_BLOCK_REV_MIN_FULL,
|
|
.max_efuse_blk_rev_full = CONFIG_ESP_EFUSE_BLOCK_REV_MAX_FULL,
|
|
.mmu_page_size = 31 - __builtin_clz(CONFIG_MMU_PAGE_SIZE),
|
|
};
|
|
|
|
#ifndef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
|
|
_Static_assert(sizeof(PROJECT_VER) <= sizeof(esp_app_desc.version), "PROJECT_VER is longer than version field in structure");
|
|
#endif
|
|
_Static_assert(sizeof(IDF_VER) <= sizeof(esp_app_desc.idf_ver), "IDF_VER is longer than idf_ver field in structure");
|
|
#ifndef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
|
|
_Static_assert(sizeof(PROJECT_NAME) <= sizeof(esp_app_desc.project_name), "PROJECT_NAME is longer than project_name field in structure");
|
|
#endif
|
|
|
|
const esp_app_desc_t *esp_app_get_description(void)
|
|
{
|
|
return &esp_app_desc;
|
|
}
|
|
|
|
char app_elf_sha256_str[CONFIG_APP_RETRIEVE_LEN_ELF_SHA + 1] = { 0 };
|
|
|
|
/* The esp_app_desc.app_elf_sha256 should be possible to print in panic handler or core dump during cache is disabled.
|
|
* But because the cache is disabled the reading esp_app_desc.app_elf_sha256 is not right and
|
|
* can lead to a complete lock-up of the CPU.
|
|
* For this reason we do a reading of esp_app_desc.app_elf_sha256 and convert to string while start up in esp_system_init_app_elf_sha256()
|
|
* and keep it in the static app_elf_sha256_str variable.
|
|
*/
|
|
static void esp_app_format_init_elf_sha256(void)
|
|
{
|
|
if (*((int *)&app_elf_sha256_str) != 0) {
|
|
// app_elf_sha256_str is already set
|
|
return;
|
|
}
|
|
// At -O2 optimization level, GCC optimizes out the copying of the first byte of the app_elf_sha256,
|
|
// because it is zero at compile time, and only modified afterwards by esptool.
|
|
// Casting to volatile disables the optimization.
|
|
const volatile char* src = (const volatile char*)esp_app_desc.app_elf_sha256;
|
|
for (size_t i = 0; i < sizeof(app_elf_sha256_str) / 2; ++i) {
|
|
char c = src[i];
|
|
for (size_t s = 0; s < 2; ++s) {
|
|
char val = (c >> 4) & 0xF;
|
|
app_elf_sha256_str[2 * i + s] = (val < 10) ? ('0' + val) : ('a' + val - 10);
|
|
c <<= 4;
|
|
}
|
|
}
|
|
app_elf_sha256_str[sizeof(app_elf_sha256_str) - 1] = 0;
|
|
}
|
|
|
|
int esp_app_get_elf_sha256(char* dst, size_t size)
|
|
{
|
|
if (dst == NULL || size < 2) {
|
|
return 0;
|
|
}
|
|
esp_app_format_init_elf_sha256();
|
|
size_t n = MIN(size, sizeof(app_elf_sha256_str));
|
|
memcpy(dst, app_elf_sha256_str, n);
|
|
dst[n - 1] = 0;
|
|
return n;
|
|
}
|
|
|
|
// startup function definition and execution does not exist on the Linux target
|
|
// (TODO: IDF-9950)
|
|
#if !CONFIG_IDF_TARGET_LINUX
|
|
ESP_SYSTEM_INIT_FN(init_show_app_info, CORE, BIT(0), 20)
|
|
{
|
|
// Load the current ELF SHA256
|
|
esp_app_format_init_elf_sha256();
|
|
|
|
// Display information about the current running image.
|
|
if (LOG_LOCAL_LEVEL >= ESP_LOG_INFO) {
|
|
ESP_EARLY_LOGI(TAG, "Application information:");
|
|
#ifndef CONFIG_APP_EXCLUDE_PROJECT_NAME_VAR
|
|
ESP_EARLY_LOGI(TAG, "Project name: %s", esp_app_desc.project_name);
|
|
#endif
|
|
#ifndef CONFIG_APP_EXCLUDE_PROJECT_VER_VAR
|
|
ESP_EARLY_LOGI(TAG, "App version: %s", esp_app_desc.version);
|
|
#endif
|
|
#ifdef CONFIG_BOOTLOADER_APP_SECURE_VERSION
|
|
ESP_EARLY_LOGI(TAG, "Secure version: %" PRIu32, esp_app_desc.secure_version);
|
|
#endif
|
|
#ifdef CONFIG_APP_COMPILE_TIME_DATE
|
|
ESP_EARLY_LOGI(TAG, "Compile time: %s %s", esp_app_desc.date, esp_app_desc.time);
|
|
#endif
|
|
char buf[17];
|
|
esp_app_get_elf_sha256(buf, sizeof(buf));
|
|
ESP_EARLY_LOGI(TAG, "ELF file SHA256: %s...", buf);
|
|
ESP_EARLY_LOGI(TAG, "ESP-IDF: %s", esp_app_desc.idf_ver);
|
|
}
|
|
return ESP_OK;
|
|
}
|
|
#endif
|