Updatable bootlaoder (over BLE SMP)

Hi,

I have added a support for application DFU over BLE SMP to our project (with mcumgr). It work with no problem. Now what I want to achieve is an updatable MCUBoot with the same transport layer. We already have a NSIB and proper static memory map configuration (configured with Partition Manager's pm_static.yml - we have mcuboot_secondary slot set in the external flash and B0 slots in internal flash). I have looked through code and it seems to me like the zephyr_img_mgmt implementation natively supports only application image updates with mcuboot backend. Is there any out of the box solution for updating the mcuboot itself? Is mcumgr flexible enough to upload the image to the partition/address other than mcuboot_secondary - in particular to the S1 slot of the B0 bootloader configured in the internal flash memory?

I have tried the solution proposed here but with the BLE SMP transport instead of UART:Update mcuboot with SMP
But it doesn't seem to work as the uploaded image lands in the mcuboot's external flash partition (verified with debbuger that the flash device being opened is the mx25r64).

I'd presume that the binary to be uploaded with mcumgr must have encoded all information needed to upload it to the proper memory address (judged by CBOR decoding implemented here: https://github.com/nrfconnect/sdk-zephyr/blob/main/subsys/mgmt/mcumgr/grp/img_mgmt/src/img_mgmt.c#L508). Does the `signed_by_mcuboot_and_b0_s1_image_update` file meet this criteria? If so, I guess it should be feasible to adapt the mcumgr to handle my case. I'd really appreciate any kind of guide or list of steps required to achieve that.

Also, I saw the CONFIG_MCUMGR_GRP_IMG_DIRECT_UPLOAD, which sounds like something which might help, but I cannot really understand what it does from the KConfig description. I'd warmly welcome any explanation here.

Thanks in advance,

G

Parents
  • Hi Jerzy, 


    According to the code, it seems that MCUBoot should be able to detect if the image is build for S0 or S1 based on the vector table. But what I'm not so sure is that if the active MCUBoot is running at S0 and you upload an image built for S0 what would happen. Ideally MCUBoot should reject it.

    I will be away this week. We will try to get an answer for you next week. 

  • Ok, anyway I think to prevent consecutive DFUs from being stuck by uploading and tagging the invalid image I need a solution which could reject the image which targets the slot (S0/S1) that cannot be actually used at given moment. Like, rejecting the signed_by_mcuboot_and_b0_s0_image_update.bin when the signed_by_mcuboot_and_b0_s1_image_update.bin is expected with simple static variable toggling (we either expect S0 or S1 to be the target slot). Now I have a draft code which assumes that once the DFU over BT SMP upload is finished we can parse the image residing in the mcuboot_secondary to read the target loader address (PM_S1_ADDRESS or PM_S0_ADDRESS):

    static int32_t command_handler(uint32_t event, int32_t rc, bool *abort_more, void *data, size_t data_size) {
        ARG_UNUSED(event);
        ARG_UNUSED(rc);
        ARG_UNUSED(abort_more);
        ARG_UNUSED(data);
        ARG_UNUSED(data_size);
    
        const struct flash_area *secondary_slot_area;
        struct image_header hdr;
    
        /* This callback can be used to perfom any custom action before and after the single DFU image chunk upload. */
        if (event == MGMT_EVT_OP_IMG_MGMT_DFU_STARTED) {
            LOG_INF("Starting DFU over SMP");
        } else if (event == MGMT_EVT_OP_IMG_MGMT_DFU_PENDING) {
            LOG_INF("Finalizing DFU over SMP!!");
    
            int ec = flash_area_open(FIXED_PARTITION_ID(mcuboot_secondary), &secondary_slot_area);
            if (0 == ec) {
                flash_area_read(secondary_slot_area, which_offset?, what_to_write_to?, sizeof(what_to_write_to));
                // TODO: check if the taget offset is PM_S1_ADDRESS or PM_S0_ADDRESS
                flash_area_close(secondary_slot_area);
            } else {
                LOG_ERR("Cannot open flash area [error: %d]", ec);
            }
        }
    
        return MGMT_ERR_EOK;
    }
    
    struct mgmt_callback sStatusCallback = {
        .callback = command_handler,
        .event_id = (MGMT_EVT_OP_IMG_MGMT_DFU_STARTED | MGMT_EVT_OP_IMG_MGMT_DFU_PENDING),
    };
    
    
    ...
    mgmt_callback_register(&sStatusCallback);
    


    But I don't know the format of the signed_by_mcuboot_and_b0_* binaries. I guess there is some metadata, like header, in front of the actual mcuboot image which indicates the slot (S0/S1) which the image will be swapped to. Do you have an idea? Is this documented anywhere? Would this approach work in general?

    Thanks,

    G

  • Hi G,

    The way we do that is in the code the Sigurd sent to you. We check the reset vector in the code of the image, if it's pointing to S0 location or S1 location to know where the image should go. 

Reply Children
Related