Loading Linux Images over UART Print

 

This application note explains how to load images to the target over UART in U-Boot. Keep in mind that loading via a serial port will take quite a long time (minutes per file!) due to the low speeds (limited to 115.2 Kps). Even if Ethernet is not required in embedded product, which is frequently the case for microcontroller applications, we always recommend to our customers that the RMII interface be brought out to a header or a set of test points on embedded board to allow connecting to Ethernet during development phases of the project. That having been said, in certain situations, when Ethernet is not available for whatever reasons, loading images over UART may be the only development and software manufacturing option.

Using the STM32F7 SOM kit, you connect to the target serial console via the USB/UART interface on the SOM-BSB-EXT baseboard. Assuming you connect to a Linux PC host, on the Linux host the STM32F7 serial console will be visible as a /dev/ttyUSBx device. The U-Boot and Linux software configures the console for 115.2 Kps operation.

There are various serial communication tools available for Linux, the most popular perhaps being kermit. kermit is a very powerful tool that can be run in interactive mode or controlled by a script. There is abundant documentation on kermit available in the Internet, if you require details.

The download procedure is based on the loadb command provided by the U-Boot command interface. loadb implements a download capability over UART using the kermit protocol and has the following synopsis:

loadb [<load_address> <baud_rate>]

If you do not specify a load address, then the value will be taken from the loadaddr environment variable. On the STM32F7 SOM loadaddr is set as follows, placing the download buffer into SDRAM:

STM32F7-SOM> print loadaddr
loadaddr=0xC0007FB4
STM32F7-SOM>

If you do not specify a baud rate, then the speed the console is currently running at will be used (set to a default value of 115200 on the STM32F7 SOM).

Once the transmission using loadb finishes, the file will be in memory at the specified load address. The loadaddr environment variable will automatically be set to the address the loadb command used. The filesize environment variable will automatically be set to the number of bytes transferred during the load operation.

Then you are free to do whatever you like with the loaded image. You can boot Linux from the image (assuming it is a bootable Linux file), copy it to some other place (for instance, on-module Flash), display the memory, etc.

To automate the download procedure, you might want to put a desired sequence of interactive steps involving interactions with the U-Boot command interface on the target and kermit on the host into a shell script. For instance, here is a sample script to download a Linux bootable image (rootfs.uImage) to SDRAM and boot Linux from it:

[vlad@yota ~]$ vi uartboot-stm32f7.script
#!/usr/local/bin/kermit

set port /dev/ttyUSB0
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 rootfs.uImage
INPUT 180 {\{13}\{10}STM32F7-SOM> }
IF FAIL STOP 1 INPUT timeout

echo {running kernel}
PAUSE 1
OUTPUT run addip; bootm\{13}
c

Make the script file executable:

[vlad@yota ~]$ chmod a+x ./uartboot-stm32f7.script

Copy the sample Linux image (rootfs.uImage) from the Emcraft software distribution to the host directory you will be running the shell script from.

Make sure that U-Boot console is active, and waiting for the commands input:

STM32F7-SOM>

Then run the script to download the image to the target via UART and boot Linux from it:

[vlad@yota ~]$ ./uartboot-stm32f7.script
C-Kermit 9.0.302 OPEN SOURCE:, 20 Aug 2011, ubuntu [192.168.1.102]

Current Directory: /home/vlad
Communication Device: /dev/ttyUSB0
Communication Speed: 115200
Parity: none
RTT/Timeout: 01 / 03
SENDING: rootfs.uImage => ROOTFS.UIMAGE
File Type: BINARY
File Size: 5773923
Percent Done: 20 //////////
...10...20...30...40...50...60...70...80...90..100
Estimated Time Left: 00:08:53
Transfer Rate, CPS: 8565
Window Slots: 1 of 1
Packet Type: D
Packet Count: 183
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 a 5+ long minutes to download the image at 115.2Kps but finally it will get to the target and Linux will boot from it:

## Total Size = 0x00581a63 = 5773923 Bytes
## Start Addr = 0xC0007FB4
STM32F7-SOM> running kernel
Connecting to /dev/ttyUSB0, 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.
----------------------------------------------------
run addip; bootm
## Booting kernel from Legacy Image at c0007fb4 ...
Image Name: Linux-4.2.0-cortexm-2.1.0
Image Type: ARM Linux Multi-File Image (uncompressed)
Data Size: 5773859 Bytes = 5.5 MB
Load Address: c0008000
Entry Point: c0008001
Contents:
Image 0: 5756576 Bytes = 5.5 MB
Image 1: 17271 Bytes = 16.9 kB
Verifying Checksum ... OK
## Flattened Device Tree from multi component Image at C0007FB4
Booting using the fdt at 0xc05856a0
Loading Multi-File Image ... OK
OK
Loading Device Tree to c1ff8000, end c1fff376 ... OK

Starting kernel ...

Booting Linux on physical CPU 0x0
Linux version 4.2.0-cortexm-2.1.0 (psl@skywanderer.emcraft.com) (gcc version 4.4.1 (Sourcery G++ Lite 2010q1-189) ) #2 Mon Sep 19 11:19:44 +0400 2016
...
init started: BusyBox v1.17.0 (2016-09-19 11:07:14 +0400)
...
/ # ls
bin etc init mnt mnt2 mnt4 root sys usr
dev httpd lib mnt1 mnt3 proc sbin tmp var
/ #

To exit from Kermit and release your terminal, press Ctrl-\, then Q.