Lines Matching +full:move +full:- +full:to +full:- +full:todo
2 * SPDX-License-Identifier: Apache-2.0
4 * Copyright (c) 2016-2020 Linaro LTD
5 * Copyright (c) 2016-2019 JUUL Labs
6 * Copyright (c) 2019-2023 Arm Limited
7 * Copyright (c) 2024-2025 Nordic Semiconductor ASA
11 * Licensed to the Apache Software Foundation (ASF) under one
15 * to you under the Apache License, Version 2.0 (the
19 * http://www.apache.org/licenses/LICENSE-2.0
21 * Unless required by applicable law or agreed to in writing,
30 * This file provides an interface to the boot loader. Functions defined in
73 /* Used for holding static buffers in multiple functions to work around issues
96 * When running natively on a target, we don't want to allocated huge
98 * we want to run as many threads as there are tests, and it's safer
99 * to just make those variables stack allocated.
145 * Failure to read any headers is a fatal error. in boot_read_image_headers()
178 BOOT_LOG_ERR("Failed to add image data to shared area"); in boot_add_shared_data()
188 BOOT_LOG_ERR("Failed to add data to shared memory area."); in boot_add_shared_data()
204 * Fills rsp to indicate how booting should occur.
207 * @param rsp boot_rsp struct to fill.
218 if (!state->img_mask[BOOT_CURR_IMG(state)]) { in fill_rsp()
229 active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot; in fill_rsp()
234 rsp->br_flash_dev_id = flash_area_get_device_id(BOOT_IMG_AREA(state, active_slot)); in fill_rsp()
235 rsp->br_image_off = boot_img_slot_off(state, active_slot); in fill_rsp()
236 rsp->br_hdr = boot_img_hdr(state, active_slot); in fill_rsp()
251 if (state->img_mask[BOOT_CURR_IMG(state)]) { in close_all_flash_areas()
259 flash_area_close(BOOT_IMG_AREA(state, BOOT_NUM_SLOTS - 1 - slot)); in close_all_flash_areas()
272 * Enable MCUBOOT_VERSION_CMP_USE_BUILD_NUMBER to take the build number into account.
274 * @param ver1 Pointer to the first image version to compare.
275 * @param ver2 Pointer to the second image version to compare.
277 * @retval -1 If ver1 is less than ver2.
285 if (ver1->iv_major > ver2->iv_major) { in boot_version_cmp()
288 if (ver1->iv_major < ver2->iv_major) { in boot_version_cmp()
289 return -1; in boot_version_cmp()
292 if (ver1->iv_minor > ver2->iv_minor) { in boot_version_cmp()
295 if (ver1->iv_minor < ver2->iv_minor) { in boot_version_cmp()
296 return -1; in boot_version_cmp()
299 if (ver1->iv_revision > ver2->iv_revision) { in boot_version_cmp()
302 if (ver1->iv_revision < ver2->iv_revision) { in boot_version_cmp()
303 return -1; in boot_version_cmp()
308 if (ver1->iv_build_num > ver2->iv_build_num) { in boot_version_cmp()
311 if (ver1->iv_build_num < ver2->iv_build_num) { in boot_version_cmp()
312 return -1; in boot_version_cmp()
340 out_sectors = state->scratch.sectors; in boot_initialize_area()
341 out_num_sectors = &state->scratch.num_sectors; in boot_initialize_area()
377 /* We need to differentiate from the primary image issue */ in boot_read_sectors_recovery()
395 * @param dep Image dependency which has to be verified.
410 uint8_t swap_type = state->swap_type[dep->image_id]; in boot_verify_slot_dependency()
414 dep_slot = state->slot_usage[dep->image_id].active_slot; in boot_verify_slot_dependency()
417 dep_version = &state->imgs[dep->image_id][dep_slot].hdr.ih_ver; in boot_verify_slot_dependency()
419 rc = boot_version_cmp(dep_version, &dep->image_min_version); in boot_verify_slot_dependency()
423 * Modify the swap type to decrease the version number of the image in boot_verify_slot_dependency()
461 int rc = -1; in boot_verify_dependencies()
466 if (state->img_mask[BOOT_CURR_IMG(state)]) { in boot_verify_dependencies()
482 /* Cannot upgrade due to non-met dependencies, so disable all in boot_verify_dependencies()
499 * case of MCUBOOT_RAM_LOAD strategy) and its slot is set to unavailable.
508 int rc = -1; in boot_verify_dependencies()
512 if (state->img_mask[BOOT_CURR_IMG(state)]) { in boot_verify_dependencies()
515 active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot; in boot_verify_dependencies()
524 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false; in boot_verify_dependencies()
525 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT; in boot_verify_dependencies()
537 * one after another to see if they are all satisfied.
574 return -1; in boot_verify_slot_dependencies()
623 /* Figure out what size to write update status update as. The size depends in boot_write_sz()
625 * We need to use the bigger of those 2 values. in boot_write_sz()
640 * This information is necessary for calculating the number of bytes to erase
642 * function is used to populate the state.
659 /* We need to differentiate from the primary image issue */ in boot_read_sectors()
679 memset(&bs->enckey, 0xff, BOOT_NUM_SLOTS * BOOT_ENC_KEY_ALIGN_SIZE); in boot_status_reset()
681 memset(&bs->enctlv, 0xff, BOOT_NUM_SLOTS * BOOT_ENC_TLV_ALIGN_SIZE); in boot_status_reset()
685 bs->use_scratch = 0; in boot_status_reset()
686 bs->swap_size = 0; in boot_status_reset()
687 bs->source = 0; in boot_status_reset()
690 bs->op = BOOT_STATUS_OP_SWAP; in boot_status_reset()
692 bs->op = BOOT_STATUS_OP_MOVE; in boot_status_reset()
694 bs->idx = BOOT_STATUS_IDX_0; in boot_status_reset()
695 bs->state = BOOT_STATUS_STATE_0; in boot_status_reset()
696 bs->swap_type = BOOT_SWAP_TYPE_NONE; in boot_status_reset()
704 bs->op == BOOT_STATUS_OP_SWAP && in boot_status_is_reset()
706 bs->op == BOOT_STATUS_OP_MOVE && in boot_status_is_reset()
708 bs->idx == BOOT_STATUS_IDX_0 && in boot_status_is_reset()
709 bs->state == BOOT_STATUS_STATE_0); in boot_status_is_reset()
713 * Writes the supplied boot status to the flash file system. The boot status
714 * contains the current state of an in-progress image copy operation.
716 * @param bs The boot status to write.
733 * first two status writes go to the scratch which will be copied to in boot_write_status()
738 if (bs->use_scratch) { in boot_write_status()
739 /* Write to scratch. */ in boot_write_status()
743 /* Write to the primary slot. */ in boot_write_status()
759 buf[0] = bs->state; in boot_write_status()
883 if (hdr->ih_magic != IMAGE_MAGIC) {
887 if (!boot_u32_safe_add(&size, hdr->ih_img_size, hdr->ih_hdr_size)) {
896 if (!boot_u32_safe_add(&size, size, hdr->ih_protect_tlv_size)) {
910 if ((hdr->ih_flags & IMAGE_F_ENCRYPTED_AES128) &&
911 (hdr->ih_flags & IMAGE_F_ENCRYPTED_AES256))
922 if ((hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA1) &&
923 (hdr->ih_flags & IMAGE_F_COMPRESSED_LZMA2))
960 return -1;
967 if (!boot_data_is_set_to(erased_val, &hdr->ih_magic, sizeof(hdr->ih_magic))) {
968 return -1;
976 * Check if image in slot has been set with specific ROM address to run from
992 active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
996 if (hdr->ih_flags & IMAGE_F_ROM_FIXED && hdr->ih_load_addr != f_off) {
1000 hdr->ih_load_addr);
1041 (hdr->ih_flags & IMAGE_F_NON_BOOTABLE)) {
1057 if (bs->swap_type == BOOT_SWAP_TYPE_REVERT ||
1070 BOOT_LOG_INF("Cleared image %d primary slot trailer due to stuck revert",
1087 /* Check first sector to see if there is a magic header here, if so the update has likely
1088 * been loaded to the wrong sector and cannot be used
1108 &boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver,
1109 &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver);
1136 /* Image is invalid, erase it to prevent further unnecessary
1137 * attempts to validate and boot it.
1150 * located in the primary slot. This is done to avoid users incorrectly
1151 * overwriting an application written to the incorrect slot.
1158 uint32_t reset_addr = secondary_hdr->ih_hdr_size + sizeof(reset_value);
1166 if (reset_value < pri_fa->fa_off || reset_value> (pri_fa->fa_off + pri_fa->fa_size)) {
1172 * indicate that the image was loaded to the wrong slot.
1176 flash_area_erase(fap, 0, fap->fa_size);
1199 * containing the pointer to the image header structure of the
1236 * Determines which swap operation to perform, if any. If it is determined
1241 * @return The type of swap to perform (BOOT_SWAP_TYPE...)
1252 /* Boot loader wants to switch to the secondary slot.
1272 * @param flash_area The flash_area containing the region to erase.
1273 * @param off The offset within the flash area to start the
1275 * @param sz The number of bytes to erase.
1302 * Copies the contents of one flash region to another. You must erase the
1303 * destination region prior to calling this function.
1307 * @param off_src The offset within the source flash area to
1309 * @param off_dst The offset within the destination flash area to
1310 * copy to.
1311 * @param sz The number of bytes to copy.
1349 /* In case of encryption enabled, we may have to do more work than
1374 * only have to copy bytes, no encryption or decryption.
1382 if (sz - bytes_copied > sizeof buf) {
1385 chunk_sz = sz - bytes_copied;
1398 uint32_t abs_off = off - sector_off + bytes_copied;
1402 if (abs_off < hdr->ih_hdr_size) {
1404 if (abs_off + chunk_sz > hdr->ih_hdr_size) {
1407 blk_sz = chunk_sz - (hdr->ih_hdr_size - abs_off);
1408 idx = hdr->ih_hdr_size - abs_off;
1411 blk_sz = 0; /* nothing to decrypt */
1416 blk_off = (abs_off - hdr->ih_hdr_size) & 0xf;
1427 blk_sz = tlv_off - abs_off;
1432 (abs_off + idx) - hdr->ih_hdr_size, blk_sz,
1436 (abs_off + idx) - hdr->ih_hdr_size, blk_sz,
1462 * this struct to determine if it is resuming
1464 * function writes the updated status to this
1500 BOOT_LOG_INF("Image %d upgrade secondary slot -> primary slot", image_index);
1519 size += src_size - size;
1520 size += BOOT_WRITE_SZ(state) - (size % BOOT_WRITE_SZ(state));
1530 sector = boot_img_num_sectors(state, BOOT_PRIMARY_SLOT) - 1;
1535 sector--;
1563 BOOT_LOG_INF("Image %d copying the secondary slot to the primary slot: 0x%zx bytes",
1614 last_sector = boot_img_num_sectors(state, BOOT_SECONDARY_SLOT) - 1;
1626 /* TODO: Perhaps verify the primary slot's signature again? */
1638 * this struct to determine if it is resuming
1640 * function writes the updated status to this
1666 * No swap ever happened, so need to find the largest image which
1667 * will be used to determine the amount of sectors to swap.
1670 if (hdr->ih_magic == IMAGE_MAGIC) {
1692 memset(bs->enckey[0], 0xff, BOOT_ENC_KEY_ALIGN_SIZE);
1697 if (hdr->ih_magic == IMAGE_MAGIC) {
1720 memset(bs->enckey[1], 0xff, BOOT_ENC_KEY_ALIGN_SIZE);
1728 bs->swap_size = copy_size;
1737 rc = boot_read_swap_size(fap, &bs->swap_size);
1740 copy_size = bs->swap_size;
1748 if (bs->enckey[slot][i] != 0xff) {
1818 * swap was finished to avoid a new revert.
1836 * In case of a permanent image swap mcuboot will never attempt to
1875 * `swap-type` trailer field.
1880 BOOT_SWAP_TYPE(state) = bs->swap_type;
1883 * swap was finished to avoid a new revert.
1885 if (bs->swap_type == BOOT_SWAP_TYPE_REVERT ||
1886 bs->swap_type == BOOT_SWAP_TYPE_PERM) {
1893 if (BOOT_IS_UPGRADE(bs->swap_type)) {
1930 * There are two separate scenarios that we have to deal with:
1938 * the fact of a reboot. In a consistent state images must move in the
1943 * REVERT swap types to NONE (these images had been successfully
1949 /* Nothing to do */
1956 /* Nothing to do */
1962 if (state->swap_type[i] == BOOT_SWAP_TYPE_REVERT) {
1963 state->swap_type[i] = BOOT_SWAP_TYPE_NONE;
1970 * Prepare image to be updated if required.
1972 * Prepare image to be updated if required with completing an image swap
1974 * swap operation. In case of any error set the swap type to NONE.
1976 * @param state TODO
1978 * boot status can be written to.
1995 " - too small?", BOOT_MAX_IMG_SECTORS);
1996 /* Unable to determine sector layout, continue with next image
2007 /* Attempt to read an image header from each slot. */
2046 * Must re-read image headers because the boot status might
2051 /* When bootstrapping it's OK to not have image magic in the primary slot */
2075 /* Should never arrive here, overwrite-only mode has
2081 * `swap-type` trailer field.
2086 /* Attempt to read an image header from each slot. Ensure that image headers in slots
2089 * The boot status (last param) is used to figure out in which slot the header of each
2091 * the header of a given image could have already been moved to the other slot. However,
2095 * want here, since the goal is to upgrade the bootloader state to reflect the new state
2103 /* Swap has finished set to NONE */
2107 if (bs->swap_type == BOOT_SWAP_TYPE_NONE) {
2115 BOOT_SWAP_TYPE(state) = bs->swap_type;
2126 * inexpensive. Since overwrite-only copies starting from
2128 * magic, so also run validation on the primary slot to be
2137 rc = (boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_magic == IMAGE_MAGIC) ? 1: 0;
2142 /* Set swap type to REVERT to overwrite the primary
2144 * and to trigger the explicit setting of the
2208 * @return 0 - image can be swapped, -1 downgrade prevention
2232 rc = -1;
2236 rc = boot_version_cmp(&boot_img_hdr(state, BOOT_SECONDARY_SLOT)->ih_ver,
2237 &boot_img_hdr(state, BOOT_PRIMARY_SLOT)->ih_ver);
2241 BOOT_LOG_INF("Image %d in slot 1 erased due to downgrade prevention", BOOT_CURR_IMG(state));
2259 int rc = -1;
2267 /* The array of slot sectors are defined here (as opposed to file scope) so
2268 * that they don't get allocated for non-boot-loader apps. This is
2269 * necessary because the gcc option "-fdata-sections" doesn't seem to have
2286 * to be determined for each image and all aborted swaps have to be
2291 if (state->img_mask[BOOT_CURR_IMG(state)]) {
2296 /* The keys used for encryption may no longer be valid (could belong to
2297 * another images). Therefore, mark them as invalid to force their reload
2311 state->scratch.sectors = sector_buffers.scratch;
2319 state->scratch.sectors = scratch_sectors;
2332 BOOT_LOG_ERR("Failed to open flash area ID %d (image %d slot %d): %d, "
2343 BOOT_LOG_ERR("Failed to open scratch flash area: %d, cannot continue", rc);
2364 * It was impossible to upgrade because the expected dependency version
2385 if (state->img_mask[BOOT_CURR_IMG(state)]) {
2390 /* The keys used for encryption may no longer be valid (could belong to
2391 * another images). Therefore, mark them as invalid to force their reload
2430 * we don't try to boot into it again on the next reboot. Do this by
2431 * pretending we just reverted back to primary slot.
2434 /* image_ok needs to be explicitly set to avoid a new revert. */
2457 * have been re-validated.
2462 /* Hardenned to prevent from skipping check of a given image,
2466 FIH_SET(tmp_img_mask, state->img_mask[BOOT_CURR_IMG(state)]);
2473 /* Attempt to read an image header from each slot. Ensure that image
2476 * uses boot state, the last parm, to figure out in which slot which
2487 * a swap or overwrite. Now the header info that should be used to
2489 * secondary slot, was updated to primary slot.
2496 * is meant to prevent FI attack.
2505 /* Even if we're not re-validating the primary slot, we could be booting
2533 * fih_cnt should be equal to BOOT_IMAGE_NUMBER now.
2547 * them here to avoid the possibility of jumping into an image that could
2599 * bootable or non-bootable image. Just validate that the image check
2612 boot_img_hdr(&boot_data, split_slot)->ih_hdr_size;
2647 if (state->img_mask[BOOT_CURR_IMG(state)]) {
2659 /* Attempt to read an image header from each slot. */
2671 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = true;
2674 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot] = false;
2682 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
2705 if (state->slot_usage[BOOT_CURR_IMG(state)].slot_available[slot]) {
2710 &boot_img_hdr(state, slot)->ih_ver,
2711 &boot_img_hdr(state, candidate_slot)->ih_ver);
2740 if (state->img_mask[BOOT_CURR_IMG(state)]) {
2744 active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
2757 * to run. Erases the image if it was selected but its execution failed,
2773 active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
2779 active_swap_state = &(state->slot_usage[BOOT_CURR_IMG(state)].swap_state);
2785 if (active_swap_state->magic != BOOT_MAGIC_GOOD ||
2786 (active_swap_state->copy_done == BOOT_FLAG_SET &&
2787 active_swap_state->image_ok != BOOT_FLAG_SET)) {
2791 * to prevent it from being selected again on the next reboot.
2799 rc = -1;
2801 if (active_swap_state->copy_done != BOOT_FLAG_SET) {
2802 if (active_swap_state->copy_done == BOOT_FLAG_BAD) {
2808 * selected to boot. It can be set in advance, before even
2814 BOOT_LOG_WRN("Failed to set copy_done flag of the image in "
2828 * Tries to load a slot for all the images with validation.
2841 /* Go over all the images and try to load one */
2847 /* Go over all the slots and try to load one */
2848 active_slot = state->slot_usage[BOOT_CURR_IMG(state)].active_slot;
2850 /* A slot is already active, go to next image. */
2856 BOOT_LOG_INF("No slot to load for image %d",
2862 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = active_slot;
2865 if (state->img_mask[BOOT_CURR_IMG(state)]) {
2874 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
2875 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
2883 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
2884 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
2891 /* Image is first loaded to RAM and authenticated there in order to
2893 * when loading images from external (untrusted) flash to internal
2900 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
2901 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
2912 state->slot_usage[BOOT_CURR_IMG(state)].slot_available[active_slot] = false;
2913 state->slot_usage[BOOT_CURR_IMG(state)].active_slot = NO_ACTIVE_SLOT;
2917 /* Valid image loaded from a slot, go to next image. */
2942 /* When the 'revert' mechanism is enabled in direct-xip mode, the
2947 if (state->slot_usage[BOOT_CURR_IMG(state)].swap_state.image_ok == BOOT_FLAG_SET) {
2950 state->slot_usage[BOOT_CURR_IMG(state)].active_slot,
2951 state->slot_usage[BOOT_CURR_IMG(state)].active_slot);
2992 * SRAM in case of MCUBOOT_RAM_LOAD strategy, and set to
2993 * unavailable. Try to load an image from another slot.
3004 if (state->img_mask[BOOT_CURR_IMG(state)]) {
3014 … rc = boot_add_shared_data(state, (uint8_t)state->slot_usage[BOOT_CURR_IMG(state)].active_slot);
3041 * appropriate, and tells you what address to boot from.
3060 * moves images around in flash as appropriate, and tells you what address to
3065 * @param image_id The image ID to prepare the boot process for.
3106 * Reads image data to find out the maximum application sizes. Only needs to
3113 int rc = -1;
3190 /* Information not available, need to fetch it */
3204 BOOT_SECONDARY_SLOT) == fap->fa_id) {
3205 return state->secondary_offset[BOOT_CURR_IMG(state)];