cancel
Showing results for 
Search instead for 
Did you mean: 

is it possible to modify first stage bootloder, u-boot-spl.stm32 for bootup from SD card

HZhu.12
Associate II

To bootup STM32MP157 from SD card, the layout for SD is

partition#1, u-boot-spl.stm32, first copy of first stage bootloader

partition#2, u-boot-spl.stm32, second copy of first stage bootloader

partition#3, u-boot.img, second stage bootloader

partition#4, rfs.ext4, root file system

 

here there is single copy of second stage bootloader, if there is power off during flashing firmware, uboot on partition#3 might be corrupted and then my device would not be able to bootup, I would like to change the partition layout to

partition#1, u-boot-spl.stm32, first copy of first stage bootloader

partition#2, u-boot-spl.stm32, second copy of first stage bootloader

partition#3, u-boot.img, first copy of second stage bootloader

partition#4, u-boot.img, second copy of second stage bootloader

partition#5, rfs.ext4, root file system

 

and modify the spl first stage bootloader to add in check, if it detect 1st copy of uboot is corrupted, then it will load second copy instead, so far haven't seen any document on how to do it.

 

Also actually in my previous production device, I always have 3 copy of boot, 2 of them can be filed update by user, and one copy is read only factory default one, just in case, somehow both first 2 corrupted by human error, device is still able to boot up.

1 REPLY 1
PatrickD
ST Employee

Hi,

For information: SPL should NOT use to make product on STM32MP15x product line (SPL is only used as upstream support).

Anyway this behavior is no supported in by default U-Boot SPL, but it can be done....

you can directly hack the u-boot code => common/spl/spl_mmc.c

Or you can to code it in your board /project custom code.

in ST Microelectronics boards, today we assigned (in the weak function arch/arm/mach-stm32mp/spl.c::spl_boot_device() )

BOOT_DEVICE_MMC1 => boot from mmc 0 device (SDMMC1 = SD card)

BOOT_DEVICE_MMC2 => boot from mmc 1 device (SDMMC2 = eMMC)

The associated partition (defined in spl_mmc_boot_partition() )

BOOT_DEVICE_MMC1 => CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION

BOOT_DEVICE_MMC2 => CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2

And an other target exist BOOT_DEVICE_MMC2_2....

with 2 targets U-Boot, by modify this part can try to load u-boot.img for 2 partitions

in your example,

1/ add a weak function weak (overidde the default beahvior = common/spl/spl.c:492:__weak void board_boot_order(u32 *spl_boot_list) )

void board_boot_order(u32 *spl_boot_list)

{

u32 boot_mode;

boot_mode = get_bootmode();

switch (boot_mode) {

case BOOT_FLASH_SD_1:

case BOOT_FLASH_EMMC_1:

spl_boot_list[0] = BOOT_DEVICE_MMC1

spl_boot_list[1] = BOOT_DEVICE_MMC2;

case BOOT_SERIAL_UART_1:

case BOOT_SERIAL_UART_2:

case BOOT_SERIAL_UART_3:

case BOOT_SERIAL_UART_4:

case BOOT_SERIAL_UART_5:

case BOOT_SERIAL_UART_6:

case BOOT_SERIAL_UART_7:

case BOOT_SERIAL_UART_8:

spl_boot_list[0] = BOOT_DEVICE_UART;

break;

case BOOT_SERIAL_USB_OTG:

spl_boot_list[0] = BOOT_DEVICE_UART;

break;

}

}

=> That changes the default SPL behavior / no more use spl_boot_device()

2/ always select the correct MMC device 0 =

change to weak the fucntion spl_mmc_get_device_index

static int spl_mmc_get_device_index(u32 boot_device)

{

switch (boot_device) {

case BOOT_DEVICE_MMC1:

case BOOT_DEVICE_MMC2:

return 0;

}

return -ENODEV;

}

3/ select the correct device partition

CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION = 3

CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2 =4

as

int spl_mmc_boot_partition(const u32 boot_device)

{

switch (boot_device) {

case BOOT_DEVICE_MMC1:

return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION;

case BOOT_DEVICE_MMC2:

return CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_PARTITION_MMC2;

default:

return -EINVAL;

}

}

regards

Patrick