]> granicus.if.org Git - esp-idf/commitdiff
Add chip revision into image header
authorsuda-morris <362953310@qq.com>
Mon, 16 Sep 2019 03:47:23 +0000 (11:47 +0800)
committersuda-morris <362953310@qq.com>
Mon, 16 Sep 2019 10:13:53 +0000 (18:13 +0800)
Check chip id and chip revision before boot app image

Closes https://github.com/espressif/esp-idf/issues/4000

Kconfig
components/app_update/esp_ota_ops.c
components/bootloader_support/include/bootloader_common.h
components/bootloader_support/include/esp_app_format.h
components/bootloader_support/src/bootloader_common.c
components/bootloader_support/src/bootloader_init.c
components/bootloader_support/src/esp_image_format.c
components/esp32/cpu_start.c
components/esptool_py/Makefile.projbuild
components/esptool_py/esptool
components/esptool_py/project_include.cmake

diff --git a/Kconfig b/Kconfig
index ad049f5dbf4f01dde3616f07b056bbcf67682caa..b6351a86c86518afe7fdf99381fc7dd198b4e1a9 100644 (file)
--- a/Kconfig
+++ b/Kconfig
@@ -29,6 +29,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 SDK_TOOLPREFIX
index 7ef5c68c5817322aff397a71a1397fc34a5f878c..51244b3d8773845beeedcc045e93650090ec535b 100644 (file)
@@ -42,7 +42,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;
@@ -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
             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;
             }
 
index 1058b20cc5be5e5392af2b2260318cdf9ec968b0..b3b88b50f00cb16b7a239ce647022028415bbc21 100644 (file)
@@ -15,6 +15,7 @@
 #pragma once
 #include "esp_flash_partitions.h"
 #include "esp_image_format.h"
+#include "esp_app_format.h"
 
 #ifdef __cplusplus
 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.
- * 
+ *
  * Returns a description for the requested app partition.
  * @param[in] partition      App partition description.
  * @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);
 
+/**
+ * @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.
  */
index 4917dd0f7b12011b12638fbd8b195df1c8caaa5b..c7edaebd2dc02006de9be55830235fe7210d4bc8 100644 (file)
 // limitations under the License.
 #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
  */
@@ -63,7 +76,9 @@ typedef struct {
                                 * the IDF bootloader uses software to configure the WP
                                 * 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 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.
                                  * Included in image length. This digest
                                  * is separate to secure boot and only used for detecting corruption.
index acc7644ea3288b252010bb16ba106c792252b317..89ff80cd392c5fa44b49a2527b76225f0a5f564a 100644 (file)
@@ -28,6 +28,7 @@
 #include "esp_image_format.h"
 #include "bootloader_sha.h"
 #include "sys/param.h"
+#include "esp_efuse.h"
 
 #define ESP_PARTITION_HASH_LEN 32 /* SHA-256 digest length */
 
@@ -271,6 +272,25 @@ void bootloader_common_vddsdio_configure(void)
 #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;
+}
 
 #if defined( CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP ) || defined( CONFIG_BOOTLOADER_CUSTOM_RESERVE_RTC )
 
@@ -332,4 +352,4 @@ rtc_retain_mem_t* bootloader_common_get_rtc_retain_mem(void)
 {
     return rtc_retain_mem;
 }
-#endif
\ No newline at end of file
+#endif
index d3196dd85551c910ae56d0c3d526f3391accf5c8..d2823319383e5769813f4e21871176f2bc83e367 100644 (file)
@@ -41,6 +41,7 @@
 #include "soc/spi_periph.h"
 
 #include "sdkconfig.h"
+#include "esp_efuse.h"
 #include "esp_image_format.h"
 #include "esp_secure_boot.h"
 #include "esp_flash_encrypt.h"
@@ -128,6 +129,14 @@ static esp_err_t bootloader_main(void)
         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 = 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);
 #if (CONFIG_ESP32_DEFAULT_CPU_FREQ_MHZ == 240)
     //Check if ESP32 is rated for a CPU frequency of 160MHz only
index b0db9b398426f49bd7125051073eb543a353588c..864cef1f59d0e90d61674b9e4a19b5efd4aba153 100644 (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
@@ -299,6 +300,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);
index c5f252881896380f36632b771b892680e6d75d3e..5e9ad69c34aed6c49602d637b0da4d7b3f5ebae5 100644 (file)
@@ -401,15 +401,6 @@ void start_cpu0_default(void)
     assert(flash_ret == ESP_OK);
 #endif
 
-    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
index 8292c06ecd380ea30d09dd6c63598634c3346a72..a351e8282fdac5fae2061734b9ca67815b566a9b 100644 (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
index 1a7dbf787e7e504acdeaea074d15a5ccaf87e9e8..4f1e825d2d1ee33b896b3977905fb29ac6cc0794 160000 (submodule)
@@ -1 +1 @@
-Subproject commit 1a7dbf787e7e504acdeaea074d15a5ccaf87e9e8
+Subproject commit 4f1e825d2d1ee33b896b3977905fb29ac6cc0794
index 78dc03cbb0ee5ea36a3668095733dae1a4ce7361..af676a626b76dbe15ae2ae3c317aa6ec3125aa9b 100644 (file)
@@ -52,6 +52,10 @@ if(CONFIG_SECURE_BOOT_ENABLED AND
     set(ESPTOOLPY_ELF2IMAGE_OPTIONS ${ESPTOOLPY_ELF2IMAGE_OPTIONS} --secure-pad)
 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...