Bare Metal on Raspberry Pi B+: Part One

One of the primary reasons I purchased my Raspberry Pi B+ is I thought that there was probably a way to do bare metal programming on it. “Bare Metal” is a general term for writing code that directly talks to a computer’s processor, essentially low level programming.

Fortunately, a professor at Cambridge University released a series called “Baking Pi,” taking students to a basic interactive operating system, all built in assembly in the Raspberry Pi B with some minor start up help to get the OS loaded.

You’ll note this post is about the B+, which does not perfectly mirror the B in the tutorial. I’ve shared my code that converts correctly the B to B+ address changes if you are looking for a quick answer on how to do the introductory exercises.

However, I have a little more advice, both generally when introducing yourself to bare metal (somebody is gonna nail me for liberally using that term) and in the conversion to the B+:

Read Documentation on ARM

The explanation for the assembly commands provided by Cambridge U is a nice intro, but they do skim over a couple minor details just to get the project rolling. While I totally understand the intent, I would highly recommend pausing at each assembly command and read the documentation at the ARM Information Center. The information is still pretty sparse here as well, but it’s a good way to wade into the ARM documentation tome in a directed manner.

Read the Peripheral Manual

Robert Mullins, the “Baking” author, repeatedly mentions he knows where the locations of the GPIO RAM locations are because he read the manual. Unfortunately, in my case, I was using the B+, which has a different memory map than the B. So I had to look up where the actual locations for the GPIO memory.

Fortunately, a Raspberry Pi forum pointed me in the right direction, a link I’ve lost, but nonetheless I was still forced to go into the manual. This turned out to be very helpful as once I got my head around how the guide outlined RAM and its functions, it actually started to make sense, though with plenty of “Okay, if you say so.”

Similar to my recommendation on ARM assembly, even if you’re using the B, double-check everything that Mullins says just for the experience of finding it yourself. Sorta like how librarians used to force you to use the Dewey Decimal Cards.

Build a pipeline

Not surprisingly, doing bare metal required a lot of trial and error, particularly since I couldn’t get error reports. I know there are ways to use a JTAG to deploy and monitor boot, but this is actually something I don’t have very much experience with or equipment to support. Nope, instead I just pulled that flash drive in and out of my Mac every time.

Save yourself 5 seconds every minute - write yourself a script that runs build commands and properly ejects your disk and provides error escape codes in case you made a typo. It’s worth it after a couple hours of work. I have included a sample script in my repo.

Create Status Functions

After the first lesson in Cambridge’s OK sequence, you’re able to turn on the Pi’s ACT light. The second lesson explains how branching works to create functions. With this little bit of information, you can create a pseudo breakpoint function to at least observe where in the code you’ve reached or test values for equality (if you read up on your ARM codes). It’s a bit of a nuclear option, but it’s the only feedback you can get without a more advanced setup.

Start Building your System Library Immediately

Right alongside my last point, start creating a system library and organizing your code around that for basic things like the breakpoint status methods, pointing to the GPIO region and so forth. While you can follow along with Mullins’ examples, you never know how far the project will take you and it’d be nice to start setting good refactored APIs sooner rather than later.

Furthermore, it’s a nice test to check if you understood everything that was discussed if you can at the very least rename and move around code while maintaining its functionality. Plus you can use cool names like “SYS_OPS_SOMETHING.”

Read Elements of Computing Systems

This is an amazing introduction to systems at this level, without a lot of concern for peripherals, having to reload flash cards, and toy with stack arithmetic when all you can see is a little light. In fact, the tools provided by the authors of the book allow you to actually see the various memory locations in both RAM and the processor. Though not what you need to get really hands on, the conceptual framework was a great resource as I dove into Cambridge’s lessons, particularly when stack organization standards arose.

 

Overall, it’s a fantastic series and the albeit small process of converting to the B+ forced me to examine what was actually happening and lean on some more general coding conventions and knowledge.