Просмотр исходного кода

Merge branch 'feature/skip_validate' into 'master'

bootloader: Add config options to skip validation of app for minimum boot time

Closes IDF-2916

See merge request espressif/esp-idf!12659
Angus Gratton 4 лет назад
Родитель
Сommit
c8ec2edc0f

+ 46 - 0
components/bootloader/Kconfig.projbuild

@@ -274,6 +274,10 @@ menu "Bootloader config"
 
     config BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
         bool "Skip image validation when exiting deep sleep"
+        # note: dependencies for this config item are different to other "skip image validation"
+        # options, allowing to turn on "allow insecure options" and have secure boot with
+        # "skip validation when existing deep sleep". Keeping this to avoid a breaking change,
+        # but - as noted in help - it invalidates the integrity of Secure Boot checks
         depends on (SECURE_BOOT && SECURE_BOOT_INSECURE) || !SECURE_BOOT
         default n
         help
@@ -286,6 +290,48 @@ menu "Bootloader config"
             partition as this would skip the validation upon first load of the new
             OTA partition.
 
+            It is possible to enable this option with Secure Boot if "allow insecure
+            options" is enabled, however it's strongly recommended to NOT enable it as
+            it may allow a Secure Boot bypass.
+
+    config BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON
+        bool "Skip image validation from power on reset (READ HELP FIRST)"
+        # only available if both Secure Boot and Check Signature on Boot are disabled
+        depends on !SECURE_SIGNED_ON_BOOT
+        default n
+        help
+            Some applications need to boot very quickly from power on. By default, the entire app binary
+            is read from flash and verified which takes up a significant portion of the boot time.
+
+            Enabling this option will skip validation of the app when the SoC boots from power on.
+            Note that in this case it's not possible for the bootloader to detect if an app image is
+            corrupted in the flash, therefore it's not possible to safely fall back to a different app
+            partition. Flash corruption of this kind is unlikely but can happen if there is a serious
+            firmware bug or physical damage.
+
+            Following other reset types, the bootloader will still validate the app image. This increases
+            the chances that flash corruption resulting in a crash can be detected following soft reset, and
+            the bootloader will fall back to a valid app image. To increase the chances of successfully recovering
+            from a flash corruption event, keep the option BOOTLOADER_WDT_ENABLE enabled and consider also enabling
+            BOOTLOADER_WDT_DISABLE_IN_USER_CODE - then manually disable the RTC Watchdog once the app is running.
+            In addition, enable both the Task and Interrupt watchdog timers with reset options set.
+
+    config BOOTLOADER_SKIP_VALIDATE_ALWAYS
+        bool "Skip image validation always (READ HELP FIRST)"
+        # only available if both Secure Boot and Check Signature on Boot are disabled
+        depends on !SECURE_SIGNED_ON_BOOT
+        default n
+        select BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP
+        select BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON
+        help
+            Selecting this option prevents the bootloader from ever validating the app image before
+            booting it. Any flash corruption of the selected app partition will make the entire SoC
+            unbootable.
+
+            Although flash corruption is a very rare case, it is not recommended to select this option.
+            Consider selecting "Skip image validation from power on reset" instead. However, if boot time
+            is the only important factor then it can be enabled.
+
     config BOOTLOADER_RESERVE_RTC_SIZE
         hex
         default 0x10 if BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP || BOOTLOADER_CUSTOM_RESERVE_RTC

+ 17 - 4
components/bootloader_support/src/esp_image_format.c

@@ -327,11 +327,24 @@ err:
 
 esp_err_t bootloader_load_image(const esp_partition_pos_t *part, esp_image_metadata_t *data)
 {
-#ifdef BOOTLOADER_BUILD
-    return image_load(ESP_IMAGE_LOAD, part, data);
-#else
+#if !defined(BOOTLOADER_BUILD)
     return ESP_FAIL;
-#endif
+#else
+    esp_image_load_mode_t mode = ESP_IMAGE_LOAD;
+
+#if !defined(CONFIG_SECURE_BOOT)
+    /* Skip validation under particular configurations */
+#if CONFIG_BOOTLOADER_SKIP_VALIDATE_ALWAYS
+    mode = ESP_IMAGE_LOAD_NO_VALIDATE;
+#elif CONFIG_BOOTLOADER_SKIP_VALIDATE_ON_POWER_ON
+    if (rtc_get_reset_reason(0) == POWERON_RESET) {
+        mode = ESP_IMAGE_LOAD_NO_VALIDATE;
+    }
+#endif // CONFIG_BOOTLOADER_SKIP_...
+#endif // CONFIG_SECURE_BOOT
+
+ return image_load(mode, part, data);
+#endif // BOOTLOADER_BUILD
 }
 
 esp_err_t bootloader_load_image_no_verify(const esp_partition_pos_t *part, esp_image_metadata_t *data)