Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bring back improvements for devices without erase #2216

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions boot/boot_serial/src/boot_serial.c
Original file line number Diff line number Diff line change
Expand Up @@ -856,7 +856,7 @@ static off_t erase_range(const struct flash_area *fap, off_t start, off_t end)
BOOT_LOG_DBG("Erasing range 0x%jx:0x%jx", (intmax_t)start,
(intmax_t)(start + size - 1));

rc = flash_area_erase(fap, start, size);
rc = boot_erase_region(fap, start, size);
if (rc != 0) {
BOOT_LOG_ERR("Error %d while erasing range", rc);
return -EINVAL;
Expand Down Expand Up @@ -1000,7 +1000,7 @@ bs_upload(char *buf, int len)
/* Non-progressive erase erases entire image slot when first chunk of
* an image is received.
*/
rc = flash_area_erase(fap, 0, area_size);
rc = boot_erase_region(fap, 0, area_size);
if (rc) {
goto out_invalid_data;
}
Expand Down
2 changes: 1 addition & 1 deletion boot/boot_serial/src/boot_serial_encryption.c
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ decrypt_region_inplace(struct boot_loader_state *state,
(off + bytes_copied + idx) - hdr->ih_hdr_size, blk_sz,
blk_off, &buf[idx]);
}
rc = flash_area_erase(fap, off + bytes_copied, chunk_sz);
rc = boot_erase_region(fap, off + bytes_copied, chunk_sz);
if (rc != 0) {
return BOOT_EFLASH;
}
Expand Down
68 changes: 68 additions & 0 deletions boot/bootutil/src/bootutil_misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,74 @@ boot_trailer_sz(uint32_t min_write_sz)
return boot_status_sz(min_write_sz) + boot_trailer_info_sz();
}

int boot_trailer_scramble_offset(const struct flash_area *fa, size_t alignment,
size_t *off)
{
int ret = 0;

/* Not allowed to enforce alignment smaller than device allows */
if (alignment < flash_area_align(fa)) {
alignment = flash_area_align(fa);
}

if (device_requires_erase(fa)) {
/* For device requiring erase align to erase unit */
struct flash_sector sector;

ret = flash_area_get_sector(fa, flash_area_get_size(fa) - boot_trailer_sz(alignment),
&sector);
if (ret < 0) {
return ret;
}

*off = flash_sector_get_off(&sector);
} else {
/* For device not requiring erase align to write block */
*off = flash_area_get_size(fa) - ALIGN_DOWN(boot_trailer_sz(alignment), alignment);
}

return ret;
}

int boot_header_scramble_off_sz(const struct flash_area *fa, int slot, size_t *off,
size_t *size)
{
int ret = 0;
const size_t write_block = flash_area_align(fa);
size_t loff = 0;
struct flash_sector sector;

(void)slot;
#if defined(MCUBOOT_SWAP_USING_OFFSET)
/* In case of swap offset, header of secondary slot image is positioned
* in second sector of slot.
*/
if (slot == BOOT_SECONDARY_SLOT) {
ret = flash_area_get_sector(fa, 0, &sector);
if (ret < 0) {
return ret;
}
loff = flash_sector_get_off(&sector);
}
#endif

if (device_requires_erase(fa)) {
/* For device requiring erase align to erase unit */
ret = flash_area_get_sector(fa, loff, &sector);
if (ret < 0) {
return ret;
}

*size = flash_sector_get_size(&sector);
} else {
/* For device not requiring erase align to write block */
*size = ALIGN_UP(sizeof(((struct image_header *)0)->ih_magic), write_block);
}
*off = loff;

return ret;
}

#if MCUBOOT_SWAP_USING_SCRATCH
/*
* Similar to `boot_trailer_sz` but this function returns the space used to
Expand Down
36 changes: 36 additions & 0 deletions boot/bootutil/src/bootutil_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,16 @@ int boot_find_status(int image_index, const struct flash_area **fap);
int boot_magic_compatible_check(uint8_t tbl_val, uint8_t val);
uint32_t boot_status_sz(uint32_t min_write_sz);
uint32_t boot_trailer_sz(uint32_t min_write_sz);
/* Get offset of trailer aligned to either device erase unit or alignment
* depending on whether device has erase or not.
*/
int boot_trailer_scramble_offset(const struct flash_area *fa, size_t alignment,
size_t *off);
/* Get size of header aligned to device erase unit or write block,
* depending on whether device has erase or not.
*/
int boot_header_scramble_off_sz(const struct flash_area *fa, int slot, size_t *off,
size_t *size);
int boot_status_entries(int image_index, const struct flash_area *fap);
uint32_t boot_status_off(const struct flash_area *fap);
int boot_read_swap_state(const struct flash_area *fap,
Expand Down Expand Up @@ -334,7 +344,19 @@ int boot_copy_region(struct boot_loader_state *state,
const struct flash_area *fap_dst,
uint32_t off_src, uint32_t off_dst, uint32_t sz);
#endif
/* Prepare for write device that requires erase prior to write. This will
* do nothing on devices without erase requirement.
*/
int boot_erase_region(const struct flash_area *fap, uint32_t off, uint32_t sz);
/* Similar to boot_erase_region but will always remove data */
int boot_scramble_region(const struct flash_area *fap, uint32_t off, uint32_t sz);
/* Similar to boot_scramble_region but works backwards */
int boot_scramble_region_backwards(const struct flash_area *fap, uint32_t off, uint32_t sz);
/* Makes slot unbootable, either by scrambling header magic, header sector
* or entire slot, depending on settings.
* Note: slot is passed here becuase at this point there is no function
* matching flash_area object to slot */
int boot_scramble_slot(const struct flash_area *fap, int slot);
bool boot_status_is_reset(const struct boot_status *bs);

#ifdef MCUBOOT_ENC_IMAGES
Expand Down Expand Up @@ -516,6 +538,20 @@ uint32_t bootutil_max_image_size(const struct flash_area *fap);
int boot_read_image_size(struct boot_loader_state *state, int slot,
uint32_t *size);

/* Helper macro to avoid compile errors with systems that do not
* provide function to check device type.
* Note: it used to be inline, but somehow compiler would not
* optimize out branches that were impossible when this evaluated to
* just "true".
*/
#if defined(MCUBOOT_SUPPORT_DEV_WITHOUT_ERASE) && defined(MCUBOOT_SUPPORT_DEV_WITH_ERASE)
#define device_requires_erase(fa) (flash_area_erase_required(fa))
#elif defined(MCUBOOT_SUPPORT_DEV_WITHOUT_ERASE)
#define device_requires_erase(fa) (false)
#else
#define device_requires_erase(fa) (true)
#endif

#ifdef __cplusplus
}
#endif
Expand Down
Loading
Loading