Skip to content

Commit

Permalink
Merge branch 'feature/app_metadata_to_esp_system' into 'master'
Browse files Browse the repository at this point in the history
app_update: Moved app metadata to new component `esp_app_format`

Closes IDF-4808

See merge request espressif/esp-idf!18862
  • Loading branch information
mahavirj committed Aug 18, 2022
2 parents 1c25086 + 85d00a4 commit a2f028a
Show file tree
Hide file tree
Showing 37 changed files with 344 additions and 137 deletions.
1 change: 1 addition & 0 deletions .gitlab/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@
/components/driver/ @esp-idf-codeowners/peripherals
/components/efuse/ @esp-idf-codeowners/system
/components/esp_adc/ @esp-idf-codeowners/peripherals
/components/esp_app_format/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
/components/esp_common/ @esp-idf-codeowners/system
/components/esp_eth/ @esp-idf-codeowners/network
/components/esp_event/ @esp-idf-codeowners/system
Expand Down
27 changes: 2 additions & 25 deletions components/app_update/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,31 +1,8 @@
idf_component_register(SRCS "esp_ota_ops.c"
"esp_app_desc.c"
idf_component_register(SRCS "esp_ota_ops.c" "esp_ota_app_desc.c"
INCLUDE_DIRS "include"
REQUIRES spi_flash partition_table bootloader_support
REQUIRES spi_flash partition_table bootloader_support esp_app_format
PRIV_REQUIRES esptool_py efuse)

# esp_app_desc structure is added as an undefined symbol because otherwise the
# linker will ignore this structure as it has no other files depending on it.
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc")

if(CONFIG_APP_PROJECT_VER_FROM_CONFIG)
# Ignore current PROJECT_VER (which was set in __project_get_revision()).
# Gets the version from the CONFIG_APP_PROJECT_VER.
idf_build_set_property(PROJECT_VER "${CONFIG_APP_PROJECT_VER}")
endif()

# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
idf_build_get_property(project_ver PROJECT_VER)
idf_build_get_property(project_name PROJECT_NAME)
string(SUBSTRING "${project_ver}" 0 31 PROJECT_VER_CUT)
string(SUBSTRING "${project_name}" 0 31 PROJECT_NAME_CUT)
message(STATUS "App \"${PROJECT_NAME_CUT}\" version: ${PROJECT_VER_CUT}")

set_source_files_properties(
SOURCE "esp_app_desc.c"
PROPERTIES COMPILE_DEFINITIONS
"PROJECT_VER=\"${PROJECT_VER_CUT}\"; PROJECT_NAME=\"${PROJECT_NAME_CUT}\"")

if(NOT BOOTLOADER_BUILD)
partition_table_get_partition_info(otadata_offset "--partition-type data --partition-subtype ota" "offset")
partition_table_get_partition_info(otadata_size "--partition-type data --partition-subtype ota" "size")
Expand Down
21 changes: 21 additions & 0 deletions components/app_update/esp_ota_app_desc.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* SPDX-FileCopyrightText: 2017-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <assert.h>
#include <sys/param.h>
#include "esp_ota_ops.h"
#include "esp_attr.h"
#include "sdkconfig.h"

const esp_app_desc_t *esp_ota_get_app_description(void)
{
return esp_app_get_description();
}

int IRAM_ATTR esp_ota_get_app_elf_sha256(char* dst, size_t size)
{
return esp_app_get_elf_sha256(dst, size);
}
10 changes: 8 additions & 2 deletions components/app_update/esp_ota_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -651,8 +651,14 @@ esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, es

#ifdef CONFIG_BOOTLOADER_APP_ANTI_ROLLBACK
static esp_err_t esp_ota_set_anti_rollback(void) {
const esp_app_desc_t *app_desc = esp_ota_get_app_description();
return esp_efuse_update_secure_version(app_desc->secure_version);
const esp_partition_t* partition = esp_ota_get_running_partition();
esp_app_desc_t app_desc = {0};

esp_err_t err = esp_ota_get_partition_description(partition, &app_desc);
if (err == ESP_OK) {
return esp_efuse_update_secure_version(app_desc.secure_version);
}
return err;
}
#endif

Expand Down
13 changes: 10 additions & 3 deletions components/app_update/include/esp_ota_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
#include <stddef.h>
#include "esp_err.h"
#include "esp_partition.h"
#include "esp_image_format.h"
#include "esp_app_desc.h"
#include "esp_flash_partitions.h"
#include "soc/soc_caps.h"

Expand Down Expand Up @@ -44,20 +44,27 @@ typedef uint32_t esp_ota_handle_t;
/**
* @brief Return esp_app_desc structure. This structure includes app version.
*
* @note This API is present for backward compatibility reasons. Alternative function
* with the same functionality is `esp_app_get_description`
*
* Return description for running app.
* @return Pointer to esp_app_desc structure.
*/
const esp_app_desc_t *esp_ota_get_app_description(void);
const esp_app_desc_t *esp_ota_get_app_description(void) __attribute__((deprecated("Please use esp_app_get_description instead")));

/**
* @brief Fill the provided buffer with SHA256 of the ELF file, formatted as hexadecimal, null-terminated.
* If the buffer size is not sufficient to fit the entire SHA256 in hex plus a null terminator,
* the largest possible number of bytes will be written followed by a null.
*
* @note This API is present for backward compatibility reasons. Alternative function
* with the same functionality is `esp_app_get_elf_sha256`
*
* @param dst Destination buffer
* @param size Size of the buffer
* @return Number of bytes written to dst (including null terminator)
*/
int esp_ota_get_app_elf_sha256(char* dst, size_t size);
int esp_ota_get_app_elf_sha256(char* dst, size_t size) __attribute__((deprecated("Please use esp_app_get_elf_sha256 instead")));

/**
* @brief Commence an OTA update writing to the specified partition.
Expand Down
5 changes: 3 additions & 2 deletions components/app_update/test/test_ota_ops.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand All @@ -13,7 +13,6 @@
#include <unity.h>
#include <test_utils.h>
#include <esp_ota_ops.h>
#include "bootloader_common.h"

/* These OTA tests currently don't assume an OTA partition exists
on the device, so they're a bit limited
Expand Down Expand Up @@ -91,6 +90,8 @@ TEST_CASE("esp_ota_get_next_update_partition logic", "[ota]")

TEST_CASE("esp_ota_get_partition_description", "[ota]")
{
extern esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);

const esp_partition_t *running = esp_ota_get_running_partition();
TEST_ASSERT_NOT_NULL(running);
esp_app_desc_t app_desc1, app_desc2;
Expand Down
13 changes: 11 additions & 2 deletions components/bootloader_support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ set(srcs
if(BOOTLOADER_BUILD)
set(include_dirs "include" "bootloader_flash/include"
"private_include")
set(priv_requires micro-ecc spi_flash efuse)
set(priv_requires micro-ecc spi_flash efuse esp_app_format)
list(APPEND srcs
"src/bootloader_init.c"
"src/bootloader_clock_loader.c"
Expand All @@ -37,7 +37,7 @@ else()
set(include_dirs "include" "bootloader_flash/include")
set(priv_include_dirs "private_include")
# heap is required for `heap_memory_layout.h` header
set(priv_requires spi_flash mbedtls efuse app_update heap)
set(priv_requires spi_flash mbedtls efuse heap esp_app_format)
endif()

if(BOOTLOADER_BUILD)
Expand Down Expand Up @@ -86,6 +86,15 @@ idf_component_register(SRCS "${srcs}"
REQUIRES "${requires}"
PRIV_REQUIRES "${priv_requires}")

if(NOT BOOTLOADER_BUILD)
if(CONFIG_SECURE_SIGNED_ON_UPDATE)
if(CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME OR CONFIG_SECURE_SIGNED_APPS_RSA_SCHEME OR
CONFIG_SECURE_SIGNED_APPS_ECDSA_V2_SCHEME)
target_link_libraries(${COMPONENT_LIB} PRIVATE idf::app_update)
endif()
endif()
endif()

if(CONFIG_SECURE_SIGNED_APPS AND (CONFIG_SECURE_BOOT_V1_ENABLED OR CONFIG_SECURE_SIGNED_APPS_ECDSA_SCHEME))
if(BOOTLOADER_BUILD)
# Whether CONFIG_SECURE_BOOT_BUILD_SIGNED_BINARIES or not, we need verification key to embed
Expand Down
15 changes: 0 additions & 15 deletions components/bootloader_support/include/bootloader_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#pragma once
#include "esp_flash_partitions.h"
#include "esp_image_format.h"
#include "esp_app_format.h"

#ifdef __cplusplus
extern "C" {
Expand Down Expand Up @@ -151,20 +150,6 @@ int bootloader_common_get_active_otadata(esp_ota_select_entry_t *two_otadata);
*/
int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata, bool *valid_two_otadata, bool max);

