Bare metal Raspberry Pi Zero

These are short notes on loading baremetal software on the Raspberry Pi Zero. I started down this path due to wanting to learn Rust, which lead to Tock which is an embedded operating system in Rust. Rather than buy yet another piece of hardware I though I’d use one of my 5 (!) Raspberry Pi Zeros as a development board instead. It’s just another microcontroller, just one that runs at 1 GHz and has a ton of RAM…

Console

See https://pinout.xyz/pinout/uart for the UART pins. Note that on Linux you need to add enable_uart=1 to boot/config.txt.

Connect to a USB –> Serial adapter and launch a console at 11500 baud.

Examples

See dwelch’s bare metal examples. Note that every Pi model has different things on different pins so use the examples from boards/pizero.

Loading

The Pi Zero can boot over USB from a host machine without needing a SD card. This greatly reduces the build/debug cycle. To do this:

  • Fetch bootcode.bin and start.elf from the firmware repo.
  • Fetch the usbboot repo and build.
  • Copy the .bin file to kernel.img
  • Run sudo rpiboot -d .
  • Unplug / plug the board

A fully worked example is:

$ git clone --depth 1 https://github.com/raspberrypi/firmware
Cloning into 'firmware'...
$ mkdir boot
$ cp firmware/boot/bootcode.bin firmware/boot/start.elf boot/

$ git clone https://github.com/raspberrypi/usbboot.git
Cloning into 'usbboot'...
$ make -C usbboot/

$ git clone https://github.com/dwelch67/raspberrypi.git
$ make -C raspberrypi/boards/pizero/uart02/
$ cp raspberrypi/boards/pizero/uart02/uart02.bin boot/kernel.img

$ sudo ./usbboot/rpiboot -d boot
Waiting for BCM2835/6/7/2711...
Sending bootcode.bin
Successful read 4 bytes
Waiting for BCM2835/6/7/2711...
Second stage boot server
File read: start.elf
File read: kernel.img
Second stage boot server done

JTAG

giving:

$ sudo openocd -f interface/jlink.cfg -f ./raspberry.cfg
Open On-Chip Debugger 0.10.0
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
adapter speed: 100 kHz
adapter_nsrst_delay: 400
none separate
Info : auto-selecting first available session transport "jtag". To override use 'transport select <transport>'.
Info : No device selected, using first device.
Info : J-Link ARM V8 compiled Nov 28 2014 13:44:46
Info : Hardware version: 8.00
Info : VTarget = 3.287 V
Info : clock speed 100 kHz
Info : JTAG tap: rspi.arm tap/device found: 0x07b7617f (mfg: 0x0bf (Broadcom), part: 0x7b76, ver: 0x0)
Info : found ARM1176
Info : rspi.arm: hardware has 6 breakpoints, 2 watchpoints

Note that the ARM CPU needs to be running some code for the JTAG to connect.