Mass storage initialization error with nsib and mcuboot

Board: nRF52840Dk

ncs: v2.3.0.

Hi, I am working on a project in which i need to update bootloader itself and application from the external flash. I also need to make partition where i can store my files using FatFs file system.

My project configuration and overlay setting are below:

CONFIG_STDOUT_CONSOLE=y

#USB related configs
CONFIG_USB_DEVICE_STACK=y
CONFIG_USB_DEVICE_PRODUCT="Zephyr MSC sample"
CONFIG_LOG=y
CONFIG_USB_DRIVER_LOG_LEVEL_ERR=y
CONFIG_USB_MASS_STORAGE=y
CONFIG_USB_DEVICE_LOG_LEVEL_ERR=y
CONFIG_USB_MASS_STORAGE_LOG_LEVEL_ERR=y

CONFIG_MAIN_STACK_SIZE=4096


#CONFIG_APP_MSC_STORAGE_FLASH_LITTLEFS=y
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
CONFIG_APP_MSC_STORAGE_FLASH_FATFS=y
CONFIG_FS_FATFS_LFN=y

# External partitions
#CONFIG_PM_PARTITION_REGION_LITTLEFS_EXTERNAL=y
#CONFIG_PM_PARTITION_REGION_SETTINGS_STORAGE_EXTERNAL=y
#CONFIG_PM_PARTITION_REGION_NVS_STORAGE_EXTERNAL=y

CONFIG_BOOTLOADER_MCUBOOT=y
CONFIG_PM_EXTERNAL_FLASH_MCUBOOT_SECONDARY=y

#memory related configs
CONFIG_NVS=y
CONFIG_FLASH=y
CONFIG_FLASH_MAP=y
CONFIG_STREAM_FLASH=y
CONFIG_REBOOT=y
CONFIG_HWINFO=y
CONFIG_IMG_MANAGER=y
CONFIG_IMG_ERASE_PROGRESSIVELY=y

#immutable boot
CONFIG_SECURE_BOOT=y
CONFIG_SB_SIGNING_KEY_FILE="nsib_priv.pem"
CONFIG_BUILD_S1_VARIANT=y
# Need to lower the number of counter slots to be able to update several times. Do not know the best number yet.
CONFIG_SB_NUM_VER_COUNTER_SLOTS=120

CONFIG_FW_INFO_FIRMWARE_VERSION=1
CONFIG_MCUBOOT_IMAGE_VERSION="1.1.1"

/delete-node/ &boot_partition;
/delete-node/ &slot0_partition;
/delete-node/ &slot1_partition;

&flash0 {
	partitions {
		boot_partition: partition@0 {
			label = "mcuboot";
			reg = <0x000000000 0x00010000>;
		};
		slot0_partition: partition@10000 {
			label = "image-0";
			reg = <0x000010000 0x0000e8000>;
		};
	};
};

&mx25r64 {
	partitions {
		compatible = "fixed-partitions";
		#address-cells = <1>;
		#size-cells = <1>;

		slot1_partition: partition@0 {
			label = "image-1";
			reg = <0x000000000 0x0000e8000>;
		};
		external_flash: partition@e8000 {
			label = "external flash";
			reg = <0x0000e8000 0x000718000>;
		};
	};
};

/ {
	chosen {
		nordic,pm-ext-flash = &mx25r64;
	};
	msc_disk0 {
		compatible = "zephyr,flash-disk";
		partition = <&external_flash>;
		disk-name = "NAND";
		cache-size = <4096>;
	};
};

When i am running the code then getting error of msc init:

Attempting to boot slot 0.
Attempting to boot from address 0x9200.
Verifying signature against key 0.
Hash: 0x8f...3b
Firmware signature verified.
Firmware version 5
Setting monotonic counter (version: 5, slot: 0)
*** Booting Zephyr OS build v3.2.99-ncs2-3159-g1e1697d881a9 ***
[00:00:00.376,220] <inf> mcuboot: Starting bootloader
[00:00:00.376,983] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.377,349] <inf> mcuboot: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.377,349] <inf> mcuboot: Boot source: none
[00:00:00.377,838] <inf> mcuboot: Swap type: none
[00:00:00.378,295] <inf> mcuboot: Primary image: magic=bad, swap_type=0x1, copy_done=0x2, image_ok=0x2
[00:00:00.378,662] <inf> mcuboot: Secondary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
[00:00:00.378,692] <inf> mcuboot: Boot source: none
[00:00:00.379,150] <inf> mcuboot: Swap type: none
*** Booting Zephyr OS build v3.2.99-ncs2-3159-g1e1697d881a9 ***
[00:00:00.000,396] <inf> flashdisk: Initialize device NAND
[00:00:00.000,427] <inf> flashdisk: offset e8000, sector size 512, page size 4096, volume size 7438336
[00:00:00.000,488] <err> flashdisk: Error -22 getting page info at offset 100000
[00:00:00.000,488] <err> usb_msc: Storage init ERROR !!!! - Aborting USB init
[00:00:00.000,518] <wrn> main: Image build time: Jul 10 2023 09:44:53
[00:00:00.000,579] <inf> main: Image is confirmed OK

