User Tools

Site Tools


Raspberry Pi 3 B+

The GPU loads kernel8.img from the first available FAT partition on the SD card or a USB mass storage device and the CPU jumps to 0x80000 to begin execution in 64-bit mode.

Quick Start: Loading Bare Metal Kernels via UART

It is highly recommended that you compile Goswin von Brederlow's, a kernel image server that will listen for a connection over a serial line (115200/8/N/1) and send a kernel image when connected.

$ gcc -o raspbootcom

For the target board to be able to listen for a kernel over the mini-UART, you should follow bzt's instructions to build a binutils/GCC toolchain targeting aarch64-elf. (We've tested with GCC 8.3.0.) Note that if you're building the toolchain on a Raspberry Pi 3 B+ host running Raspbian, you may want to edit /etc/dphys-swapfile to increase your swap file to a more reasonable value (such as 1024 MB), and limit the build to two simultaneous jobs (make -j2 all-gcc) to avoid GCC running out of memory or making your system unusable. Ideally, you would move this swap to a USB hard drive to avoid SD card wear. Be prepared for this step to take several hours on a Raspberry Pi 3 B+ host.

Next, build bzt's raspbootin64 and copy its kernel8.img to your target SD card. You'll also need bootcode.bin, fixup.dat, and start.elf from the Raspberry Pi Foundation's firmware repository. Finally, you'll need an appropriate config.txt:


Wire up your USB-UART adapter (we've tested with the WINGONEER CP2102 adapter on a Raspberry Pi 3 B+ running Raspbian using CuteCom) to the target board's mini-UART (on pins 8 and 10; don't forget a GND pin). Start raspbootcom by passing it the serial device path of your adapter and the path of the kernel image you'd like to run on the target board, e.g., the kernel from bzt's first UART tutorial, which echoes back your input.

$ raspbootcom /dev/ttyUSB0 kernel8.img

Unmount the SD card, sync to be sure the files have been flushed, and put the SD card in the target board. Power up the target board, and you should see confirmation from raspbootcom that your kernel has been loaded. Now, you can kill raspbootcom and work with the target board, e.g., by talking to the target board via the now available UART.

Following that, you should work through bzt's Bare Metal Raspberry Pi 3 Tutorials.

JTAG Configuration

See OpenOCD for instructions on compiling and installing the latest OpenOCD source. You will need a USB-to-JTAG adapter (SEGGER J-Link EDU and Olimex ARM-USB-TINY-H have been tried) and board configuration, raspi.cfg. To connect to a board with JTAG enabled on the ALT4 pins (e.g., by a devicetree overlay for Linux), you might do:

$ openocd -d3 -f interface/jlink.cfg -f raspi.cfg

Note that in order to run OpenOCD as a regular user on a typical Linux system, you'll need to install a rules file for your JTAG adapter in /etc/udev/rules.d and reboot. The order of the configuration options is important: the interface adapter config must be specified before the board config. The -d3 option provides a more useful level of insight into OpenOCD operation.

OpenOCD Board Configuration (raspi.cfg)

Warning: This is a work-in-progress, and segfaults as soon as you try to connect to the GDB server instance. You need a copy of the latest OpenOCD (0.10+dev) built from the source repository for this configuration.

transport select jtag

#reset_config trst_and_srst
reset_config srst_only

#jtag_rclk 4000
adapter_khz 1000
jtag_ntrst_delay 500

if { [info exists CHIPNAME] } {
} else {
  set _CHIPNAME rpi3

if { [info exists DAP_TAPID] } {
} else {
   set _DAP_TAPID 0x4ba00477

set _DAPNAME      $_CHIPNAME.dap
set _CTINAME_0 	  $_CHIPNAME.cti0
set _CTINAME_1 	  $_CHIPNAME.cti1
set _CTINAME_2 	  $_CHIPNAME.cti2
set _CTINAME_3 	  $_CHIPNAME.cti3

jtag newtap $_CHIPNAME dap -irlen 4 -ircapture 0x1 -irmask 0xf -expected-id $_DAP_TAPID -enable

dap create $_CHIPNAME -chain-position $_DAPNAME 

target create $_TARGETNAME_0 aarch64 -dap $_CHIPNAME -coreid 0 -dbgbase 0x80010000 
target create $_TARGETNAME_1 aarch64 -dap $_CHIPNAME -coreid 1 -dbgbase 0x80012000 
target create $_TARGETNAME_2 aarch64 -dap $_CHIPNAME -coreid 2 -dbgbase 0x80014000 
target create $_TARGETNAME_3 aarch64 -dap $_CHIPNAME -coreid 3 -dbgbase 0x80016000 

cti create $_CTINAME_0 -dap $_CHIPNAME -ap-num 0 -ctibase 0x80018000 
cti create $_CTINAME_1 -dap $_CHIPNAME -ap-num 0 -ctibase 0x80019000 
cti create $_CTINAME_2 -dap $_CHIPNAME -ap-num 0 -ctibase 0x8001A000 
cti create $_CTINAME_3 -dap $_CHIPNAME -ap-num 0 -ctibase 0x8001B000 

$_TARGETNAME_0 configure -event reset-assert-post "aarch64 dbginit"
$_TARGETNAME_0 configure -event gdb-attach { halt }
$_TARGETNAME_1 configure -event reset-assert-post "aarch64 dbginit"
$_TARGETNAME_1 configure -event gdb-attach { halt }
$_TARGETNAME_2 configure -event reset-assert-post "aarch64 dbginit"
$_TARGETNAME_2 configure -event gdb-attach { halt }
$_TARGETNAME_3 configure -event reset-assert-post "aarch64 dbginit"
$_TARGETNAME_3 configure -event gdb-attach { halt }
raspberry_pi_3_b.txt · Last modified: 2019/03/23 03:54 by weilawei