This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[FAQ] How to boot from dual boot media (OSPI NOR + eMMC) using MCU+SDK?

Part Number: AM62P
Other Parts Discussed in Thread: UNIFLASH

Default MCU+SDK SBL examples only support booting from a single boot media (SBL OSPI/SBL EMMC), this FAQ demonstrates how to modify the SBL example to support booting from different boot medias for certain application images (Linux for A53 from eMMC and rest of the images from OSPI NOR). 

  • The FAQ uses SBL_OSPI_LINUX Stage-2 for AM62P as a reference but this can be applied to any other AM62XX SoC, the example below uses following configurations for booting:

    SBL Stage-1 & 2, MCU R5, HSM application images + u-boot.img from OSPI NOR

    Linux Appimage for A53 from EMMC

    Please make the following changes in SBL OSPI Stage-2 example:

    1. SYSCFG change:

    Change the boot media for Linux SBL instance (CONFIG_BOOTLOADER_FLASH_LINUX) to EMMC, you can configure the boot image offset according to your requirements but make sure to flash the Linux Appimage at same the same configured offset.

    Changing the boot media to eMMC will also add an MMCSD instance in the syscfg, you need to change the name of that instance to CONFIG_MMCSD_SBL, following patch includes all the changes required for example.syscfg:

    diff --git a/examples/drivers/boot/sbl_ospi_linux_multistage/sbl_ospi_linux_stage2/am62px-sk/wkup-r5fss0-0_freertos/example.syscfg b/examples/driv
    ers/boot/sbl_ospi_linux_multistage/sbl_ospi_linux_stage2/am62px-sk/wkup-r5fss0-0_freertos/example.syscfg
    index f3b7b5f..efce82a 100644
    --- a/examples/drivers/boot/sbl_ospi_linux_multistage/sbl_ospi_linux_stage2/am62px-sk/wkup-r5fss0-0_freertos/example.syscfg
    +++ b/examples/drivers/boot/sbl_ospi_linux_multistage/sbl_ospi_linux_stage2/am62px-sk/wkup-r5fss0-0_freertos/example.syscfg
    @@ -16,6 +16,8 @@ const bootloader1 = bootloader.addInstance();
     const bootloader2 = bootloader.addInstance();
     const bootloader3 = bootloader.addInstance();
     const gtc         = scripting.addModule("/drivers/gtc/gtc");
    +const mmcsd       = scripting.addModule("/drivers/mmcsd/mmcsd", {}, false);
    +const mmcsd1      = mmcsd.addInstance();
     const uart        = scripting.addModule("/drivers/uart/uart", {}, false);
     const uart1       = uart.addInstance();
     const clock       = scripting.addModule("/kernel/dpl/clock");
    @@ -40,12 +42,8 @@ bootloader1.appImageOffset = "0x240000";
     bootloader2.$name          = "CONFIG_BOOTLOADER_FLASH_MCU";
     bootloader2.appImageOffset = "0x800000";
     
    -bootloader3.$name          = "CONFIG_BOOTLOADER_FLASH_LINUX";
    -bootloader3.appImageOffset = "0x1200000";
    -
     bootloader1.flashDriver                                 = flash1;
     bootloader2.flashDriver                                 = flash1;
    -bootloader3.flashDriver                                 = flash1;
     flash1.$name                                            = "CONFIG_FLASH_SBL";
     flash1.serialFlashDriver.$name                          = "board_flash_serialFlash_serialflash0";
     flash1.serialFlashDriver.peripheralDriver.$name         = "CONFIG_OSPI_SBL";
    @@ -53,6 +51,13 @@ flash1.serialFlashDriver.peripheralDriver.dmaEnable     = true;
     flash1.serialFlashDriver.peripheralDriver.phyEnable     = true;
     flash1.serialFlashDriver.peripheralDriver.phySkipTuning = true;
     
    +bootloader3.$name          = "CONFIG_BOOTLOADER_FLASH_LINUX";
    +bootloader3.appImageOffset = "0x1200000";
    +bootloader3.bootMedia      = "EMMC";
    +
    +bootloader3.MMCSDDriver = mmcsd1;
    +mmcsd1.$name            = "CONFIG_MMCSD_SBL";
    +
     uart1.$name                      = "CONFIG_UART_SBL";
     uart1.useWakeupDomainPeripherals = false;
     uart1.addedByBootloader          = true;
    @@ -142,6 +147,7 @@ flash1.serialFlashDriver.peripheralDriver.OSPI.D3.$suggestSolution   = "OSPI0_D3
     flash1.serialFlashDriver.peripheralDriver.OSPI.D2.$suggestSolution   = "OSPI0_D2";
     flash1.serialFlashDriver.peripheralDriver.OSPI.D1.$suggestSolution   = "OSPI0_D1";
     flash1.serialFlashDriver.peripheralDriver.OSPI.D0.$suggestSolution   = "OSPI0_D0";
    +mmcsd1.MMC0.$suggestSolution                                         = "MMC0";
     uart1.UART.$suggestSolution                                          = "USART0";
     uart1.UART.RXD.$suggestSolution                                      = "UART0_RXD";
     uart1.UART.TXD.$suggestSolution                                      = "UART0_TXD";

    2.  Changes in sbl_ospi_linux_stage2.c:

    Apply this patch to sbl_ospi_linux_stage2.c to boot the linux appimage from eMMC:

    diff --git a/examples/drivers/boot/common/soc/am62px/sbl_ospi_linux_stage2.c b/examples/drivers/boot/common/soc/am62px/sbl_ospi_linux_stage2.c
    index d6df824..3785ddb 100644
    --- a/examples/drivers/boot/common/soc/am62px/sbl_ospi_linux_stage2.c
    +++ b/examples/drivers/boot/common/soc/am62px/sbl_ospi_linux_stage2.c
    @@ -109,6 +109,14 @@ void App_driversOpen()
             DebugP_logError("OSPI open failed for instance %d !!!\r\n", CONFIG_OSPI_SBL);
         }
     
    +    gMmcsdHandle[CONFIG_MMCSD_SBL] = NULL;
    +
    +    gMmcsdHandle[CONFIG_MMCSD_SBL] = MMCSD_open(CONFIG_MMCSD_SBL, &gMmcsdParams[CONFIG_MMCSD_SBL]);
    +    if(NULL == gMmcsdHandle[CONFIG_MMCSD_SBL])
    +    {
    +        DebugP_logError("MMCSD open failed for instance %d !!!\r\n", CONFIG_MMCSD_SBL);
    +    }
    +
         gUartHandle[CONFIG_UART_SBL] = NULL;
     
         gUartHandle[CONFIG_UART_SBL] = UART_open(CONFIG_UART_SBL, &gUartParams[CONFIG_UART_SBL]);
    @@ -129,6 +137,9 @@ void App_driversClose()
         OSPI_close(gOspiHandle[CONFIG_OSPI_SBL]);
         gOspiHandle[CONFIG_OSPI_SBL] = NULL;
     
    +    MMCSD_close(gMmcsdHandle[CONFIG_MMCSD_SBL]);
    +    gMmcsdHandle[CONFIG_MMCSD_SBL] = NULL;
    +
         UART_close(gUartHandle[CONFIG_UART_SBL]);
         gUartHandle[CONFIG_UART_SBL] = NULL;
     }
    @@ -232,6 +243,7 @@ void App_loadAndRunImages(Bootloader_LoadImageParams *bootLoadParams)
                     gImageSize += Bootloader_getMulticoreImageSize(bootLoadParams->bootHandle);
     
                     App_printBootloaderLogs();
    +                SOC_moduleClockEnable(TISCI_DEV_MMCSD0, 0);
     
                     /* Unlock all the control MMRs. Linux/U-boot expects all the MMRs to be unlocked */
                     SOC_unlockAllMMR();

    Please make sure to rebuild the Stage-2 example after making these changes.

  • Make sure to flash the application images to proper boot media and at a proper offset according to the bootloader configurations, when using UART UNIFLASH, you can use the following config file as a reference for flashing: sbl_ospi_emmc_linux_hs_fs.cfg

    Falcon boot:

    Please note that for a normal linux boot, u-boot.img still gets loaded from OSPI NOR, so you would need to flash it at 0x280000 offset in OSPI, but u-boot is skipped when using the falcon boot so there is no need to flash the u-boot.img and you just need to flash linux.falcon.appimage.hs_fs at the configured offset in eMMC.