mirror of
https://github.com/espressif/esp-idf.git
synced 2024-10-05 20:47:46 -04:00
Merge branch 'feature/bootloader_skip_validate_in_deep_sleep_for_c2' into 'master'
feat(bootloader): BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP for C2 (without RTC_MEM) Closes IDF-9129 See merge request espressif/esp-idf!31241
This commit is contained in:
commit
e7070e777a
@ -360,9 +360,9 @@ menu "Bootloader config"
|
||||
# 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 SOC_RTC_FAST_MEM_SUPPORTED && ((SECURE_BOOT && SECURE_BOOT_INSECURE) || !SECURE_BOOT)
|
||||
depends on ((SECURE_BOOT && SECURE_BOOT_INSECURE) || !SECURE_BOOT)
|
||||
default n
|
||||
select BOOTLOADER_RESERVE_RTC_MEM
|
||||
select BOOTLOADER_RESERVE_RTC_MEM if SOC_RTC_FAST_MEM_SUPPORTED
|
||||
help
|
||||
This option disables the normal validation of an image coming out of
|
||||
deep sleep (checksums, SHA256, and signature). This is a trade-off
|
||||
|
@ -56,9 +56,14 @@ __attribute__((__noreturn__)) void bootloader_utility_load_boot_image(const boot
|
||||
/**
|
||||
* @brief Load that application which was worked before we go to the deep sleep.
|
||||
*
|
||||
* If chip supports the RTC memory:
|
||||
* Checks the reboot reason if it is the deep sleep and has a valid partition in the RTC memory
|
||||
* then try to load the application which was worked before we go to the deep sleep.
|
||||
*
|
||||
* If chip does not support the RTC memory:
|
||||
* Checks the reboot reason if it is the deep sleep then the partition table is read
|
||||
* to select and load an application which was worked before we go to the deep sleep.
|
||||
*
|
||||
*/
|
||||
void bootloader_utility_load_boot_image_from_deep_sleep(void);
|
||||
#endif
|
||||
|
@ -461,15 +461,33 @@ static void set_actual_ota_seq(const bootloader_state_t *bs, int index)
|
||||
void bootloader_utility_load_boot_image_from_deep_sleep(void)
|
||||
{
|
||||
if (esp_rom_get_reset_reason(0) == RESET_REASON_CORE_DEEP_SLEEP) {
|
||||
#if SOC_RTC_FAST_MEM_SUPPORTED
|
||||
esp_partition_pos_t *partition = bootloader_common_get_rtc_retain_mem_partition();
|
||||
if (partition != NULL) {
|
||||
esp_image_metadata_t image_data;
|
||||
if (partition != NULL && bootloader_load_image_no_verify(partition, &image_data) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Fast booting app from partition at offset 0x%"PRIx32, partition->offset);
|
||||
bootloader_common_update_rtc_retain_mem(NULL, true);
|
||||
load_image(&image_data);
|
||||
}
|
||||
#else // !SOC_RTC_FAST_MEM_SUPPORTED
|
||||
bootloader_state_t bs = {0};
|
||||
if (bootloader_utility_load_partition_table(&bs)) {
|
||||
int index_of_last_loaded_app = FACTORY_INDEX;
|
||||
esp_ota_select_entry_t otadata[2];
|
||||
if (bs.ota_info.size && bootloader_common_read_otadata(&bs.ota_info, otadata) == ESP_OK) {
|
||||
int active_otadata = bootloader_common_get_active_otadata(otadata);
|
||||
if (active_otadata != -1) {
|
||||
index_of_last_loaded_app = (otadata[active_otadata].ota_seq - 1) % bs.app_count;
|
||||
}
|
||||
}
|
||||
esp_partition_pos_t partition = index_to_partition(&bs, index_of_last_loaded_app);
|
||||
esp_image_metadata_t image_data;
|
||||
if (bootloader_load_image_no_verify(partition, &image_data) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Fast booting app from partition at offset 0x%"PRIx32, partition->offset);
|
||||
bootloader_common_update_rtc_retain_mem(NULL, true);
|
||||
if (partition.size && bootloader_load_image_no_verify(&partition, &image_data) == ESP_OK) {
|
||||
ESP_LOGI(TAG, "Fast booting app from partition at offset 0x%"PRIx32, partition.offset);
|
||||
load_image(&image_data);
|
||||
}
|
||||
}
|
||||
#endif // !SOC_RTC_FAST_MEM_SUPPORTED
|
||||
ESP_LOGE(TAG, "Fast booting is not successful");
|
||||
ESP_LOGI(TAG, "Try to load an app as usual with all validations");
|
||||
}
|
||||
|
@ -163,12 +163,18 @@ Options to work around this are:
|
||||
|
||||
When Secure Boot V2 is enabled, there is also an absolute binary size limit of {IDF_TARGET_MAX_BOOTLOADER_SIZE} (excluding the 4 KB signature), because the bootloader is first loaded into a fixed size buffer for verification.
|
||||
|
||||
Fast Boot from Deep-Sleep
|
||||
-------------------------
|
||||
|
||||
The bootloader has the :ref:`CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` option which allows the wake-up time from Deep-sleep to be reduced (useful for reducing power consumption). This option is available when the :ref:`CONFIG_SECURE_BOOT` option is disabled or :ref:`CONFIG_SECURE_BOOT_INSECURE` is enabled along with Secure Boot. The reduction in time is achieved by ignoring image verification.
|
||||
|
||||
.. only:: SOC_RTC_FAST_MEM_SUPPORTED
|
||||
|
||||
Fast Boot from Deep-Sleep
|
||||
-------------------------
|
||||
During the first boot, the bootloader stores the address of the application being launched in the RTC FAST memory. After waking up from deep sleep, this address is used to boot the application again without any checks, resulting in a significantly faster load.
|
||||
|
||||
The bootloader has the :ref:`CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` option which allows the wake-up time from Deep-sleep to be reduced (useful for reducing power consumption). This option is available when :ref:`CONFIG_SECURE_BOOT` option is disabled. Reduction of time is achieved due to the lack of image verification. During the first boot, the bootloader stores the address of the application being launched in the RTC FAST memory. And during the awakening, this address is used for booting without any checks, thus fast loading is achieved.
|
||||
.. only:: not SOC_RTC_FAST_MEM_SUPPORTED
|
||||
|
||||
The {IDF_TARGET_NAME} does not have RTC memory, so a running partition cannot be saved there; instead, the entire partition table is read to select the correct application. During wake-up, the selected application is loaded without any checks, resulting in a significantly faster load.
|
||||
|
||||
Custom Bootloader
|
||||
-----------------
|
||||
|
@ -19,7 +19,7 @@ Note: Some wake up sources can be disabled via configuration (see section on [pr
|
||||
|
||||
Warning: On ESP32, touch wake up source cannot be used together with EXT0 wake up source. If they co-exist, IDF will give a runtime error and the program will crash. By default in this example, touch wake up is enabled, and the other two are disabled. You can switch to enable the other wake up sources via menuconfig.
|
||||
|
||||
In this example, the `CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` Kconfig option is used, which allows you to reduce the boot time of the bootloader during waking up from deep sleep. The bootloader stores in rtc memory the address of a running partition and uses it when it wakes up. This example allows you to skip all image checks and speed up the boot.
|
||||
In this example, the `CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP` Kconfig option is used, which allows you to reduce the boot time of the bootloader during waking up from deep sleep. The bootloader stores in RTC memory the address of a running partition and uses it when it wakes up (ESP32-C2 does not have RTC memory, so a running partition cannot be saved there, instead the partition table is read to select an application). This example allows you to skip all image checks and speed up the boot.
|
||||
|
||||
## How to use example
|
||||
|
||||
|
7
examples/system/deep_sleep/partitions.csv
Normal file
7
examples/system/deep_sleep/partitions.csv
Normal file
@ -0,0 +1,7 @@
|
||||
# Name, Type, SubType, Offset, Size, Flags
|
||||
# Note: if you have increased the bootloader size, make sure to update the offsets to avoid overlap
|
||||
nvs, data, nvs, , 0x4000,
|
||||
otadata, data, ota, , 0x2000,
|
||||
factory, app, factory, , 600K,
|
||||
ota_0, app, ota_0, , 600K,
|
||||
ota_1, app, ota_1, , 600K,
|
|
@ -1,4 +1,4 @@
|
||||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-FileCopyrightText: 2022-2024 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import logging
|
||||
import time
|
||||
@ -67,11 +67,7 @@ def test_deep_sleep(dut: Dut) -> None:
|
||||
logging.info('Host measured sleep time at {:.2f}s'.format(sleep_time))
|
||||
assert 18 < sleep_time < 22 # note: high tolerance as measuring time on the host may have some timing skew
|
||||
|
||||
# This line indicates that the CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP option set in sdkconfig.defaults
|
||||
# has correctly allowed skipping verification on wakeup
|
||||
# Note: this feature depends on rtc mem
|
||||
if dut.app.sdkconfig.get('SOC_RTC_MEM_SUPPORTED') is True:
|
||||
dut.expect_exact('boot: Fast booting app from partition', timeout=2)
|
||||
dut.expect_exact('boot: Fast booting app from partition', timeout=2)
|
||||
|
||||
# Check that it measured 2xxxxms in deep sleep, i.e at least 20 seconds:
|
||||
expect_enable_deep_sleep()
|
||||
|
@ -8,3 +8,4 @@ CONFIG_ULP_COPROC_ENABLED=y
|
||||
CONFIG_ULP_COPROC_RESERVE_MEM=512
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y
|
||||
CONFIG_RTC_CLK_SRC_INT_RC=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
|
@ -13,3 +13,4 @@ CONFIG_ULP_COPROC_ENABLED=y
|
||||
CONFIG_ULP_COPROC_RESERVE_MEM=512
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y
|
||||
CONFIG_RTC_CLK_SRC_INT_RC=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
|
@ -5,3 +5,4 @@ CONFIG_ULP_COPROC_RESERVE_MEM=512
|
||||
CONFIG_NEWLIB_TIME_SYSCALL_USE_RTC_HRT=y
|
||||
CONFIG_RTC_CLK_SRC_INT_RC=y
|
||||
CONFIG_BOOTLOADER_SKIP_VALIDATE_IN_DEEP_SLEEP=y
|
||||
CONFIG_PARTITION_TABLE_CUSTOM=y
|
||||
|
Loading…
Reference in New Issue
Block a user