Please help me, what I am doing wrong.

Thanks.

Parents
  • Hi Mithi,

    Currently FAT FS does not work with the Partition Manager enabled. Meanwhile, the Partition Manager is automatically involved when MCUboot, or NSIB, or any other child images are used. Reference:  How to use FATFS with partition manager?  

    Thus, what you are trying to achieve is currently not possible.

    If this is of great importance to your company and product, could you please drop a note with your local Nordic Regional Sales Manager?

    Hieu

    P.s: Please note that it is the summer holiday season here. We are thus understaffed and there would be delay in responses. Our apologies for the inconveniences.

  • By decreasing the size of external flash, I am able to run mass storage device:

            external_flash: partition@e8000 {
                label = "external flash";
                //reg = <0x0000e8000 0x000718000>;
                reg = <0x0000e8000 0x00018000>;
            };
    But I want to consume full size of  external flash memory.
  • Hi Sigvartmh,

    I've uploaded the sample code, please look into this, if i am doing any wrong configuration: 

    nsib_mcuboot_mass_1.zip

  • *** Booting nRF Connect SDK v2.4.99-dev2-68-g386b811dfb17 ***
    Attempting to boot slot 0.
    Attempting to boot from address 0x9200.
    Verifying signature against key 0.
    Hash: 0x8f...3b
    Firmware signature verified.
    Firmware version 11
    Booting (0x9200).
    *** Booting nRF Connect SDK v2.4.99-dev2-68-g386b811dfb17 ***
    [00:00:00.250,854] <inf> mcuboot: Starting bootloader
    [00:00:00.252,868] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.253,326] <inf> mcuboot: Secondary image: magic=good, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.253,356] <inf> mcuboot: Boot source: none
    [00:00:00.255,340] <inf> mcuboot: Primary image: magic=unset, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.255,798] <inf> mcuboot: Secondary image: magic=good, swap_type=0x1, copy_done=0x3, image_ok=0x3
    [00:00:00.255,828] <inf> mcuboot: Boot source: none
    [00:00:00.256,561] <inf> mcuboot: Image index: 1, Swap type: test
    [00:00:00.409,942] <inf> mcuboot: Starting swap using move algorithm.
    [00:00:00.409,973] <wrn> mcuboot: Not enough free space to run swap upgrade
    [00:00:00.409,973] <wrn> mcuboot: required 69632 bytes but only 65536 are available
    *** Booting nRF Connect SDK v2.4.99-dev2-68-g386b811dfb17 ***
    [00:00:00.000,518] <inf> flashdisk: Initialize device NAND
    [00:00:00.000,518] <inf> flashdisk: offset 0, sector size 512, page size 4096, volume size 7516160
    [00:00:00.004,608] <wrn> main: Image build time: Oct  4 2023 13:39:34
    [00:00:00.004,669] <inf> main: Set up button at gpio@50000000 pin 11

    So I tired to run your setup on a newer version of MCUBoot which gives this error message which probably means that the swap before happened with a too small space meaning it copies some wrong data into the flash resulting in an invalid image.

    see:

    [00:00:00.409,973] <wrn> mcuboot: Not enough free space to run swap upgrade
    [00:00:00.409,973] <wrn> mcuboot: required 69632 bytes but only 65536 are available


    So using MCUBoot with Swap using Move requires empty 1 free flash page(4k) at the end of the image for swapping. So what needs to be fixed is your pm_static.yml file. Details on the algorithm here: https://www.youtube.com/watch?v=YgILPGzCdxc

    more info with regards to the flash block here: Partition Manager not using flash efficientlyy

  • Could you please fix this issue in pm_static.yml file for both application and bootloader upgrade, and please share the updated file.

  • nsib_mcuboot_mass_1_modified.zip

    Here is a modified version of your project that can do MCUBoot and Application updates. It features a much smaller MCUBoot without logging.

    The problem is that I don't know what you intended with your setup, so I kept it as close to what you initially setup as possible, but I had to modify MCUBoot to fit the alignment requirements. This is not necessarily needed, as you could have also made it bigger, but it depends on your project and what you intend to do.

  • My objective is to update mcuboot and application by binary file stored in external flash. I want to use external flash in two partition 1- for file system and 2- for mcuboot secondary partition.

    I tried your modified project code but not able to update bootloader but able to update application.

    To debug the failure on updating MCUBOOT, I enabled the log of mcuboot, but encountered a flash overflow error.

    Are you able to update MCUBOOT?, if so please let me know which SDK you are using(ncs installed by toolchain manger or installed the main sdk by west) and which cherry-pick you have selected?

