Installing Linux Images to Internal Flash Print

 

This note explains how to install images to the internal Flash of the STM32F429. With a bootable Linux image installed to the Flash, you can boot Linux on the STM32F429 with no user intervention. This corresponds to a deployment mode for an embedded device. Whenever a power or reset occurs, Linux boots from the internal Flash automatically and then starts performing whatever operation a specific application is designed for.

As explained in Running U-Boot, the U-Boot firmware is run from the internal Flash. Also, U-Boot takes some portion of the internal Flash to store its environment variables. The Flash memory map maintained by U-Boot on the STM32F429 Discovery is as follows:

Region Size Use
0x08000000 - 0x0801FFFF 128 KBytes U-Boot firmware image
0x08020000 - 0x0803FFFF 128 KBytes U-Boot environment variables
0x08040000 - 0x081FFFFF 1792 KBytes Unused area

 

As can be seen from the above table, there is a 1792 KBytes area in Flash that is unused by U-Boot. The most obvious use for that area is storage for a bootable Linux image. Conceivably it can be used for something else too, for instance to host some file system.

Let's see how to install a bootable Linux image to the Flash and then boot Linux from the installed image. We will use the prebuilt networking.uImage included in the Emcraft software distribution in the below example.

The procedure is based on the U-Boot command called cptf (from "copy to flash"). cptf allows to copy a memory buffer to the internal Flash and has the following synopsis:

cptf dst src size [reset]

dst is an address in the internal Flash, for instance, for a bootable Linux image it will typically be 0x08040000. src is a buffer that gets copied to the Flash. size is the size of the buffer. reset is an optional binary (0 or 1, 0 by default) that specifies whether cptf shall reset the target immediately after installing the buffer to the Flash. The text below will provide concrete examples of how cptf is used to install a Linux image to the Flash.

If you have your STM32F429 connected to the Ethernet (refer to Connecting to Ethernet on the STM32F429 Discovery) and your network is configured for TFTP download (refer to Loading Linux Images via Ethernet and TFTP), installation to Flash is very simple. This is done as follows:

On the host, copy networking.uImage to the TFTP directory:

$ cp networking.uImage /tftpboot/vlad/
$

On the target, tell U-Boot that you will be using the specific image in follow-up commands:

STM32F429-DISCO> setenv image vlad/networking.uImage
STM32F429-DISCO> savenv
Saving Environment to envm...
STM32F429-DISCO>

Run the update command to load the image via TFTP and install it to the internal Flash:

STM32F429-DISCO> run update
Auto-negotiation...completed.
STM32_MAC: link UP (100/Full)
Using STM32_MAC device
TFTP from server 172.17.0.1; our IP address is 172.17.6.136
Filename 'vlad/networking.uImage'.
Load address: 0xd0007fc0
Loading: #################################################################
############################################
done
Bytes transferred = 1592224 (184ba0 hex)
cptf: Updating eNVM. Please wait ...
STM32F429-DISCO>

To clarify, update is really a convinience short-cut to the following command sequence:

STM32F429-DISCO> print update
update=tftp ${image};cptf ${envmaddr} ${loadaddr} ${filesize}
STM32F429-DISCO>

envmaddr is defined as shown below so when the update invocation completes you have the image installed to the unused area of the internal Flash (offset 256 KBytes from the beginning of the Flash):

STM32F429-DISCO> print envmaddr
envmaddr=08040000
STM32F429-DISCO>

If you do not have the Ethernet connection on your Discovery board, you can use UART to download a Linux image to the target. It is not as convienient as Ethernet (download takes minutes), however it works.

Refer to Connecting serial console to the STM32F429 Discovery and Loading Linux images over UART for information on how to set up the UART connection and the basics of UART-based download, respectively.

Here is a shell / kermit script that you can use on the host to install a networking.uImage to the STM32F429 via UART:

$ vi uartinstall-stm32f429.script

set port /dev/ttyUSB1
set speed 115200
set carrier-watch off
set flow-control none
set prefixing all

echo {loading uImage}
PAUSE 1

OUTPUT loadb ${loadaddr} 115200\{13}
send networking.uImage
INPUT 180 {\{13}\{10}STM32F429-DISCO> }
IF FAIL STOP 1 INPUT timeout

echo {installing uImage}
PAUSE 1
OUTPUT cptf ${envmaddr} ${loadaddr} ${filesize} 0\{13}
INPUT 180 {\{13}\{10}STM32F429-DISCO> }
IF FAIL STOP 1 INPUT timeout

c

Change the file mode to make the script an executable file:

$ chmod +x uartinstall-stm32f429.script

Copy the sample Linux image (networking.uImage) to the host directory you will be running the shell script from.

Then run the script to download the image to the target via UART and install it to the internal Flash:

$ ./uartinstall-stm32f429.script
loading uImage

C-Kermit 8.0.212 Dev.26, 20 Dec 2006, yota.emcraft.com [172.17.0.138]

Current Directory: /home/vlad
Communication Device: /dev/ttyUSB1
Communication Speed: 115200
Parity: none
RTT/Timeout: 01 / 03
SENDING: networking.uImage => NETWORKING.UIMAGE
File Type: BINARY
File Size: 1592224
Percent Done: 6 ///
...10...20...30...40...50...60...70...80...90..100
Estimated Time Left: 00:02:56
Transfer Rate, CPS: 8378
Window Slots: 1 of 1
Packet Type: D
Packet Count: 21
Packet Length: 9024
Error Count: 0
Last Error:
Last Message:

X to cancel file, Z to cancel group, to resend last packet,
E to send Error packet, ^C to quit immediately, ^L to refresh screen.

It will take 3 minutes to download the image at 115.2Kps but finally it will get to the target. The next command in the script programs the image to the unused area of the internal Flash (offset 256 KBytes):

STM32F429-DISCO> installing uImage
cptf ${envmaddr} ${loadaddr} ${filesize} 0
cptf: Updating eNVM. Please wait ...
STM32F429-DISCO> Connecting to /dev/ttyUSB1, speed 115200
Escape character: Ctrl-\ (ASCII 28, FS): enabled
Type the escape character followed by C to get back,
or followed by ? to see other options.
----------------------------------------------------

STM32F429-DISCO>

Regardless of whether you have installed the image via Ethernet or UART, the next reset will boot the image from the image in Flash. This is defined by the bootcmd command, which essentailly calls bootm on an image at 0x08040000 (offset 256 KBytes from the beginning of the Flash):

STM32F429-DISCO> print bootcmd
bootcmd=run envmboot
STM32F429-DISCO> print envmboot
envmboot=run addip;bootm ${envmaddr}
STM32F429-DISCO> print envmaddr
envmaddr=08040000
STM32F429-DISCO>


Refer to Running U-Boot for how to control the bootdelay variable in U-Boot.