mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Add chip revision into image header
Check chip id and chip revision before boot app image Closes https://github.com/espressif/esp-idf/issues/4000
This commit is contained in:
parent
abdf12dc9e
commit
79923d0199
4
Kconfig
4
Kconfig
@ -29,6 +29,10 @@ mainmenu "Espressif IoT Development Framework Configuration"
|
|||||||
default "IDF_TARGET_NOT_SET" if IDF_TARGET_ENV=""
|
default "IDF_TARGET_NOT_SET" if IDF_TARGET_ENV=""
|
||||||
default IDF_TARGET_ENV
|
default IDF_TARGET_ENV
|
||||||
|
|
||||||
|
config IDF_FIRMWARE_CHIP_ID
|
||||||
|
hex
|
||||||
|
default 0x0000 if IDF_TARGET="esp32"
|
||||||
|
default 0xFFFF
|
||||||
|
|
||||||
menu "SDK tool configuration"
|
menu "SDK tool configuration"
|
||||||
config SDK_TOOLPREFIX
|
config SDK_TOOLPREFIX
|
||||||
|
@ -42,7 +42,7 @@
|
|||||||
#include "esp_efuse.h"
|
#include "esp_efuse.h"
|
||||||
|
|
||||||
|
|
||||||
#define SUB_TYPE_ID(i) (i & 0x0F)
|
#define SUB_TYPE_ID(i) (i & 0x0F)
|
||||||
|
|
||||||
typedef struct ota_ops_entry_ {
|
typedef struct ota_ops_entry_ {
|
||||||
uint32_t handle;
|
uint32_t handle;
|
||||||
@ -200,7 +200,7 @@ esp_err_t esp_ota_write(esp_ota_handle_t handle, const void *data, size_t size)
|
|||||||
// must erase the partition before writing to it
|
// must erase the partition before writing to it
|
||||||
assert(it->erased_size > 0 && "must erase the partition before writing to it");
|
assert(it->erased_size > 0 && "must erase the partition before writing to it");
|
||||||
if (it->wrote_size == 0 && it->partial_bytes == 0 && size > 0 && data_bytes[0] != ESP_IMAGE_HEADER_MAGIC) {
|
if (it->wrote_size == 0 && it->partial_bytes == 0 && size > 0 && data_bytes[0] != ESP_IMAGE_HEADER_MAGIC) {
|
||||||
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x", data_bytes[0]);
|
ESP_LOGE(TAG, "OTA image has invalid magic byte (expected 0xE9, saw 0x%02x)", data_bytes[0]);
|
||||||
return ESP_ERR_OTA_VALIDATE_FAILED;
|
return ESP_ERR_OTA_VALIDATE_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "esp_flash_partitions.h"
|
#include "esp_flash_partitions.h"
|
||||||
#include "esp_image_format.h"
|
#include "esp_image_format.h"
|
||||||
|
#include "esp_app_format.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@ -129,7 +130,7 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Returns esp_app_desc structure for app partition. This structure includes app version.
|
* @brief Returns esp_app_desc structure for app partition. This structure includes app version.
|
||||||
*
|
*
|
||||||
* Returns a description for the requested app partition.
|
* Returns a description for the requested app partition.
|
||||||
* @param[in] partition App partition description.
|
* @param[in] partition App partition description.
|
||||||
* @param[out] app_desc Structure of info about app.
|
* @param[out] app_desc Structure of info about app.
|
||||||
@ -141,6 +142,16 @@ int bootloader_common_select_otadata(const esp_ota_select_entry_t *two_otadata,
|
|||||||
*/
|
*/
|
||||||
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);
|
esp_err_t bootloader_common_get_partition_description(const esp_partition_pos_t *partition, esp_app_desc_t *app_desc);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Check if the image (bootloader and application) has valid chip ID and revision
|
||||||
|
*
|
||||||
|
* @param img_hdr: image header
|
||||||
|
* @return
|
||||||
|
* - ESP_OK: image and chip are matched well
|
||||||
|
* - ESP_FAIL: image doesn't match to the chip
|
||||||
|
*/
|
||||||
|
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
|
* @brief Configure VDDSDIO, call this API to rise VDDSDIO to 1.9V when VDDSDIO regulator is enabled as 1.8V mode.
|
||||||
*/
|
*/
|
||||||
|
@ -13,6 +13,19 @@
|
|||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief ESP chip ID
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
typedef enum {
|
||||||
|
ESP_CHIP_ID_ESP32 = 0x0000, /*!< chip ID: ESP32 */
|
||||||
|
ESP_CHIP_ID_INVALID = 0xFFFF /*!< Invalid chip ID (we defined it to make sure the esp_chip_id_t is 2 bytes size) */
|
||||||
|
} __attribute__((packed)) esp_chip_id_t;
|
||||||
|
|
||||||
|
/** @cond */
|
||||||
|
_Static_assert(sizeof(esp_chip_id_t) == 2, "esp_chip_id_t should be 16 bit");
|
||||||
|
/** @endcond */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief SPI flash mode, used in esp_image_header_t
|
* @brief SPI flash mode, used in esp_image_header_t
|
||||||
*/
|
*/
|
||||||
@ -63,7 +76,9 @@ typedef struct {
|
|||||||
* the IDF bootloader uses software to configure the WP
|
* the IDF bootloader uses software to configure the WP
|
||||||
* pin and sets this field to 0xEE=disabled) */
|
* pin and sets this field to 0xEE=disabled) */
|
||||||
uint8_t spi_pin_drv[3]; /*!< Drive settings for the SPI flash pins (read by ROM bootloader) */
|
uint8_t spi_pin_drv[3]; /*!< Drive settings for the SPI flash pins (read by ROM bootloader) */
|
||||||
uint8_t reserved[11]; /*!< Reserved bytes in ESP32 additional header space, currently unused */
|
esp_chip_id_t chip_id; /*!< Chip identification number */
|
||||||
|
uint8_t min_chip_rev; /*!< Minimum chip revision supported by image */
|
||||||
|
uint8_t reserved[8]; /*!< Reserved bytes in additional header space, currently unused */
|
||||||
uint8_t hash_appended; /*!< If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum.
|
uint8_t hash_appended; /*!< If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum.
|
||||||
* Included in image length. This digest
|
* Included in image length. This digest
|
||||||
* is separate to secure boot and only used for detecting corruption.
|
* is separate to secure boot and only used for detecting corruption.
|
||||||
|
@ -28,6 +28,7 @@
|
|||||||
#include "esp_image_format.h"
|
#include "esp_image_format.h"
|
||||||
#include "bootloader_sha.h"
|
#include "bootloader_sha.h"
|
||||||
#include "sys/param.h"
|
#include "sys/param.h"
|
||||||
|
#include "esp_efuse.h"
|
||||||
|
|
||||||
#define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
|
#define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
|
||||||
|
|
||||||
@ -270,3 +271,23 @@ void bootloader_common_vddsdio_configure()
|
|||||||
}
|
}
|
||||||
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
|
||||||
}
|
}
|
||||||
|
|
||||||
|
esp_err_t bootloader_common_check_chip_validity(const esp_image_header_t* img_hdr)
|
||||||
|
{
|
||||||
|
esp_err_t err = ESP_OK;
|
||||||
|
esp_chip_id_t chip_id = CONFIG_IDF_FIRMWARE_CHIP_ID;
|
||||||
|
if (chip_id != img_hdr->chip_id) {
|
||||||
|
ESP_LOGE(TAG, "image has invalid chip ID, expected at least %d, found %d", chip_id, img_hdr->chip_id);
|
||||||
|
err = ESP_FAIL;
|
||||||
|
}
|
||||||
|
uint8_t revision = esp_efuse_get_chip_ver();
|
||||||
|
if (revision < img_hdr->min_chip_rev) {
|
||||||
|
ESP_LOGE(TAG, "image has invalid chip revision, expected at least %d, found %d", revision, img_hdr->min_chip_rev);
|
||||||
|
err = ESP_FAIL;
|
||||||
|
} else if (revision != img_hdr->min_chip_rev) {
|
||||||
|
ESP_LOGI(TAG, "This chip is revision %d but project was configured for minimum revision %d. "\
|
||||||
|
"Suggest setting project minimum revision to %d if safe to do so.",
|
||||||
|
revision, img_hdr->min_chip_rev, revision);
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
@ -41,6 +41,7 @@
|
|||||||
#include "soc/spi_periph.h"
|
#include "soc/spi_periph.h"
|
||||||
|
|
||||||
#include "sdkconfig.h"
|
#include "sdkconfig.h"
|
||||||
|
#include "esp_efuse.h"
|
||||||
#include "esp_image_format.h"
|
#include "esp_image_format.h"
|
||||||
#include "esp_secure_boot.h"
|
#include "esp_secure_boot.h"
|
||||||
#include "esp_flash_encrypt.h"
|
#include "esp_flash_encrypt.h"
|
||||||
@ -127,6 +128,14 @@ static esp_err_t bootloader_main()
|
|||||||
ESP_LOGE(TAG, "failed to load bootloader header!");
|
ESP_LOGE(TAG, "failed to load bootloader header!");
|
||||||
return ESP_FAIL;
|
return ESP_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Check chip ID and minimum chip revision that supported by this image */
|
||||||
|
uint8_t revision = esp_efuse_get_chip_ver();
|
||||||
|
ESP_LOGI(TAG, "Chip Revision: %d", revision);
|
||||||
|
if (bootloader_common_check_chip_validity(&fhdr) != ESP_OK) {
|
||||||
|
return ESP_FAIL;
|
||||||
|
}
|
||||||
|
|
||||||
bootloader_init_flash_configure(&fhdr);
|
bootloader_init_flash_configure(&fhdr);
|
||||||
#if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240)
|
#if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240)
|
||||||
//Check if ESP32 is rated for a CPU frequency of 160MHz only
|
//Check if ESP32 is rated for a CPU frequency of 160MHz only
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include <bootloader_random.h>
|
#include <bootloader_random.h>
|
||||||
#include <bootloader_sha.h>
|
#include <bootloader_sha.h>
|
||||||
#include "bootloader_util.h"
|
#include "bootloader_util.h"
|
||||||
|
#include "bootloader_common.h"
|
||||||
|
|
||||||
/* Checking signatures as part of verifying images is necessary:
|
/* Checking signatures as part of verifying images is necessary:
|
||||||
- Always if secure boot is enabled
|
- Always if secure boot is enabled
|
||||||
@ -278,6 +279,9 @@ static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t
|
|||||||
}
|
}
|
||||||
err = ESP_ERR_IMAGE_INVALID;
|
err = ESP_ERR_IMAGE_INVALID;
|
||||||
}
|
}
|
||||||
|
if (bootloader_common_check_chip_validity(image) != ESP_OK) {
|
||||||
|
err = ESP_ERR_IMAGE_INVALID;
|
||||||
|
}
|
||||||
if (!silent) {
|
if (!silent) {
|
||||||
if (image->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) {
|
if (image->spi_mode > ESP_IMAGE_SPI_MODE_SLOW_READ) {
|
||||||
ESP_LOGW(TAG, "image at 0x%x has invalid SPI mode %d", src_addr, image->spi_mode);
|
ESP_LOGW(TAG, "image at 0x%x has invalid SPI mode %d", src_addr, image->spi_mode);
|
||||||
|
@ -400,15 +400,6 @@ void start_cpu0_default(void)
|
|||||||
esp_err_t flash_ret = esp_flash_init_default_chip();
|
esp_err_t flash_ret = esp_flash_init_default_chip();
|
||||||
assert(flash_ret == ESP_OK);
|
assert(flash_ret == ESP_OK);
|
||||||
|
|
||||||
uint8_t revision = esp_efuse_get_chip_ver();
|
|
||||||
ESP_LOGI(TAG, "Chip Revision: %d", revision);
|
|
||||||
if (revision > CONFIG_ESP32_REV_MIN) {
|
|
||||||
ESP_LOGW(TAG, "Chip revision is higher than the one configured in menuconfig. Suggest to upgrade it.");
|
|
||||||
} else if(revision != CONFIG_ESP32_REV_MIN) {
|
|
||||||
ESP_LOGE(TAG, "ESP-IDF can't support this chip revision. Modify minimum supported revision in menuconfig");
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PM_ENABLE
|
#ifdef CONFIG_PM_ENABLE
|
||||||
esp_pm_impl_init();
|
esp_pm_impl_init();
|
||||||
#ifdef CONFIG_PM_DFS_INIT_AUTO
|
#ifdef CONFIG_PM_DFS_INIT_AUTO
|
||||||
|
@ -31,6 +31,10 @@ endif
|
|||||||
|
|
||||||
ESPTOOL_ELF2IMAGE_OPTIONS :=
|
ESPTOOL_ELF2IMAGE_OPTIONS :=
|
||||||
|
|
||||||
|
ifdef CONFIG_ESP32_REV_MIN
|
||||||
|
ESPTOOL_ELF2IMAGE_OPTIONS += --min-rev $(CONFIG_ESP32_REV_MIN)
|
||||||
|
endif
|
||||||
|
|
||||||
ifdef CONFIG_SECURE_BOOT_ENABLED
|
ifdef CONFIG_SECURE_BOOT_ENABLED
|
||||||
ifndef CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION
|
ifndef CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION
|
||||||
ifndef IS_BOOTLOADER_BUILD
|
ifndef IS_BOOTLOADER_BUILD
|
||||||
|
@ -1 +1 @@
|
|||||||
Subproject commit 1a7dbf787e7e504acdeaea074d15a5ccaf87e9e8
|
Subproject commit 4f1e825d2d1ee33b896b3977905fb29ac6cc0794
|
@ -52,6 +52,10 @@ if(CONFIG_SECURE_BOOT_ENABLED AND
|
|||||||
set(ESPTOOLPY_ELF2IMAGE_OPTIONS ${ESPTOOLPY_ELF2IMAGE_OPTIONS} --secure-pad)
|
set(ESPTOOLPY_ELF2IMAGE_OPTIONS ${ESPTOOLPY_ELF2IMAGE_OPTIONS} --secure-pad)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(CONFIG_ESP32_REV_MIN)
|
||||||
|
set(ESPTOOLPY_ELF2IMAGE_OPTIONS ${ESPTOOLPY_ELF2IMAGE_OPTIONS} --min-rev ${CONFIG_ESP32_REV_MIN})
|
||||||
|
endif()
|
||||||
|
|
||||||
if(CONFIG_ESPTOOLPY_FLASHSIZE_DETECT)
|
if(CONFIG_ESPTOOLPY_FLASHSIZE_DETECT)
|
||||||
# Set ESPFLASHSIZE to 'detect' *after* elf2image options are generated,
|
# Set ESPFLASHSIZE to 'detect' *after* elf2image options are generated,
|
||||||
# as elf2image can't have 'detect' as an option...
|
# as elf2image can't have 'detect' as an option...
|
||||||
|
Loading…
x
Reference in New Issue
Block a user