Master boot record

Hi,

I am developing using the SoftDevice s140 7.2.0.

I am trying to use the MBR function sd_mbr_command() to upgrade my bootloader with command SD_MBR_COMMAND_COPY_BL.

The bootloader occupies the address range 0xf8000-0xfdfff, so the length is 0x6000 bytes. The initialization of the copy_bl_t component of the command structure is:

- bl_src pointing to a RAM buffer containing the new bootloader

- bl_len = 0x6000/sizeof(uint32_t) = 0x1800.

I have set the UICR_NWF[0] = 0xf8000 (bootloader_address) and UICR_NWF[1] = 0xfe0000 (mbr_params_page_address). When calling sd_mbr_command(), I get the error code 9 (NRF_ERROR_INVALID_LENGTH). What could be wrong? What is the valid range for the bl_len parameter?

Regards

  Dirk

Parents
  • Hi,

    Unfortunately, SD_MBR_COMMAND_COPY_BL requires both the source and destination area to be in flash.

    /**@brief This command copies a new BootLoader.
     *
     * The MBR assumes that either @ref MBR_BOOTLOADER_ADDR or @ref MBR_UICR_BOOTLOADER_ADDR is set to
     * the address where the bootloader will be copied. If both addresses are set, the MBR will prioritize
     * @ref MBR_BOOTLOADER_ADDR.
     *
     * The bootloader destination is erased by this function.
     * If (destination+bl_len) is in the middle of a flash page, that whole flash page will be erased.
     *
     * This command requires that @ref MBR_PARAM_PAGE_ADDR or @ref MBR_UICR_PARAM_PAGE_ADDR is set,
     * see @ref sd_mbr_command.
     *
     * This command will use the flash protect peripheral (BPROT or ACL) to protect the flash that is
     * not intended to be written.
     *
     * On success, this function will not return. It will start the new bootloader from reset-vector as normal.
     *
     * @retval ::NRF_ERROR_INTERNAL indicates an internal error that should not happen.
     * @retval ::NRF_ERROR_FORBIDDEN if the bootloader address is not set.
     * @retval ::NRF_ERROR_INVALID_LENGTH if parameters attempts to read or write outside flash area.
     * @retval ::NRF_ERROR_NO_MEM No MBR parameter page is provided. See @ref sd_mbr_command.
     */

    Regards,

    Vidar

  • Thank you for a really fast answer. That explains it. I had not realized that the source must be located in flash. But I guess, that is required to recover after a power failure while writing the new bootloader is not yet complete.

Reply Children
  • No problem, I hope you will be able to work around this limitation without too much change.. Yes, the main, if not only reason for not allowing it to be copied from RAM is probably that it wouldn't be able to recover from a sudden power failure.

  • Hi, sorry to come up again with this topic, but I still have not solved my problem.

    I changed the code to put the new bootloader into flash, and I still get the error code 9.

    command.command = SD_MBR_COMMAND_COPY_BL;

    command.copy_bl.bl_src = 0xdb000

    command.copy_bl.bl_len = 6144

    errCode = sd_mbr_command(&command);

    gives still errCode == 9

    MBR_BOOTLOADER_ADDR (at 0xfff8) is not set, as well as MB_PARAM_PAGE_ADDR (at 0xffc).

    MBR_UICR_BOOTLOADER_ADDR (NRF_UICR->NRFFW[0]) is still 0xf8000 (this is also where the currently executing bootloader is located), MBR_UICR_PARAM_PAGE_ADDR (UICR.NRFW[1]) is 0xfe000

    Do you have any idea what else I could check?

  • Hi,

    This is strange. As far as I can tell, all parameters are valid.

    The copy command should only return invalid length if one of the following conditions are true:

    1) bl_src + bl_len does not exceeds total flash size. 0xdb000 + 0x6000 = 0xE1000

    2) bootloader start + bl_len does not exceeds total flash size. 0xf8000 + 0x6000 = 0xFE000

    3) MBR_UICR_PARAM_PAGE_ADDR + flash page size does not exceeds total flash page size. 0xFE000 + 0x1000 = 0xFF000

    Can you double-check the addresses in UICR again?

  • Ok, I seem to have found it. I had not (as I thought) set MBR_UICR_PARAM_PAGE_ADDR to 0xfe000, but instead to 0xFFE00, so condition 3 was the culprit. Thank you for your help!

Related