Boot a Kernel over Serial with U‑Boot and Kermit

I’m doing a lit­tle bit of work that involves fre­quent­ly rebuild­ing the Linux ker­nel and installing it on a head­less ARM board. The par­tic­u­lar ARM board I’m work­ing with has some ven­dor sup­port for flash­ing ker­nels, but it’s slow and clunky, and I have to run it inside a Windows XP VM. The ARM board uses the U‑Boot boot­loader, though, so it’s pos­si­ble to boot the ker­nel in a cou­ple of dif­fer­ent ways. One way would be to load the ker­nel via TFTP, but I haven’t got­ten that work­ing yet on my board. The oth­er option is to load it via ser­i­al, which isn’t very fast but requires very lit­tle setup.

U‑Boot’s loadm com­mand allows a ker­nel to be loaded, via ser­i­al, into a mem­o­ry loca­tion. The bootm com­mand may then be used to boot the ker­nel direct­ly, which saves time com­pared to writ­ing the ker­nel to the flash mem­o­ry and load­ing it from there. The trou­ble is that loadm expects the ker­nel to be sent via the Kermit pro­to­col. I found a few exam­ples of how to deal with Kermit, but none of them direct­ly applied to load­ing a ker­nel with U‑Boot.

I came up with the fol­low­ing Kermit script to solve my prob­lem. This script auto­mat­i­cal­ly waits for the board to reset, sends the loadm com­mand, push­es down the ker­nel, and runs it via the bootm com­mand. After it boots the ker­nel, it turns into an inter­ac­tive con­sole. This script relies on C‑Kermit, which I installed under Ubuntu as follows:

bash$ sudo aptitude install ckermit

The script I’m using is as fol­lows. There are a lot of set­tings hard-cod­ed into the script, so read the com­ments care­ful­ly to deter­mine what parts you might need to change to suit your set­up. To use this script, sim­ply copy it into a file named, for exam­ple, boot-ker­nel, give it exe­cutable per­mis­sions, and run it.

#!/usr/bin/kermit

# Serial port setup.  These settings will likely need to be
# changed to match the configuration of your workstation
# and the ARM board you're working with.
set line /dev/ttyUSB0
set speed 115200
set serial 8n1

# General C-Kermit settings.  These probably don't need to change.
set flow-control none
set file type bin
set carrier-watch off
set prefixing all
set modem none

echo "Prepared to boot new kernel.  Reset the board now."

# This is the string that my board outputs to allow the user to
# gain access to the U-Boot console.  Change this to suit your
# setup.
input 60 "Hit SPACE to stop autoboot"
# If your board wants you to press a different key to get to
# U-Boot, edit this line.
output " "
input 5 "u-boot>"
# Here, 0x800000 is the memory address into which the kernel
# should be loaded.
lineout "loadb 0x800000"
# This should be the absolute path to your kernel uImage file.
send /path/to/uImage
input 5 "u-boot>"
lineout "bootm 0x800000"

# This command drops you into a console where you can interact
# with the kernel.
connect

Once the script has giv­en you con­sole con­trol, you need to use the Kermit escape key to exit. By default, this is set to Ctrl+\ (that’s a back­slash). To see a list of com­mands, type Ctrl+\ and then ?. The com­mand to imme­di­ate­ly exit the con­sole is q.

One last thing to note: this script does­n’t do any error check­ing. Each of the input com­mands can fail, if it does not see the text it’s look­ing for in the spec­i­fied time. The script could be extend­ed to check for errors using Kermit’s IF command.

Comments are disabled for this post