espressif:esp32: Add multi image support
Changes on configuration and flash area organization for supporting
multi image and implementation for booting on different processors
on esp32
Signed-off-by: Almir Okato <almir.okato@espressif.com>
diff --git a/boot/espressif/main.c b/boot/espressif/main.c
index 083efc5..6fe93a2 100644
--- a/boot/espressif/main.c
+++ b/boot/espressif/main.c
@@ -22,22 +22,75 @@
#ifdef CONFIG_SECURE_FLASH_ENC_ENABLED
#include "esp_flash_encrypt.h"
#endif
+#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
+#include "app_cpu_start.h"
+#endif
#include "esp_loader.h"
#include "os/os_malloc.h"
+#define IMAGE_INDEX_0 0
+#define IMAGE_INDEX_1 1
+
+#define PRIMARY_SLOT 0
+#define SECONDARY_SLOT 1
+
#ifdef CONFIG_SECURE_BOOT
extern esp_err_t check_and_generate_secure_boot_keys(void);
#endif
void do_boot(struct boot_rsp *rsp)
{
+ unsigned int entry_addr;
BOOT_LOG_INF("br_image_off = 0x%x", rsp->br_image_off);
BOOT_LOG_INF("ih_hdr_size = 0x%x", rsp->br_hdr->ih_hdr_size);
- int slot = (rsp->br_image_off == CONFIG_ESP_APPLICATION_PRIMARY_START_ADDRESS) ? 0 : 1;
- esp_app_image_load(slot, rsp->br_hdr->ih_hdr_size);
+ int slot = (rsp->br_image_off == CONFIG_ESP_IMAGE0_PRIMARY_START_ADDRESS) ? PRIMARY_SLOT : SECONDARY_SLOT;
+ esp_app_image_load(IMAGE_INDEX_0, slot, rsp->br_hdr->ih_hdr_size, &entry_addr);
+ ((void (*)(void))entry_addr)(); /* Call to application entry address should not return */
+ FIH_PANIC; /* It should not get here */
}
+#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
+int read_image_header(uint32_t img_index, uint32_t slot, struct image_header *img_header)
+{
+ const struct flash_area *fap;
+ int area_id;
+ int rc = 0;
+
+ area_id = flash_area_id_from_multi_image_slot(img_index, slot);
+ rc = flash_area_open(area_id, &fap);
+ if (rc != 0) {
+ rc = BOOT_EFLASH;
+ goto done;
+ }
+
+ if (flash_area_read(fap, 0, img_header, sizeof(struct image_header))) {
+ rc = BOOT_EFLASH;
+ goto done;
+ }
+
+ BOOT_LOG_INF("Image offset = 0x%x", fap->fa_off);
+ BOOT_LOG_INF("Image header size = 0x%x", img_header->ih_hdr_size);
+
+done:
+ flash_area_close(fap);
+ return rc;
+}
+
+void do_boot_appcpu(uint32_t img_index, uint32_t slot)
+{
+ unsigned int entry_addr;
+ struct image_header img_header;
+
+ if (read_image_header(img_index, slot, &img_header) != 0) {
+ FIH_PANIC;
+ }
+
+ esp_app_image_load(img_index, slot, img_header.ih_hdr_size, &entry_addr);
+ appcpu_start(entry_addr);
+}
+#endif
+
int main()
{
bootloader_init();
@@ -97,8 +150,10 @@
* 2) MCUboot validates the application images and prepares the booting process.
*/
+ /* MCUboot's boot_go validates and checks all images for update and returns
+ * the load information for booting the main image
+ */
FIH_CALL(boot_go, fih_rc, &rsp);
-
if (fih_not_eq(fih_rc, FIH_SUCCESS)) {
BOOT_LOG_ERR("Unable to find bootable image");
#ifdef CONFIG_SECURE_BOOT
@@ -165,6 +220,13 @@
BOOT_LOG_INF("Disabling RNG early entropy source...");
bootloader_random_disable();
+#ifdef CONFIG_ESP_MULTI_PROCESSOR_BOOT
+ /* Multi image independent boot
+ * Boot on the second processor happens before the image0 boot
+ */
+ do_boot_appcpu(IMAGE_INDEX_1, PRIMARY_SLOT);
+#endif
+
do_boot(&rsp);
while(1);