Boot a Kernel over Serial with U-Boot and Kermit

I’m doing a little bit of work that involves frequently rebuilding the Linux kernel and installing it on a headless ARM board. The particular ARM board I’m working with has some vendor support for flashing kernels, but it’s slow and clunky, and I have to run it inside a Windows XP VM. The ARM board uses the U-Boot bootloader, though, so it’s possible to boot the kernel in a couple of different ways. One way would be to load the kernel via TFTP, but I haven’t gotten that working yet on my board. The other option is to load it via serial, which isn’t very fast but requires very little setup.

U-Boot’s loadm command allows a kernel to be loaded, via serial, into a memory location. The bootm command may then be used to boot the kernel directly, which saves time compared to writing the kernel to the flash memory and loading it from there. The trouble is that loadm expects the kernel to be sent via the Kermit protocol. I found a few examples of how to deal with Kermit, but none of them directly applied to loading a kernel with U-Boot.

I came up with the following Kermit script to solve my problem. This script automatically waits for the board to reset, sends the loadm command, pushes down the kernel, and runs it via the bootm command. After it boots the kernel, it turns into an interactive console. 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 follows. There are a lot of settings hard-coded into the script, so read the comments carefully to determine what parts you might need to change to suit your setup. To use this script, simply copy it into a file named, for example, boot-kernel, give it executable permissions, 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 given you console control, you need to use the Kermit escape key to exit. By default, this is set to Ctrl+\ (that’s a backslash). To see a list of commands, type Ctrl+\ and then ?. The command to immediately exit the console is q.

One last thing to note: this script doesn’t do any error checking. Each of the input commands can fail, if it does not see the text it’s looking for in the specified time. The script could be extended to check for errors using Kermit’s IF command.

Comments are disabled for this post