Skip to content

Commit

Permalink
esp_bootloader_format: Adds bootloader description structure to read …
Browse files Browse the repository at this point in the history
…bootloader version from app

Closes #8800
Closes #9132
  • Loading branch information
KonstantinKondrashov committed May 10, 2023
1 parent 87dd7bb commit 6983840
Show file tree
Hide file tree
Showing 38 changed files with 419 additions and 49 deletions.
1 change: 1 addition & 0 deletions .gitlab/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
/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_bootloader_format/ @esp-idf-codeowners/system @esp-idf-codeowners/app-utilities
/components/esp_coex/ @esp-idf-codeowners/wifi @esp-idf-codeowners/bluetooth @esp-idf-codeowners/ieee802154
/components/esp_common/ @esp-idf-codeowners/system
/components/esp_eth/ @esp-idf-codeowners/network
Expand Down
2 changes: 1 addition & 1 deletion components/app_update/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
idf_component_register(SRCS "esp_ota_ops.c" "esp_ota_app_desc.c"
INCLUDE_DIRS "include"
REQUIRES partition_table bootloader_support esp_app_format esp_partition
REQUIRES partition_table bootloader_support esp_app_format esp_bootloader_format esp_partition
PRIV_REQUIRES esptool_py efuse spi_flash)

if(NOT BOOTLOADER_BUILD)
Expand Down
28 changes: 28 additions & 0 deletions components/app_update/esp_ota_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
#include "esp_system.h"
#include "esp_efuse.h"
#include "esp_attr.h"
#include "esp_bootloader_desc.h"
#include "esp_flash.h"

#if CONFIG_IDF_TARGET_ESP32
#include "esp32/rom/secure_boot.h"
Expand Down Expand Up @@ -628,6 +630,32 @@ const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *

}

esp_err_t esp_ota_get_bootloader_description(const esp_partition_t *bootloader_partition, esp_bootloader_desc_t *desc)
{
if (desc == NULL) {
return ESP_ERR_INVALID_ARG;
}
esp_partition_t partition = { 0 };
if (bootloader_partition == NULL) {
partition.flash_chip = esp_flash_default_chip;
partition.encrypted = esp_flash_encryption_enabled();
partition.address = CONFIG_BOOTLOADER_OFFSET_IN_FLASH;
partition.size = CONFIG_PARTITION_TABLE_OFFSET - CONFIG_BOOTLOADER_OFFSET_IN_FLASH;
} else {
memcpy(&partition, bootloader_partition, sizeof(partition));
}
esp_err_t err = esp_partition_read(&partition, sizeof(esp_image_header_t) + sizeof(esp_image_segment_header_t), desc, sizeof(esp_bootloader_desc_t));
if (err != ESP_OK) {
return err;
}

if (desc->magic_byte != ESP_BOOTLOADER_DESC_MAGIC_BYTE) {
return ESP_ERR_NOT_FOUND;
}

return ESP_OK;
}

esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, esp_app_desc_t *app_desc)
{
if (partition == NULL || app_desc == NULL) {
Expand Down
18 changes: 18 additions & 0 deletions components/app_update/include/esp_ota_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "esp_err.h"
#include "esp_partition.h"
#include "esp_app_desc.h"
#include "esp_bootloader_desc.h"
#include "esp_flash_partitions.h"
#include "soc/soc_caps.h"

Expand Down Expand Up @@ -251,6 +252,23 @@ const esp_partition_t* esp_ota_get_next_update_partition(const esp_partition_t *
*/
esp_err_t esp_ota_get_partition_description(const esp_partition_t *partition, esp_app_desc_t *app_desc);

/**
* @brief Returns the description structure of the bootloader.
*
* @param[in] bootloader_partition Pointer to bootloader partition.
* If NULL, then the current bootloader is used (the default location).
* offset = CONFIG_BOOTLOADER_OFFSET_IN_FLASH,
* size = CONFIG_PARTITION_TABLE_OFFSET - CONFIG_BOOTLOADER_OFFSET_IN_FLASH,
* @param[out] desc Structure of info about bootloader.
* @return
* - ESP_OK Successful.
* - ESP_ERR_NOT_FOUND Description structure is not found in the bootloader image. Magic byte is incorrect.
* - ESP_ERR_INVALID_ARG Arguments is NULL.
* - ESP_ERR_INVALID_SIZE Read would go out of bounds of the partition.
* - or one of error codes from lower-level flash driver.
*/
esp_err_t esp_ota_get_bootloader_description(const esp_partition_t *bootloader_partition, esp_bootloader_desc_t *desc);

/**
* @brief Returns number of ota partitions provided in partition table.
*
Expand Down
2 changes: 2 additions & 0 deletions components/bootloader/Kconfig.projbuild
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
menu "Bootloader config"

orsource "../esp_bootloader_format/Kconfig.bootloader"

config BOOTLOADER_OFFSET_IN_FLASH
hex
default 0x1000 if IDF_TARGET_ESP32 || IDF_TARGET_ESP32S2
Expand Down
7 changes: 6 additions & 1 deletion components/bootloader/subproject/main/ld/esp32/bootloader.ld
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,14 @@ SECTIONS
_bss_end = ABSOLUTE(.);
} >dram_seg

.dram0.data :
.dram0.bootdesc : ALIGN(0x10)
{
_data_start = ABSOLUTE(.);
*(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */
} > dram_seg

.dram0.data : ALIGN(0x10)
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,14 @@ SECTIONS
_bss_end = ABSOLUTE(.);
} > dram_seg

.dram0.data :
.dram0.bootdesc : ALIGN(0x10)
{
_data_start = ABSOLUTE(.);
*(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */
} > dram_seg

.dram0.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -131,9 +131,14 @@ SECTIONS
_bss_end = ABSOLUTE(.);
} > dram_seg

.dram0.data :
.dram0.bootdesc : ALIGN(0x10)
{
_data_start = ABSOLUTE(.);
*(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */
} > dram_seg

.dram0.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,9 +128,14 @@ SECTIONS
_bss_end = ABSOLUTE(.);
} > dram_seg

.dram0.data :
.dram0.bootdesc : ALIGN(0x10)
{
_data_start = ABSOLUTE(.);
*(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */
} > dram_seg

.dram0.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,12 @@ SECTIONS
_bss_end = ABSOLUTE(.);
} > dram_seg

.dram0.bootdesc : ALIGN(0x10)
{
_data_start = ABSOLUTE(.);
*(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */
} > dram_seg

.dram0.data :
{
_data_start = ABSOLUTE(.);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,9 +98,14 @@ SECTIONS
_bss_end = ABSOLUTE(.);
} >dram_seg

.dram0.data :
.dram0.bootdesc : ALIGN(0x10)
{
_data_start = ABSOLUTE(.);
*(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */
} > dram_seg

.dram0.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,9 +132,14 @@ SECTIONS
_bss_end = ABSOLUTE(.);
} > dram_seg

.dram0.data :
.dram0.bootdesc : ALIGN(0x10)
{
_data_start = ABSOLUTE(.);
*(.data_bootloader_desc .data_bootloader_desc.*) /* Should be the first. Bootloader version info. DO NOT PUT ANYTHING BEFORE IT! */
} > dram_seg

.dram0.data :
{
*(.data)
*(.data.*)
*(.gnu.linkonce.d.*)
Expand Down
7 changes: 5 additions & 2 deletions components/bootloader_support/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ endif()
if(BOOTLOADER_BUILD OR CONFIG_APP_BUILD_TYPE_RAM)
set(include_dirs "include" "bootloader_flash/include"
"private_include")
set(priv_requires micro-ecc spi_flash efuse esp_app_format)
set(priv_requires micro-ecc spi_flash efuse esp_bootloader_format esp_app_format)
list(APPEND srcs
"src/bootloader_init.c"
"src/bootloader_clock_loader.c"
Expand All @@ -50,7 +50,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 heap esp_app_format)
set(priv_requires spi_flash mbedtls efuse heap esp_bootloader_format esp_app_format)
endif()

if(BOOTLOADER_BUILD)
Expand Down Expand Up @@ -170,4 +170,7 @@ endif()

if(BOOTLOADER_BUILD)
target_link_libraries(${COMPONENT_LIB} INTERFACE "-u abort")
# esp_bootloader_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_bootloader_desc")
endif()
10 changes: 7 additions & 3 deletions components/bootloader_support/src/bootloader_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include "soc/rtc.h"
#include "hal/wdt_hal.h"
#include "hal/efuse_hal.h"
#include "esp_bootloader_desc.h"

static const char *TAG = "boot";

Expand Down Expand Up @@ -92,10 +93,13 @@ void bootloader_enable_random(void)

void bootloader_print_banner(void)
{
ESP_EARLY_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", IDF_VER);
#ifndef CONFIG_APP_REPRODUCIBLE_BUILD
ESP_EARLY_LOGI(TAG, "compile time " __DATE__ " " __TIME__);
if (CONFIG_BOOTLOADER_LOG_LEVEL >= ESP_LOG_INFO) {
const esp_bootloader_desc_t *desc = esp_bootloader_get_description();
ESP_EARLY_LOGI(TAG, "ESP-IDF %s 2nd stage bootloader", desc->idf_ver);
#ifdef CONFIG_BOOTLOADER_COMPILE_TIME_DATE
ESP_EARLY_LOGI(TAG, "compile time %s", desc->date_time);
#endif
}

#if CONFIG_FREERTOS_UNICORE
#if (SOC_CPU_CORES_NUM > 1)
Expand Down
43 changes: 24 additions & 19 deletions components/esp_app_format/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,26 +1,31 @@
idf_component_register(SRCS "esp_app_desc.c"
if(NOT BOOTLOADER_BUILD)
set(src "esp_app_desc.c")
else()
set(src "")
endif()
idf_component_register(SRCS ${src}
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)
# 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")
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()
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}")
# 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}\"")
set_source_files_properties(
SOURCE "esp_app_desc.c"
PROPERTIES COMPILE_DEFINITIONS
"PROJECT_VER=\"${PROJECT_VER_CUT}\"; PROJECT_NAME=\"${PROJECT_NAME_CUT}\"")
endif()
1 change: 1 addition & 0 deletions components/esp_app_format/Kconfig.projbuild
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ menu "Application manager"
config APP_COMPILE_TIME_DATE
bool "Use time/date stamp for app"
default y
depends on !APP_REPRODUCIBLE_BUILD
help
If set, then the app will be built with the current time/date stamp. It is stored in the app description
structure. If not set, time/date stamp will be excluded from app image. This can be useful for getting the
Expand Down
4 changes: 2 additions & 2 deletions components/esp_app_format/esp_app_desc.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2022 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
Expand Down Expand Up @@ -33,7 +33,7 @@ const __attribute__((weak)) __attribute__((section(".rodata_desc"))) esp_app_de
.secure_version = 0,
#endif

#if defined(CONFIG_APP_COMPILE_TIME_DATE) && !defined(CONFIG_APP_REPRODUCIBLE_BUILD)
#ifdef CONFIG_APP_COMPILE_TIME_DATE
.time = __TIME__,
.date = __DATE__,
#else
Expand Down
6 changes: 6 additions & 0 deletions components/esp_bootloader_format/.build-test-rules.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps

components/esp_bootloader_format/test_apps:
disable:
- if: IDF_TARGET != "esp32"
reason: It is enough to test it only for one target
11 changes: 11 additions & 0 deletions components/esp_bootloader_format/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
idf_component_register(SRCS "esp_bootloader_desc.c"
INCLUDE_DIRS "include")

if(BOOTLOADER_BUILD)
# esp_bootloader_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_bootloader_desc")

idf_build_get_property(project_name PROJECT_NAME)
message(STATUS "Bootloader project name: \"${project_name}\" version: ${CONFIG_BOOTLOADER_PROJECT_VER}")
endif()
21 changes: 21 additions & 0 deletions components/esp_bootloader_format/Kconfig.bootloader
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
menu "Bootloader manager"

config BOOTLOADER_COMPILE_TIME_DATE
bool "Use time/date stamp for bootloader"
default y
depends on !APP_REPRODUCIBLE_BUILD
help
If set, then the bootloader will be built with the current time/date stamp.
It is stored in the bootloader description
structure. If not set, time/date stamp will be excluded from bootloader image.
This can be useful for getting the
same binary image files made from the same source, but at different times.

config BOOTLOADER_PROJECT_VER
int "Project version"
default 1
range 0 4294967295
help
Project version. It is placed in "version" field of the esp_bootloader_desc structure.
The type of this field is "uint32_t".
endmenu # "Bootloader manager"
Loading

0 comments on commit 6983840

Please sign in to comment.