April 25, 2017

U-Boot startup and initialization

You may know that U-Boot starts via a two stage process. First a "miniature version" of U-boot called the SPL gets loaded by the bootrom. This in turn loads the full version of U-boot that we will be addressing here. This is by and large because the bootrom has no idea what kind of external memory (ram) may be used in a system or where it might be located. So it is set up to load whatever it loads into a special bit of on-chip static RAM that it knows is always available. This is where the SPL goes. There is not enough room there for the full U-boot, so we have this two stage game.

But let's forget about all that and consider the full U-boot. On the Orange Pi, this gets loaded to 0x4a000000 and execution begins at the first word of the image -- at 0x4a000000, which is the label "_start". You can look high and low for this label. It is not in arch/arm/cpu/armv7/start.S as you might think. You will find it in arch/arm/lib/vectors.S As it turns out though the first instruction at _start is a branch to "reset" in arch/arm/cpu/armv7/start.S so we get there in any event. After performing a fair bit of processor initialization, this branches to "main"

To figure out where "main" is, we resort to ctags. First we run ctags in the base directory for u-boot:

ctags -R .
This produces the "tags" file. Ultimately this proves useless as there are "main" things all over the source tree. So I write another ruby script. This one runs grep for main on only those files that I have listed as being used in the orange Pi build. While not ideal, this does quickly lead us to the answer we want.

As it turns out, we have not yet escaped the world of assembly language, we find the _main entry point in ./arch/arm/lib/crt0.S There is a nice informative comment at the start of this file that explains what is going on. It also guides us to a couple of documents in the U-boot documentation directory. Specifically it recommends reading the section entitled "Board Initialisation Flow" in the main README file. There are a number of other files in the "doc" directory that are worth reading (and no doubt others besides these):

README.generic-board
README.arm-relocation
The meat of things seems to be the two files common/board_f.c and common/board_r.c. The "f" code gets run pre-relocation. The "r" code is the main deal and gets run post-relocation.


Have any comments? Questions? Drop me a line!

Tom's electronics pages / tom@mmto.org