mirror of https://github.com/wolfSSL/wolfBoot.git
554 lines
18 KiB
C
554 lines
18 KiB
C
/* update_ram.c
|
|
*
|
|
* Implementation for RAM based updater
|
|
*
|
|
*
|
|
* Copyright (C) 2026 wolfSSL Inc.
|
|
*
|
|
* This file is part of wolfBoot.
|
|
*
|
|
* wolfBoot is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* wolfBoot is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
|
|
*/
|
|
|
|
#include "image.h"
|
|
#include "loader.h"
|
|
#include "hal.h"
|
|
#include "hooks.h"
|
|
#include "spi_flash.h"
|
|
#include "printf.h"
|
|
#include "wolfboot/wolfboot.h"
|
|
#include <string.h>
|
|
|
|
#ifdef WOLFBOOT_UBOOT_LEGACY
|
|
#include "gpt.h" /* gpt_crc32_* helpers (reflected CRC-32, poly 0xEDB88320) */
|
|
#endif
|
|
|
|
#ifdef WOLFBOOT_TPM
|
|
#include "tpm.h"
|
|
#endif
|
|
#ifdef WOLFBOOT_ELF
|
|
#include "elf.h"
|
|
#endif
|
|
|
|
extern void hal_flash_dualbank_swap(void);
|
|
extern int wolfBoot_get_dts_size(void *dts_addr);
|
|
|
|
extern uint32_t kernel_load_addr;
|
|
extern uint32_t dts_load_addr;
|
|
|
|
#if defined(__WOLFBOOT) && defined(WOLFBOOT_LOAD_ADDRESS)
|
|
extern uint8_t _end[]; /* linker symbol: end of wolfBoot BSS */
|
|
#endif
|
|
|
|
#if ((defined(EXT_FLASH) && defined(NO_XIP)) || \
|
|
(defined(EXT_ENCRYPTED) && defined(MMU))) && \
|
|
!defined(WOLFBOOT_NO_RAMBOOT)
|
|
/* Load firmware to RAM on boot (single flash read) */
|
|
#undef WOLFBOOT_USE_RAMBOOT
|
|
#define WOLFBOOT_USE_RAMBOOT
|
|
#endif
|
|
|
|
#ifdef WOLFBOOT_USE_RAMBOOT
|
|
|
|
/* Function to load image from flash to ram */
|
|
int wolfBoot_ramboot(struct wolfBoot_image *img, uint8_t *src, uint8_t *dst)
|
|
{
|
|
int ret;
|
|
uint32_t img_size;
|
|
BENCHMARK_DECLARE();
|
|
|
|
/* read header into RAM */
|
|
wolfBoot_printf("Loading header %d bytes from %p to %p\n",
|
|
IMAGE_HEADER_SIZE, src, dst);
|
|
#if defined(EXT_FLASH) && defined(NO_XIP)
|
|
ret = ext_flash_read((uintptr_t)src, dst, IMAGE_HEADER_SIZE);
|
|
if (ret != IMAGE_HEADER_SIZE){
|
|
wolfBoot_printf("Error reading header at %p\n", src);
|
|
return -1;
|
|
}
|
|
#else
|
|
memcpy(dst, src, IMAGE_HEADER_SIZE);
|
|
#endif
|
|
|
|
/* check for valid header and version */
|
|
ret = wolfBoot_get_blob_version((uint8_t*)dst);
|
|
if (ret <= 0) {
|
|
wolfBoot_printf("No valid image found at %p\n", src);
|
|
return -1;
|
|
}
|
|
|
|
/* determine size of partition */
|
|
img_size = wolfBoot_image_size((uint8_t*)dst);
|
|
#if defined(WOLFBOOT_NO_PARTITIONS)
|
|
# ifndef WOLFBOOT_RAMBOOT_MAX_SIZE
|
|
# error "WOLFBOOT_RAMBOOT_MAX_SIZE required when WOLFBOOT_NO_PARTITIONS=1"
|
|
# endif
|
|
if (img_size > WOLFBOOT_RAMBOOT_MAX_SIZE) {
|
|
wolfBoot_printf("Invalid image size %u at %p\n", img_size, src);
|
|
return -1;
|
|
}
|
|
#elif defined(WOLFBOOT_PARTITION_SIZE)
|
|
if (img_size > (WOLFBOOT_PARTITION_SIZE - IMAGE_HEADER_SIZE)) {
|
|
wolfBoot_printf("Invalid image size %u at %p\n", img_size, src);
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
#if defined(__WOLFBOOT) && defined(WOLFBOOT_LOAD_ADDRESS)
|
|
/* Runtime overlap check: ensure image destination does not overwrite
|
|
* wolfBoot's own code/data/bss in RAM. */
|
|
if ((uintptr_t)dst < (uintptr_t)_end) {
|
|
wolfBoot_printf("Error: image dest %p overlaps wolfBoot end %p\n",
|
|
dst, _end);
|
|
return -1;
|
|
}
|
|
#endif
|
|
|
|
/* Read the entire image into RAM */
|
|
wolfBoot_printf("Loading image %d bytes from %p to %p...",
|
|
img_size, src + IMAGE_HEADER_SIZE, dst + IMAGE_HEADER_SIZE);
|
|
BENCHMARK_START();
|
|
#if defined(EXT_FLASH) && defined(NO_XIP)
|
|
ret = ext_flash_read((uintptr_t)src + IMAGE_HEADER_SIZE,
|
|
dst + IMAGE_HEADER_SIZE, img_size);
|
|
if (ret < 0) {
|
|
wolfBoot_printf("Error reading image at %p\n", src);
|
|
return -1;
|
|
}
|
|
#else
|
|
memcpy(dst + IMAGE_HEADER_SIZE, src + IMAGE_HEADER_SIZE, img_size);
|
|
#endif
|
|
BENCHMARK_END("done");
|
|
|
|
/* mark image as no longer external */
|
|
img->not_ext = 1;
|
|
|
|
return 0; /* success */
|
|
}
|
|
#endif /* WOLFBOOT_USE_RAMBOOT */
|
|
|
|
#ifdef WOLFBOOT_UBOOT_LEGACY
|
|
/* Validate a 64-byte U-Boot legacy image header (image_header_t).
|
|
*
|
|
* Layout (all multi-byte fields stored big-endian on flash):
|
|
* 0x00 4 ih_magic 0x27051956
|
|
* 0x04 4 ih_hcrc CRC32 of header with hcrc treated as 0
|
|
* 0x08 4 ih_time timestamp
|
|
* 0x0C 4 ih_size payload size (excl. header)
|
|
* 0x10 4 ih_load load address
|
|
* 0x14 4 ih_ep entry point
|
|
* 0x18 4 ih_dcrc data CRC32 (validated by wolfBoot signature)
|
|
* 0x1C 1 ih_os
|
|
* 0x1D 1 ih_arch
|
|
* 0x1E 1 ih_type
|
|
* 0x1F 1 ih_comp
|
|
* 0x20 32 ih_name
|
|
*
|
|
* Magic alone is a ~1-in-2^32 collision for random data, so we also
|
|
* validate the header CRC32 (~2^-32) and the payload size, dropping the
|
|
* joint false-positive probability to roughly 2^-64. This matches
|
|
* U-Boot's own mkimage/bootm validation. */
|
|
static int uboot_legacy_header_valid(const uint8_t *hdr, uint32_t total)
|
|
{
|
|
struct gpt_crc32_ctx ctx;
|
|
uint8_t scratch[UBOOT_IMG_HDR_SZ];
|
|
uint32_t magic;
|
|
uint32_t hcrc;
|
|
uint32_t size;
|
|
uint32_t crc;
|
|
|
|
if (hdr == NULL)
|
|
return 0;
|
|
if (total < UBOOT_IMG_HDR_SZ)
|
|
return 0;
|
|
|
|
/* ih_magic is stored big-endian on flash; UBOOT_IMG_HDR_MAGIC is the
|
|
* host-order word that compares equal to that BE encoding on a
|
|
* little-endian host (which is the only ARM/x86 host wolfBoot
|
|
* supports for the targets enabling WOLFBOOT_UBOOT_LEGACY). */
|
|
memcpy(&magic, hdr + 0x00, sizeof(magic));
|
|
if (magic != UBOOT_IMG_HDR_MAGIC)
|
|
return 0;
|
|
|
|
/* ih_size: big-endian payload length. Reject zero and anything that
|
|
* would overrun the signed image. */
|
|
memcpy(&size, hdr + 0x0C, sizeof(size));
|
|
size = ((size & 0xFF000000U) >> 24) |
|
|
((size & 0x00FF0000U) >> 8) |
|
|
((size & 0x0000FF00U) << 8) |
|
|
((size & 0x000000FFU) << 24);
|
|
if (size == 0)
|
|
return 0;
|
|
if (size > (total - UBOOT_IMG_HDR_SZ))
|
|
return 0;
|
|
|
|
/* ih_hcrc: CRC32 of the header with the hcrc field treated as zero. */
|
|
memcpy(scratch, hdr, UBOOT_IMG_HDR_SZ);
|
|
memcpy(&hcrc, scratch + 0x04, sizeof(hcrc));
|
|
memset(scratch + 0x04, 0, sizeof(hcrc));
|
|
gpt_crc32_init(&ctx);
|
|
gpt_crc32_update(&ctx, scratch, UBOOT_IMG_HDR_SZ);
|
|
crc = gpt_crc32_final(&ctx);
|
|
/* hcrc is stored big-endian; byte-swap for comparison against the
|
|
* host-order CRC32 returned by gpt_crc32_final. */
|
|
hcrc = ((hcrc & 0xFF000000U) >> 24) |
|
|
((hcrc & 0x00FF0000U) >> 8) |
|
|
((hcrc & 0x0000FF00U) << 8) |
|
|
((hcrc & 0x000000FFU) << 24);
|
|
if (hcrc != crc)
|
|
return 0;
|
|
|
|
return 1;
|
|
}
|
|
#endif /* WOLFBOOT_UBOOT_LEGACY */
|
|
|
|
void RAMFUNCTION wolfBoot_start(void)
|
|
{
|
|
int active = -1, ret = 0;
|
|
struct wolfBoot_image os_image;
|
|
BENCHMARK_DECLARE();
|
|
#ifdef WOLFBOOT_UBOOT_LEGACY
|
|
uint8_t *image_ptr;
|
|
#endif
|
|
uint32_t *load_address = NULL;
|
|
uint32_t *source_address = NULL;
|
|
#ifdef WOLFBOOT_FIXED_PARTITIONS
|
|
uint8_t p_state;
|
|
#endif
|
|
#ifdef MMU
|
|
uint8_t *dts_addr = NULL;
|
|
uint32_t dts_size = 0;
|
|
#endif
|
|
#if !defined(ALLOW_DOWNGRADE) && defined(WOLFBOOT_FIXED_PARTITIONS)
|
|
int boot_v_raw = (int)wolfBoot_current_firmware_version();
|
|
int update_v_raw = (int)wolfBoot_update_firmware_version();
|
|
uint32_t boot_v = 0U;
|
|
uint32_t update_v = 0U;
|
|
uint32_t max_v = 0U;
|
|
|
|
if (boot_v_raw >= 0)
|
|
boot_v = (uint32_t)boot_v_raw;
|
|
if (update_v_raw >= 0)
|
|
update_v = (uint32_t)update_v_raw;
|
|
max_v = (boot_v > update_v) ? boot_v : update_v;
|
|
#endif /* !ALLOW_DOWNGRADE && WOLFBOOT_FIXED_PARTITIONS */
|
|
|
|
memset(&os_image, 0, sizeof(struct wolfBoot_image));
|
|
|
|
for (;;) {
|
|
#if defined(WOLFBOOT_DUALBOOT) && defined(WOLFBOOT_FIXED_PARTITIONS)
|
|
if (active < 0)
|
|
active = wolfBoot_dualboot_candidate();
|
|
if (active == PART_BOOT)
|
|
source_address = (uint32_t*)WOLFBOOT_PARTITION_BOOT_ADDRESS;
|
|
else
|
|
source_address = (uint32_t*)WOLFBOOT_PARTITION_UPDATE_ADDRESS;
|
|
#else
|
|
if (active < 0)
|
|
active = wolfBoot_dualboot_candidate_addr((void**)&source_address);
|
|
else if (active == PART_BOOT)
|
|
source_address = (uint32_t*)hal_get_primary_address();
|
|
else
|
|
source_address = (uint32_t*)hal_get_update_address();
|
|
#endif
|
|
if (active < 0) { /* panic if no images available */
|
|
wolfBoot_printf("No valid image found!\n");
|
|
wolfBoot_panic();
|
|
break;
|
|
}
|
|
#if !defined(ALLOW_DOWNGRADE) && defined(WOLFBOOT_FIXED_PARTITIONS)
|
|
{
|
|
uint32_t active_v = (active == PART_UPDATE) ? update_v : boot_v;
|
|
if ((max_v > 0U) && (active_v < max_v)) {
|
|
wolfBoot_printf("Rollback to lower version not allowed\n");
|
|
wolfBoot_panic();
|
|
break;
|
|
}
|
|
}
|
|
#endif /* !ALLOW_DOWNGRADE && WOLFBOOT_FIXED_PARTITIONS */
|
|
|
|
#if defined(WOLFBOOT_DUALBOOT) && defined(WOLFBOOT_FIXED_PARTITIONS)
|
|
wolfBoot_printf("Trying %s partition at %p\n",
|
|
active == PART_BOOT ? "Boot" : "Update", source_address);
|
|
#else
|
|
wolfBoot_printf("Trying partition %d at %p\n",
|
|
active, source_address);
|
|
#endif
|
|
|
|
#ifdef WOLFBOOT_USE_RAMBOOT
|
|
load_address = (uint32_t *)(uintptr_t)(WOLFBOOT_LOAD_ADDRESS -
|
|
IMAGE_HEADER_SIZE);
|
|
#if defined(EXT_ENCRYPTED) && defined(MMU)
|
|
ret = wolfBoot_ram_decrypt((uint8_t*)source_address,
|
|
(uint8_t*)load_address);
|
|
#else
|
|
ret = wolfBoot_ramboot(&os_image, (uint8_t*)source_address,
|
|
(uint8_t*)load_address);
|
|
#endif
|
|
if (ret != 0) {
|
|
goto backup_on_failure;
|
|
}
|
|
#else
|
|
load_address = source_address;
|
|
#endif
|
|
#if !defined(WOLFBOOT_FIXED_PARTITIONS) || \
|
|
defined(WOLFBOOT_USE_RAMBOOT)
|
|
ret = wolfBoot_open_image_address(&os_image, (uint8_t*)load_address);
|
|
#else
|
|
ret = wolfBoot_open_image(&os_image, active);
|
|
#endif
|
|
if (ret < 0) {
|
|
goto backup_on_failure;
|
|
}
|
|
|
|
#ifndef WOLFBOOT_SKIP_BOOT_VERIFY
|
|
/* Verify image integrity (hash check) */
|
|
wolfBoot_printf("Checking integrity...");
|
|
BENCHMARK_START();
|
|
ret = wolfBoot_verify_integrity(&os_image);
|
|
if (ret < 0) {
|
|
wolfBoot_printf("FAILED\n");
|
|
goto backup_on_failure;
|
|
}
|
|
BENCHMARK_END("done");
|
|
|
|
/* Verify image authenticity (signature check) */
|
|
wolfBoot_printf("Verifying signature...");
|
|
BENCHMARK_START();
|
|
ret = wolfBoot_verify_authenticity(&os_image);
|
|
if (ret < 0) {
|
|
wolfBoot_printf("FAILED\n");
|
|
goto backup_on_failure;
|
|
}
|
|
BENCHMARK_END("done");
|
|
|
|
#endif
|
|
|
|
{
|
|
/* Success - integrity and signature valid */
|
|
#if !defined(WOLFBOOT_NO_LOAD_ADDRESS) && defined(WOLFBOOT_LOAD_ADDRESS)
|
|
load_address = (uint32_t*)WOLFBOOT_LOAD_ADDRESS;
|
|
#elif !defined(NO_XIP)
|
|
load_address = (uint32_t*)os_image.fw_base;
|
|
#else
|
|
#error missing WOLFBOOT_LOAD_ADDRESS or XIP
|
|
#endif
|
|
wolfBoot_printf("Successfully selected image in part: %d\n", active);
|
|
break;
|
|
}
|
|
|
|
backup_on_failure:
|
|
wolfBoot_printf("Failure %d: Part %d, Hdr %d, Hash %d, Sig %d\n", ret,
|
|
active, os_image.hdr_ok, os_image.sha_ok, os_image.signature_ok);
|
|
/* panic if authentication fails and no backup */
|
|
if (!wolfBoot_fallback_is_possible()) {
|
|
wolfBoot_printf("Impossible recovery with fallback.\n");
|
|
wolfBoot_panic();
|
|
break;
|
|
} else {
|
|
/* Invalidate failing image and switch to the other partition */
|
|
active ^= 1;
|
|
wolfBoot_printf("Active is now: %d\n", active);
|
|
continue;
|
|
}
|
|
}
|
|
#ifdef UNIT_TEST
|
|
if (wolfBoot_panicked != 0) {
|
|
wolfBoot_printf("panic!\n");
|
|
return;
|
|
}
|
|
#endif
|
|
|
|
wolfBoot_printf("Firmware Valid\n");
|
|
|
|
/* First time we boot this update, set to TESTING to await
|
|
* confirmation from the system
|
|
*/
|
|
#ifdef WOLFBOOT_FIXED_PARTITIONS
|
|
if ((wolfBoot_get_partition_state(active, &p_state) == 0) &&
|
|
(p_state == IMG_STATE_UPDATING))
|
|
{
|
|
#ifdef EXT_FLASH
|
|
ext_flash_unlock();
|
|
#else
|
|
hal_flash_unlock();
|
|
#endif
|
|
wolfBoot_set_partition_state(active, IMG_STATE_TESTING);
|
|
#ifdef EXT_FLASH
|
|
ext_flash_lock();
|
|
#else
|
|
hal_flash_lock();
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
#ifdef WOLFBOOT_UBOOT_LEGACY
|
|
/* Check for U-Boot legacy format image header. Validate magic +
|
|
* header CRC32 + payload size before stripping the 64-byte header,
|
|
* so a non-uImage payload whose first 4 bytes happen to collide
|
|
* with UBOOT_IMG_HDR_MAGIC (~1 in 2^32) cannot be misinterpreted. */
|
|
image_ptr = wolfBoot_peek_image(&os_image, 0, NULL);
|
|
if (image_ptr != NULL &&
|
|
uboot_legacy_header_valid(image_ptr, os_image.fw_size)) {
|
|
/* Skip 64 bytes (size of legacy format image header). */
|
|
load_address += UBOOT_IMG_HDR_SZ;
|
|
os_image.fw_base += UBOOT_IMG_HDR_SZ;
|
|
os_image.fw_size -= UBOOT_IMG_HDR_SZ;
|
|
}
|
|
#endif
|
|
|
|
#ifdef __GNUC__
|
|
/* WOLFBOOT_LOAD_ADDRESS can be 0 address.
|
|
* Do not warn on use of NULL for memcpy */
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Wnonnull"
|
|
#endif
|
|
|
|
#ifndef WOLFBOOT_USE_RAMBOOT
|
|
/* copy image to RAM */
|
|
#if defined(EXT_FLASH) && defined(NO_XIP)
|
|
wolfBoot_printf("Loading flash image from %p to RAM at %p (%d bytes)\n",
|
|
os_image.fw_base, load_address, os_image.fw_size);
|
|
ret = ext_flash_read((uintptr_t)os_image.fw_base, (uint8_t*)load_address,
|
|
os_image.fw_size);
|
|
if (ret < 0){
|
|
wolfBoot_printf("Error loading image at %p (ret %d)\n",
|
|
os_image.fw_base, ret);
|
|
return;
|
|
}
|
|
#else
|
|
wolfBoot_printf("Copying image from %p to RAM at %p (%d bytes)\n",
|
|
os_image.fw_base, load_address, os_image.fw_size);
|
|
memcpy((void*)load_address, os_image.fw_base, os_image.fw_size);
|
|
#endif
|
|
#endif /* !WOLFBOOT_USE_RAMBOOT */
|
|
|
|
#ifdef WOLFBOOT_ELF
|
|
/* Load elf */
|
|
if (elf_load_image_mmu((uint8_t*)load_address, os_image.fw_size,
|
|
(uintptr_t*)&load_address, NULL) != 0){
|
|
wolfBoot_printf("Invalid elf, falling back to raw binary\n");
|
|
}
|
|
#endif
|
|
|
|
#ifdef MMU
|
|
/* Is this a Flattened uImage Tree (FIT) image (FDT format) */
|
|
if (wolfBoot_get_dts_size(load_address) > 0) {
|
|
void* fit = (void*)load_address;
|
|
const char *kernel = NULL, *flat_dt = NULL, *ramdisk = NULL;
|
|
|
|
wolfBoot_printf("Flattened uImage Tree: Version %d, Size %d\n",
|
|
fdt_version(fit), fdt_totalsize(fit));
|
|
|
|
(void)fit_find_images(fit, &kernel, &flat_dt, &ramdisk);
|
|
if (kernel != NULL) {
|
|
void *new_load = fit_load_image(fit, kernel, NULL);
|
|
if (new_load == NULL) {
|
|
wolfBoot_printf("FIT: failed to load kernel '%s'\n", kernel);
|
|
wolfBoot_panic();
|
|
}
|
|
load_address = new_load;
|
|
}
|
|
if (flat_dt != NULL) {
|
|
uint8_t *dts_ptr = fit_load_image(fit, flat_dt, (int*)&dts_size);
|
|
if (dts_ptr != NULL && wolfBoot_get_dts_size(dts_ptr) >= 0) {
|
|
/* relocate to load DTS address */
|
|
dts_addr = (uint8_t*)WOLFBOOT_LOAD_DTS_ADDRESS;
|
|
wolfBoot_printf("Loading DTS: %p -> %p (%d bytes)\n",
|
|
dts_ptr, dts_addr, dts_size);
|
|
memcpy(dts_addr, dts_ptr, dts_size);
|
|
}
|
|
}
|
|
#ifdef WOLFBOOT_FIT_RAMDISK
|
|
if (ramdisk != NULL) {
|
|
(void)fit_load_ramdisk(fit, ramdisk, (void*)dts_addr);
|
|
}
|
|
#else
|
|
(void)ramdisk;
|
|
#endif
|
|
}
|
|
else {
|
|
/* Load DTS to RAM */
|
|
#ifdef EXT_FLASH
|
|
if (PART_IS_EXT(&os_image) &&
|
|
wolfBoot_open_image(&os_image, PART_DTS_BOOT) >= 0) {
|
|
dts_addr = (uint8_t*)WOLFBOOT_LOAD_DTS_ADDRESS;
|
|
dts_size = (uint32_t)os_image.fw_size;
|
|
|
|
wolfBoot_printf("Loading DTS (size %lu) to RAM at %08lx\n",
|
|
(long unsigned int)dts_size, (long unsigned int)dts_addr);
|
|
ext_flash_check_read((uintptr_t)os_image.fw_base,
|
|
(uint8_t*)dts_addr, dts_size);
|
|
}
|
|
else
|
|
#endif /* EXT_FLASH */
|
|
{
|
|
dts_addr = hal_get_dts_address();
|
|
if (dts_addr) {
|
|
ret = wolfBoot_get_dts_size(dts_addr);
|
|
if (ret < 0) {
|
|
wolfBoot_printf("Failed parsing DTB to load\n");
|
|
/* Allow failure, continue booting */
|
|
}
|
|
else {
|
|
/* relocate DTS to RAM */
|
|
uint8_t* dts_dst = (uint8_t*)WOLFBOOT_LOAD_DTS_ADDRESS;
|
|
dts_size = (uint32_t)ret;
|
|
wolfBoot_printf("Loading DTB (size %d) from %p to RAM at %p\n",
|
|
dts_size, dts_addr, (void*)WOLFBOOT_LOAD_DTS_ADDRESS);
|
|
memcpy(dts_dst, dts_addr, dts_size);
|
|
dts_addr = dts_dst;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif /* MMU */
|
|
|
|
wolfBoot_printf("Booting at %p\n", load_address);
|
|
|
|
#ifdef WOLFBOOT_ENABLE_WOLFHSM_CLIENT
|
|
(void)hal_hsm_disconnect();
|
|
#elif defined(WOLFBOOT_ENABLE_WOLFHSM_SERVER)
|
|
(void)hal_hsm_server_cleanup();
|
|
#endif
|
|
|
|
#ifndef TZEN
|
|
if (hal_flash_protect(WOLFBOOT_ORIGIN, BOOTLOADER_PARTITION_SIZE) < 0) {
|
|
wolfBoot_printf("Error protecting bootloader flash region\n");
|
|
wolfBoot_panic();
|
|
}
|
|
#endif
|
|
hal_prepare_boot();
|
|
|
|
#ifdef WOLFBOOT_HOOK_BOOT
|
|
wolfBoot_hook_boot(&os_image);
|
|
#endif
|
|
#ifndef WOLFBOOT_SKIP_BOOT_VERIFY
|
|
PART_SANITY_CHECK(&os_image);
|
|
#endif
|
|
#ifdef MMU
|
|
do_boot((uint32_t*)load_address,
|
|
(uint32_t*)dts_addr);
|
|
#else
|
|
/* Use load_address instead of os_image.fw_base, which may have
|
|
* wrong base address */
|
|
do_boot((uint32_t*)load_address);
|
|
#endif
|
|
|
|
#ifdef __GNUC__
|
|
#pragma GCC diagnostic pop
|
|
#endif
|
|
}
|