/**
* @brief Returns esp_app_desc structure for app partition. This structure includes app version.
*
* Returns a description for the requested app partition.
* @param[in] partition App partition description.
* @param[out] app_desc Structure of info about app.
* @return
* - ESP_OK: Successful.
* - ESP_ERR_INVALID_ARG: The arguments passed are not valid.
* - ESP_ERR_NOT_FOUND: app_desc structure is not found. Magic word is incorrect.
* - ESP_FAIL: mapping is fail.
*/
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);

/**
* @brief Get chip package
*
Expand Down
22 changes: 0 additions & 22 deletions components/bootloader_support/include/esp_app_format.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,25 +106,3 @@ typedef struct {
} esp_image_segment_header_t;

#define ESP_IMAGE_MAX_SEGMENTS 16 /*!< Max count of segments in the image. */

#define ESP_APP_DESC_MAGIC_WORD 0xABCD5432 /*!< The magic word for the esp_app_desc structure that is in DROM. */

/**
* @brief Description about application.
*/
typedef struct {
uint32_t magic_word; /*!< Magic word ESP_APP_DESC_MAGIC_WORD */
uint32_t secure_version; /*!< Secure version */
uint32_t reserv1[2]; /*!< reserv1 */
char version[32]; /*!< Application version */
char project_name[32]; /*!< Project name */
char time[16]; /*!< Compile time */
char date[16]; /*!< Compile date*/
char idf_ver[32]; /*!< Version IDF */
uint8_t app_elf_sha256[32]; /*!< sha256 of elf file */
uint32_t reserv2[20]; /*!< reserv2 */
} esp_app_desc_t;

