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
andstart.elf
from the firmware repo. - Fetch the usbboot repo and build.
- Copy the
.bin
file tokernel.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
- Add
enable_jtag_gpio=1
toboot/config.txt
- Wire up using https://github.com/raspberrypi/linux/issues/1749#issuecomment-265404857
- Use the
raspberry.cfg
from https://sysprogs.com/VisualKernel/tutorials/raspberry/jtagsetup/ - Run openocd using
openocd -f interface/jlink.cfg -f ./raspberry.cfg
- Run gdb-multiarch against the corresponding ELF file
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.