Reply
  • My objective is to update mcuboot and application by binary file stored in external flash. I want to use external flash in two partition 1- for file system and 2- for mcuboot secondary partition.

    I tried your modified project code but not able to update bootloader but able to update application.

    To debug the failure on updating MCUBOOT, I enabled the log of mcuboot, but encountered a flash overflow error.

    Are you able to update MCUBOOT?, if so please let me know which SDK you are using(ncs installed by toolchain manger or installed the main sdk by west) and which cherry-pick you have selected?

Children
  • I was able to do it but I see that I disabled asserts which is why you probably are experiencing the same error as I encountered trying to look into your issues:

    I: Starting swap using move algorithm.
    assertion "rc == 0" failed: file "WEST_TOPDIR/bootloader/mcuboot/boot/bootutil/src/swap_move.c", line 367, function: boot_move_sector_up
    and
    assertion "rc == 0" failed: file "WEST_TOPDIR/bootloader/mcuboot/boot/bootutil/src/swap_misc.c", line 73, function: swap_erase_trailer_sectors
    abort()
    nsib_mcuboot_with_log.zip

    removing the asserts will allow it to swap at least once(haven't tested more) but it's not ideal.

    attached you can find a project wtih log enabled but figuring out why this asserts would require some more investigations.

  • Hi,

    I tested the nsib_mcuboot_mass_1_modified.zip project by disabling the assert which you mentioned but could not get success.

    When I tried nsib_mcuboot_with_log.zip project, the host displayed a mass storage disk size of approx. 45 KB, preventing me to pasting the binary file into the disk because of size.

    I am expecting that, after allocating required size to the mcuboot secondary partition, all flash memory will be available for the file system i.e. approx. 7MB.

  • Hi Sigvartmh,

    Did you get a chance to investigate the issue?

     

  • Seems it's trying to do a trailer erase out of bounds within the storage space of the new bootloader.

    I assume you tried to investigate some more with your configuration? If not here is one with a larger FS you can still change the PM_static file just make sure you align the sizes.

    nsib_mcuboot_with_log_larger_fs.zip

    I was able to get it working with scratch at least if you apply this patch to mcuboot

    diff --git a/boot/bootutil/src/swap_misc.c b/boot/bootutil/src/swap_misc.c
    index 733a3974..39e89582 100644
    --- a/boot/bootutil/src/swap_misc.c
    +++ b/boot/bootutil/src/swap_misc.c
    @@ -66,15 +66,17 @@ swap_erase_trailer_sectors(const struct boot_loader_state *state,
         sector = boot_img_num_sectors(state, slot) - 1;
         trailer_sz = boot_trailer_sz(BOOT_WRITE_SZ(state));
         total_sz = 0;
    -    do {
    -        sz = boot_img_sector_size(state, slot, sector);
    -        off = boot_img_sector_off(state, slot, sector);
    -        rc = boot_erase_region(fap, off, sz);
    -        assert(rc == 0);
    -
    -        sector--;
    -        total_sz += sz;
    -    } while (total_sz < trailer_sz);
    +    if(!(fa_id_primary == PM_S1_ID || fa_id_primary == PM_S0_ID)) {
    +	    do {
    +		    sz = boot_img_sector_size(state, slot, sector);
    +		    off = boot_img_sector_off(state, slot, sector);
    +		    rc = boot_erase_region(fap, off, sz);
    +		    assert(rc == 0);
    +
    +		    sector--;
    +		    total_sz += sz;
    +	    } while (total_sz < trailer_sz);
    +    }
    
         return rc;
     }

    If you want the PM with scratch are I have it here:

    EMPTY_0:
      address: 0x19200
      end_address: 0x1a000
      placement:
        before:
        - s1_pad
      region: flash_primary
      size: 0xe00
    EMPTY_1:
      address: 0x2a200
      end_address: 0x2b000
      placement:
        before:
        - mcuboot_pad
      region: flash_primary
      size: 0xe00
    app:
      address: 0x2b200
      end_address: 0xfa000
      region: flash_primary
      size: 0xcee00
    app_image:
      address: 0x2b200
      end_address: 0xfa000
      orig_span: &id001
      - app
      region: flash_primary
      size: 0xcee00
      span: *id001
    b0:
      address: 0x0
      end_address: 0x8000
      placement:
        after:
        - start
      region: flash_primary
      size: 0x8000
    b0_container:
      address: 0x0
      end_address: 0x9000
      orig_span: &id002
      - b0
      - provision
      region: flash_primary
      size: 0x9000
      span: *id002
    fatfs_storage:
      address: 0xb1000
      affiliation:
      - disk
      device: DT_CHOSEN(nordic_pm_ext_flash)
      extra_params:
        disk_cache_size: 0x1000
        disk_name: NAND
        disk_read_only: 0x0
        disk_sector_size: 0x200
      placement:
        align:
          start: 0x1000
        before:
        - tfm_storage
        - end
      region: external_flash
      size: 0x74f000
    mcuboot:
      address: 0x9200
      end_address: 0x19200
      placement:
        before:
        - mcuboot_primary
      region: flash_primary
      sharers: 0x1
      size: 0x10000
    mcuboot_pad:
      address: 0x2b000
      end_address: 0x2b200
      placement:
        align:
          start: 0x1000
        before:
        - mcuboot_primary_app
      region: flash_primary
      sharers: 0x2
      size: 0x200
    mcuboot_primary:
      address: 0x2b000
      end_address: 0xfa000
      orig_span: &id003
      - app
      - mcuboot_pad
      region: flash_primary
      size: 0xb1000
      span: *id003
    mcuboot_primary_app:
      address: 0x2b200
      end_address: 0xfa000
      orig_span: &id004
      - app
      region: flash_primary
      size: 0xcee00
      span: *id004
    mcuboot_secondary:
      address: 0x0
      device: DT_CHOSEN(nordic_pm_ext_flash)
      placement:
        align:
          start: 0x4
      region: external_flash
      share_size:
      - mcuboot_primary
      size: 0xb1000
    nvs_storage:
      address: 0xfa000
      end_address: 0x100000
      placement:
        before:
        - end
      region: flash_primary
      size: 0x6000
    provision:
      address: 0x8000
      end_address: 0x9000
      placement:
        after:
        - b0
        align:
          start: 0x1000
      region: flash_primary
      size: 0x1000
    s0:
      address: 0x9000
      end_address: 0x19200
      orig_span: &id005
      - mcuboot
      - s0_pad
      region: flash_primary
      size: 0x10200
      span: *id005
    s0_image:
      address: 0x9200
      end_address: 0x19200
      orig_span: &id006
      - mcuboot
      region: flash_primary
      size: 0x10000
      span: *id006
    s0_pad:
      address: 0x9000
      end_address: 0x9200
      placement:
        after:
        - b0_container
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_pad
      size: 0x200
    s1:
      address: 0x1a000
      end_address: 0x2a200
      orig_span: &id007
      - s1_pad
      - s1_image
      region: flash_primary
      size: 0x10200
      span: *id007
    s1_image:
      address: 0x1a200
      end_address: 0x2a200
      placement:
        after:
        - s1_pad
        - s0
      region: flash_primary
      share_size:
      - mcuboot
      size: 0x10000
    s1_pad:
      address: 0x1a000
      end_address: 0x1a200
      placement:
        after:
        - s0
        align:
          start: 0x1000
      region: flash_primary
      share_size:
      - mcuboot_pad
      size: 0x200
    mcuboot_scratch:
      address: 0xdc000
      end_address: 0xfa000
      placement:
        after:
        - app
        align:
          start: 0x1000
      region: flash_primary
      size: 0x1e000
    sram_primary:
      address: 0x20000000
      end_address: 0x20040000
      region: sram_primary
      size: 0x40000

    I think the patch should work with MCUBoot using move however I haven't tested this.

  • Thanks, Sigvartmh, Now I am able to update the mcuboot.

    We need separated binary files for updating slot S0 and S1, but I prefer not to monitor these for FOTA updates.

    I found a solution for the same:

    But When I am writing "dfu_mcuboot.zip" file to flash, I don't see any updates.

    Please help me, do I need to write any parser for this or It will write same as  signed_by_mcuboot_and_b0_s0_image_update.bin and  signed_by_mcuboot_and_b0_s1_image_update.bin file.

Related