Sat 26 April 2014

Below is a story of what I've learned about what it takes to
boot a Beagleboard.

BeagleBoard XM on reset - a barren wasteland

Without boot code such as U-Boot
running first, very little is actually working. Most noticeably,
there is no usable UART or external RAM, and quite a lot of
initialization is necessary before they are both in a usable state.
The only available RAM is 128kB that is on the SOC itself. There is
also some ROM that contains code which is the first thing that
starts executing on reset.

How initialization can be done

The usual case is that on reset, the ROM boot code searches boot
devices to find the second-stage bootcode to be executed from the
128kB RAM. Its only task is to initialize RAM and other necessary
peripherals so that the next stage bootloader can be loaded and
executed. This executable is called MLO in TI parlance and it
can be fulfilled by an SPL build of U-Boot. The ROM boot code
is smart enough to parse a partition table and FAT filesystem
and load the MLO to the 128kB on-SOC RAM if there is an MLO on
the MMC. Other boot devices are possible also.

What MLO then does

The U-Boot MLO initializes whatever PLLs, clocks, controllers and
RAM is necessary to get a working UART, external RAM and MMC device.
It is then able to load the full U-Boot from the MMC device into RAM
and execute it. Full U-Boot has much more peripheral support and
other supporting features to load the next step, i.e. the
operating system or application.

What we want so we can test RTEMS

As mentioned, I am working on a
BSP for the
Beagle family of products for
RTEMS. In other words, a port of RTEMS to the
beagles; specifically the BeagleBoard XM, BeagleBone 'White,' and the
BeagleBone Black.

My friend Chris, in testing
my BSP, has introduced me to the powerful notion of what I might
call running-from-scratch. Specifically, getting the hardware, after
reset, into a state where it can load and run an RTEMS binary, absent
a boot loader. This eliminates a lot of dependency on what kind of
state a bootloader might leave the hardware in. And it also eliminates
needing any external software to load & run RTEMS for unattended
testing. We have taken to doing this with
JTAG.

Running without boot code affords us full control. The full system
state is known, which has as advantage that once it works for us,
it should work everywhere. The bootloader is eliminated as a
dependency in determining the system state once the RTEMS binary
starts running. The disadvantage is that we have to figure out how
to load the RTEMS executable, and how to get the hardware into a
usable state without the help of MLO or U-Boot. We can do all this
with JTAG.

Initializing the board with JTAG

My approach has been to duplicate the initialization procedure that U-Boot
SPL (i.e. their MLO) does with JTAG. I executed it in qemu and traced all
memory i/o operations it uses to initialize the hardware. Then I could
recreate then in OpenOCD as a series of writes and so reset the board
and initialize it on every GDB attachment. Now we can run RTEMS
executables over JTAG without any additional software needed!