Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) – Loading from SPIFLASH

1. Introduction

Previously, we completed the design and source code implementation of the storage layout and loader. Now we will practice and test loading the image from SPIFLASH into SDRAM for execution. Of course, during debugging, we can also directly transfer the image to SDRAM using xmodem for direct execution.

See the code at:https://github.com/qinyunti/stm32f429-boot.git

Please open in the WeChat client

2. Block Diagram and Image Preparation

The entire process is illustrated as follows

During debugging, we can directly transfer the device tree and kernel image to SDRAM using SHELL with XMODEM, and then use the SHELL BOOT command to jump directly to the kernel for execution, which is suitable for debugging. This method manually loads to SDRAM for execution, and does not retain data upon power loss.

After release, we can transfer the SHELL HEAD information, device tree, and kernel image to SPIFLASH, and then during startup, the LOAD program loads the content from SPIFLASH into SDRAM for execution.

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

Since loading the DTB and KERNEL into SDRAM requires some space, the actual usable RAM is less than 64MB. The usable SDRAM starts from 0x90000000, but only 48MB is allocated. Here, we allocate the last 16MB for the DTB and kernel, with the DTB starting from 0x93000000 occupying 32KB, i.e., 0x8000, and the kernel image starting from 0x93008000 occupying 16MB-32KB.

Therefore, we need to modify the device tree’s memory starting from 0x90000000 with a size of 0x3000000.

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

To speed up xmodem, the serial port baud rate is also modified to 1000000. The device tree is modified as follows

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

Modify the Boot code as follows

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

The previous kernel image ran atin address 0x0800C000, now changed to 0x93008000

Boot options —>

(0x93008000) XIP Kernel Physical Location

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

Rebuild

make ARCH=arm CROSS_COMPILE=arm-none-eabi-

Export to windows

cp arch/arm/boot/dts/st/stm32f429-disco.dtb /mnt/d/stm32f429-disco-sdram.dtb

cp arch/arm/boot/xipImage /mnt/d/xipImage-sdram.bin

Add the boot command in the Boot shell for direct manual jump to the specified location for execution.

Declare in shell_func.c as follows

static void bootfunc(uint8_t* param);

Add in g_shell_cmd_list_ast

 { (uint8_t*)"boot",         bootfunc,         (uint8_t*)"boot dtbaddr[hex] kernel[hex]"}, 

Implement as follows

static void bootfunc(uint8_t* param){ uint32_t dtbaddr; uint32_t kerneladdr; #if 0 if(2 == sscanf((const char*)param, "%*s %lx %lx", &dtbaddr, &kerneladdr)) #else char* p =(char*)param; while(1){  /* Skip %*s part */   if((*p > 'z') || (*p < 'a')){     break;   }else{     p++;   } } long tmp; xatoi(&p, &tmp); dtbaddr = tmp; xatoi(&p, &tmp); kerneladdr = tmp; #endif {   start_kernel(dtbaddr, kerneladdr); }}

3. Manually Load to SDRAM During Debugging

First import stm32f429-disco-sdram.dtb to 0x93000000

rxmem 0x93000000 19604

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

Then import xipImage-sdram.bin to 0x93008000

rxmem 0x93008000 1935164

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

Then enter

boot 0x93000000 0x93008000

Run

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

4. Burn to SPIFLASH for Execution

First manually prepare the HEAD file content as follows

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

The device tree is loaded from SPIFLASH at 0x200 to SDRAM at 0x93000000

The kernel is loaded from SPIFLASH at 0x8200 to SDRAM at 0x93008000

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

Import the HEAD

rxspiflash 0 54

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

Then import the dtb

First rxmem to sdram and then restore to write to spiflash

rxmem 0x90000000 19604

restorespiflash 0x90000000 0x200 19604

Alternatively, you can directly

rxspiflash 0x200 19604

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

Then import the kernel image

First rxmem to sdram and then restore to write to spiflash

rxmem 0x90000000 1935164

restorespiflash 0x90000000 0x8200 1935164

Alternatively, you can directly

rxspiflash 0x8200 1935164

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

Then restart to run

Mastering Linux on MCU Series Part 18: New Boot Design to Load and Start Linux (5) - Loading from SPIFLASH

5. Conclusion

The above has improved the functionality of BOOT, achieving LOAD. You can download the image to SPIFLASH through the boot shell, and then load and start from SPIFLASH, thus the image is no longer limited to the internal 2MB FLASH space, allowing for a larger kernel and more drivers to be added.

At the same time, the BOOT shell has also added more practical commands, such as import/export of mem, import/export of spi flash, and manually transferring images to SDRAM for booting, covering basic common needs, and more can be added for debugging and maintenance.

Leave a Comment