Merge branch 'feature/add_chip_revision_to_image_header_v3.3' into 'release/v3.3'

Add chip revision into image header (v3.3)

See merge request espressif/esp-idf!6128
This commit is contained in:
Angus Gratton
2019-10-10 11:24:00 +08:00
12 changed files with 113 additions and 16 deletions

View File

@@ -23,6 +23,10 @@ mainmenu "Espressif IoT Development Framework Configuration"
default "IDF_TARGET_NOT_SET" if 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"
config TOOLPREFIX

View File

@@ -43,7 +43,7 @@
#include "esp_efuse.h"
#define SUB_TYPE_ID(i) (i & 0x0F)
#define SUB_TYPE_ID(i) (i & 0x0F)
typedef struct ota_ops_entry_ {
uint32_t handle;
@@ -208,7 +208,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
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) {
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;
}

View File

@@ -15,6 +15,7 @@
#pragma once
#include "esp_flash_data_types.h"
#include "esp_image_format.h"
#include "esp_image_format.h"
/// Type of hold a GPIO in low state
typedef enum {
@@ -125,7 +126,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.
*
*
* Returns a description for the requested app partition.
* @param[in] partition App partition description.
* @param[out] app_desc Structure of info about app.
@@ -137,6 +138,23 @@ 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);
/**
* @brief Get chip revision
*
* @return Chip revision number
*/
uint8_t bootloader_common_get_chip_revision(void);
/**
* @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.
*/

View File

@@ -55,6 +55,19 @@ typedef enum {
#define ESP_IMAGE_HEADER_MAGIC 0xE9
/**
* @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 */
/* Main header of binary image */
typedef struct {
uint8_t magic;
@@ -71,8 +84,9 @@ typedef struct {
uint8_t wp_pin;
/* Drive settings for the SPI flash pins (read by ROM bootloader) */
uint8_t spi_pin_drv[3];
/* Reserved bytes in ESP32 additional header space, currently unused */
uint8_t reserved[11];
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 */
/* If 1, a SHA256 digest "simple hash" (of the entire image) is appended after the checksum. Included in image length. This digest
* is separate to secure boot and only used for detecting corruption. For secure boot signed images, the signature
* is appended after this (and the simple hash is included in the signed data). */

View File

@@ -30,6 +30,8 @@
#include "soc/efuse_reg.h"
#include "soc/rtc.h"
#include "soc/spi_reg.h"
#include "soc/efuse_reg.h"
#include "soc/apb_ctrl_reg.h"
#include "esp_image_format.h"
#include "bootloader_sha.h"
#include "sys/param.h"
@@ -275,3 +277,51 @@ void bootloader_common_vddsdio_configure()
}
#endif // CONFIG_BOOTLOADER_VDDSDIO_BOOST
}
#ifdef CONFIG_IDF_TARGET_ESP32
uint8_t bootloader_common_get_chip_revision(void)
{
uint8_t eco_bit0, eco_bit1, eco_bit2;
eco_bit0 = (REG_READ(EFUSE_BLK0_RDATA3_REG) & 0xF000) >> 15;
eco_bit1 = (REG_READ(EFUSE_BLK0_RDATA5_REG) & 0x100000) >> 20;
eco_bit2 = (REG_READ(APB_CTRL_DATE_REG) & 0x80000000) >> 31;
uint32_t combine_value = (eco_bit2 << 2) | (eco_bit1 << 1) | eco_bit0;
uint8_t chip_ver = 0;
switch (combine_value) {
case 0:
chip_ver = 0;
break;
case 1:
chip_ver = 1;
break;
case 3:
chip_ver = 2;
break;
case 7:
chip_ver = 3;
break;
default:
chip_ver = 0;
break;
}
return chip_ver;
}
#endif
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, "mismatch chip ID, expect %d, found %d", chip_id, img_hdr->chip_id);
err = ESP_FAIL;
}
uint8_t revision = bootloader_common_get_chip_revision();
if (revision < img_hdr->min_chip_rev) {
ESP_LOGE(TAG, "can't run on lower chip revision, expect %d, found %d", revision, img_hdr->min_chip_rev);
err = ESP_FAIL;
} else if (revision != img_hdr->min_chip_rev) {
ESP_LOGI(TAG, "mismatch chip revision, expect %d, found %d", revision, img_hdr->min_chip_rev);
}
return err;
}

View File

@@ -126,6 +126,14 @@ static esp_err_t bootloader_main()
ESP_LOGE(TAG, "failed to load bootloader header!");
return ESP_FAIL;
}
/* Check chip ID and minimum chip revision that supported by this image */
uint8_t revision = bootloader_common_get_chip_revision();
ESP_LOGI(TAG, "Chip Revision: %d", revision);
if (bootloader_common_check_chip_validity(&fhdr) != ESP_OK) {
return ESP_FAIL;
}
bootloader_init_flash_configure(&fhdr);
#if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240)
//Check if ESP32 is rated for a CPU frequency of 160MHz only

View File

@@ -24,6 +24,7 @@
#include <bootloader_random.h>
#include <bootloader_sha.h>
#include "bootloader_util.h"
#include "bootloader_common.h"
/* Checking signatures as part of verifying images is necessary:
- Always if secure boot is enabled
@@ -280,6 +281,9 @@ static esp_err_t verify_image_header(uint32_t src_addr, const esp_image_header_t
}
err = ESP_ERR_IMAGE_INVALID;
}
if (bootloader_common_check_chip_validity(image) != ESP_OK) {
err = ESP_ERR_IMAGE_INVALID;
}
if (!silent) {
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);

View File

@@ -35,7 +35,7 @@ uint8_t esp_efuse_get_chip_ver(void)
uint8_t eco_bit0, eco_bit1, eco_bit2;
esp_efuse_read_field_blob(ESP_EFUSE_CHIP_VER_REV1, &eco_bit0, 1);
esp_efuse_read_field_blob(ESP_EFUSE_CHIP_VER_REV2, &eco_bit1, 1);
eco_bit2 = (REG_READ(APB_CTRL_DATE_REG) & 80000000) >> 31;
eco_bit2 = (REG_READ(APB_CTRL_DATE_REG) & 0x80000000) >> 31;
uint32_t combine_value = (eco_bit2 << 2) | (eco_bit1 << 1) | eco_bit0;
uint8_t chip_ver = 0;
switch (combine_value) {

View File

@@ -398,15 +398,6 @@ void start_cpu0_default(void)
/* init default OS-aware flash access critical section */
spi_flash_guard_set(&g_flash_guard_default_ops);
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
esp_pm_impl_init();
#ifdef CONFIG_PM_DFS_INIT_AUTO

View File

@@ -31,6 +31,10 @@ endif
ESPTOOL_ELF2IMAGE_OPTIONS :=
ifdef CONFIG_ESP32_REV_MIN
ESPTOOL_ELF2IMAGE_OPTIONS += --min-rev $(CONFIG_ESP32_REV_MIN)
endif
ifdef CONFIG_SECURE_BOOT_ENABLED
ifndef CONFIG_SECURE_BOOT_ALLOW_SHORT_APP_PARTITION
ifndef IS_BOOTLOADER_BUILD

View File

@@ -56,6 +56,10 @@ if(NOT BOOTLOADER_BUILD)
set(ESPTOOLPY_ELF2IMAGE_OPTIONS --elf-sha256-offset 0xb0)
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)
# Set ESPFLASHSIZE to 'detect' *after* elf2image options are generated,
# as elf2image can't have 'detect' as an option...