cancel
Showing results for 
Search instead for 
Did you mean: 

STM32N6 boot from eMMC

flyflyfly001
Visitor

1. Setup OTP
The default OTP configuration of the chip is to boot from norflash, so you need to modify OTP to boot from EMMC. (Note: OTP can only be modified once, please operate with caution!)
Open STM32CubeProgrammer software, check OTP_FUSES_STM32N6xx in External loaders, as shown below.

640.png
On the OTP page, change the boot_source of OTP11 of the STM32N6 chip to 2, indicating booting from EMMC1 (the default 0 is NorFlash booting), as shown below.

640 (1).png

If you are using 1.8V IO, HSLV_VDDIO4 of OTP124 also needs to be set to 1 to improve performance. (The power domain of EMMC1 uses VDDIO4)

640 (2).png

2. Configure EMMC registers
2.1 Access EXT_CSD registers
The focus is on the configuration of the EXT_CSD[179] register. By reading the EMMC standard document, we can know that the meaning of each bit of this register is as follows:

640 (3).png
We should enable Boot partition 1 enable for boot and Boot acknowledge sent during boot operation Bit. This is based on empirical testing, and the ST official document does not mention this. Very important !!
 
Example code of reading ext_csd[179] register.

    uint8_t ext_csd[512];
    HAL_MMC_GetCardExtCSD(&MMCHandle, ext_csd, 1000);
    printf("EXT_CSD[179] value 0x%x\n", ext_csd[179]);

Example code of writing ext_csd[179] register.

    uint32_t value = 0x00004800;
    status = HAL_MMC_SwitchPartition(&MMCHandle, value);
    if (status) {
        printf("mmc switch partition failed %d", status);
    }

Why the write value is 0x00004800? The 0x48 here is actually the value to be written to the ext_csd[179] register to enable the two bits mentioned above.
The above operation only needs to be written once. The access type of EXT_CSD[179] register bit[6] and bit[5:3] is R/W/E type, where E means that the EMMC will save the value when the power is off. In this way, the required configuration will be used for the next power-on startup, and the BOOT can be performed normally.

 

2.2 CMD command analyse
Going deep into the function HAL_MMC_SwitchPartition, we can find that the function parameter Partition will "OR" the value 0x03B30000 and then sent to EMMC.

640 (4).png
Here 03(Hex) represents the access type, and B3(Hex) is the index of the EXT_CSD register to be accessed, which is 179(Dec). So this function can be used to specifically access the EXT_CSD[179] register. If you want to access other registers, the method is similar. The cmd format can reference as below.

flyflyfly001_0-1738849925084.png

2.3 Write FSBL.bin
EMMC has USER partition, BOOT partition 1 and BOOT partition 2. By default, the USER partition is accessed when powering on. You need to switch to the BOOT partition 1 and write FSBL.bin into it. The method is as follows.
Still in the EXT_CSD[179] register, set bits[2:1] of the register to 1, indicating that you want to access the BOOT partition 1.

640 (6).png

Simple example code can references as below. HAL_MMC_BOOT_PARTITION1 is a macro defined by ST, and its value is 0x00000100, which is consistent with the register writing method introduced before.

    status = HAL_MMC_SwitchPartition(&MMCHandle, HAL_MMC_BOOT_PARTITION1);
    if (status) {
        printf("mmc switch partition failed %d", status);
    }

    if(HAL_MMC_WriteBlocks(&MMCHandle, FSBL_trusted, fsbl_start_addr, fsbl_block_num, 1000) != HAL_OK) {
        printf("write fsbl failed\n");
    }

After finished, we can boot from EMMC next time when power on.

 

 

 

 

1 REPLY 1
RomainR.
ST Employee

Hello @flyflyfly001 

It is true that programming OTPs must be done with caution as it is irreversible.
Regardless of your article, note also that some OTPs are marked as shadowed in RM0486 Rev2 in table 17.

OTP mapping. It is possible for the user to read and write these shadowed OTPs by firmware in secure mode without physically changing the OTP configuration.

RomainR_0-1738855802086.png

This is only possible for the list of shadowed OTPs using the BSEC functions in the driver stm32n6xx_hal_bsec.c.

  • HAL_StatusTypeDef HAL_BSEC_OTP_ReadShadow()
  • HAL_StatusTypeDef HAL_BSEC_OTP_WriteShadow()

More information in RM0486 Rev2 in section 4.3 BSEC functional description, 4.3.5 Operations on fuses.

Best regards,

Romain,

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.