/** @cond */
_Static_assert(sizeof(esp_app_desc_t) == 256, "esp_app_desc_t should be 256 bytes");
/** @endcond */
24 changes: 0 additions & 24 deletions components/bootloader_support/src/bootloader_common_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -112,30 +112,6 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
return active_otadata;
}

esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc)
{
if (partition == NULL || app_desc == NULL || partition->offset == 0) {
return ESP_ERR_INVALID_ARG;
}

const uint32_t app_desc_offset = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t);
const uint32_t mmap_size = app_desc_offset + sizeof(esp_app_desc_t);
const uint8_t *image = bootloader_mmap(partition->offset, mmap_size);
if (image == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", partition->offset, mmap_size);
return ESP_FAIL;
}

memcpy(app_desc, image + app_desc_offset, sizeof(esp_app_desc_t));
bootloader_munmap(image);

if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) {
return ESP_ERR_NOT_FOUND;
}

return ESP_OK;
}

#if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )

#define RTC_RETAIN_MEM_ADDR (SOC_RTC_DRAM_HIGH - sizeof(rtc_retain_mem_t))
Expand Down
26 changes: 26 additions & 0 deletions components/bootloader_support/src/bootloader_utility.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@

#include "esp_cpu.h"
#include "esp_image_format.h"
#include "esp_app_desc.h"
#include "esp_secure_boot.h"
#include "esp_flash_encrypt.h"
#include "esp_flash_partitions.h"
Expand Down Expand Up @@ -119,6 +120,31 @@ static esp_err_t read_otadata(const esp_partition_pos_t *ota_info, esp_ota_selec
return ESP_OK;
}

esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc)
{
if (partition == NULL || app_desc == NULL || partition->offset == 0) {
return ESP_ERR_INVALID_ARG;
}

const uint32_t app_desc_offset = sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t);
const uint32_t mmap_size = app_desc_offset + sizeof(esp_app_desc_t);
const uint8_t *image = bootloader_mmap(partition->offset, mmap_size);
if (image == NULL) {
ESP_LOGE(TAG, "bootloader_mmap(0x%x, 0x%x) failed", partition->offset, mmap_size);
return ESP_FAIL;
}

memcpy(app_desc, image + app_desc_offset, sizeof(esp_app_desc_t));
bootloader_munmap(image);

if (app_desc->magic_word != ESP_APP_DESC_MAGIC_WORD) {
return ESP_ERR_NOT_FOUND;
}

return ESP_OK;
}


bool bootloader_utility_load_partition_table(bootloader_state_t *bs)
{
const esp_partition_info_t *partitions;
Expand Down
26 changes: 26 additions & 0 deletions components/esp_app_format/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
idf_component_register(SRCS "esp_app_desc.c"
INCLUDE_DIRS "include")

# esp_app_desc structure is added as an undefined symbol because otherwise the
# linker will ignore this structure as it has no other files depending on it.
if(NOT BOOTLOADER_BUILD)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u esp_app_desc")
endif()

if(CONFIG_APP_PROJECT_VER_FROM_CONFIG)
# Ignore current PROJECT_VER (which was set in __project_get_revision()).
# Gets the version from the CONFIG_APP_PROJECT_VER.
idf_build_set_property(PROJECT_VER "${CONFIG_APP_PROJECT_VER}")
endif()

# cut PROJECT_VER and PROJECT_NAME to required 32 characters.
idf_build_get_property(project_ver PROJECT_VER)
idf_build_get_property(project_name PROJECT_NAME)
string(SUBSTRING "${project_ver}" 0 31 PROJECT_VER_CUT)
string(SUBSTRING "${project_name}" 0 31 PROJECT_NAME_CUT)
message(STATUS "App \"${PROJECT_NAME_CUT}\" version: ${PROJECT_VER_CUT}")

set_source_files_properties(
SOURCE "esp_app_desc.c"
PROPERTIES COMPILE_DEFINITIONS
"PROJECT_VER=\"${PROJECT_VER_CUT}\"; PROJECT_NAME=\"${PROJECT_NAME_CUT}\"")
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
/*
* SPDX-FileCopyrightText: 2017-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <assert.h>
#include <sys/param.h>
#include "esp_ota_ops.h"
#include "esp_app_desc.h"
#include "esp_attr.h"
#include "sdkconfig.h"


// Application version info
const __attribute__((section(".rodata_desc"))) esp_app_desc_t esp_app_desc = {
.magic_word = ESP_APP_DESC_MAGIC_WORD,
Expand Down Expand Up @@ -50,7 +51,7 @@ _Static_assert(sizeof(IDF_VER) <= sizeof(esp_app_desc.idf_ver), "IDF_VER is long
_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_ota_get_app_description(void)
const esp_app_desc_t *esp_app_get_description(void)
{
return &esp_app_desc;
}
Expand All @@ -64,18 +65,18 @@ static inline char IRAM_ATTR to_hex_digit(unsigned val)
return (val < 10) ? ('0' + val) : ('a' + val - 10);
}

__attribute__((constructor)) void esp_ota_init_app_elf_sha256(void)
__attribute__((constructor)) void esp_init_app_elf_sha256(void)
{
esp_ota_get_app_elf_sha256(NULL, 0);
esp_app_get_elf_sha256(NULL, 0);
}

/* The esp_app_desc.app_elf_sha256 should be possible to print in panic handler 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 while start up in esp_ota_init_app_elf_sha256()
* For this reason we do a reading of esp_app_desc.app_elf_sha256 while start up in esp_init_app_elf_sha256()
* and keep it in the static s_app_elf_sha256 value.
*/
int IRAM_ATTR esp_ota_get_app_elf_sha256(char* dst, size_t size)
int IRAM_ATTR esp_app_get_elf_sha256(char* dst, size_t size)
{
static char s_app_elf_sha256[CONFIG_APP_RETRIEVE_LEN_ELF_SHA / 2];
static bool first_call = true;
Expand Down
Loading

0 comments on commit a2f028a

Please sign in to comment.