Raspberry Pi

From HW wiki
Jump to navigation Jump to search

Raspberry Pi Based Projects

GNU/Linux Kernel and other Utilities

GCC Tool-chain for Cross-Compilation

There are more suggestion of different arm-gnueabihf toolchains variants to use for cross-build of applications for Raspberry Pi platform. But all of them which I have easily found do not correctly match ARMv6 BCM2835 target. The unfortunate selection of arm-linux-gnueabihf as GNU triplet for Raspbian build clashes with official arm-linux-gnueabihf tool-chains which target ARMv7 architecture and produced binaries are less or more incompatible with RPi hardware and GLIBC build.

I have decided to define separate/non-classing GCC architecture arm-rpi-linux-gnueabihf variant and use original Raspbian GLIBC binaries to ensure best compatibility for build tool-chain. The simple approach is to put whole Raspbian root filesystem copy to /usr/arm-rpi-linux-gnueabihf/sys-root. The mosts of the files are not required in fact so reduction to subset of /lib, /lib/arm-linux-gnueabihf, /lib/arm-linux-gnueabihf/libnfsidmap, /lib/arm-linux-gnueabihf/security, /usr/include, /usr/lib, /usr/lib/arm-rpi-linux-gnueabihf is enough. Other option is to use debootstrap with correct parameters to install base Raspbian libraries and development files in /usr/arm-rpi-linux-gnueabihf/sys-root directory. Some symbolic links has to be adapted to point correctly to target files by changing paths to relative. Then libc.so prepared for relative paths and cross-compilation needs to be provided. Create file /usr/arm-rpi-linux-gnueabihf/lib/libc.so with next content

/* GNU ld script
  Use the shared library, but some functions are only in
  the static library, so try that secondarily.  */
GROUP ( libc.so.6 libc_nonshared.a  AS_NEEDED ( ld-linux.so.3 ) )

This should be enough for environment for standard binutils and GCC build. binutils-2.24 has been used without any changes. gcc-4.9.1 with statically included gmp-5.1.2, mpc-1.0.1 and mpfr-3.1.2 has been patched by subset of Debian patches


Then binutils and GCC has been compiled and installed with next configuration

../../../src/gcc-4.9/configure -v \
        --enable-languages=c,c++ \
        --prefix=/usr \
        --with-system-zlib \
        --without-included-gettext \
        --enable-threads=posix \
        --enable-shared \
        --disable-nls \
        --enable-clocale=gnu \
        --enable-objc-gc \
        --enable-mpfr \
        --enable-tls \
        --enable-secureplt \
        --enable-targets=arm-linux-gnu \
        --enable-symvers=gnu \
        --enable-checking=release \
        --build=x86_64-linux-gnu \
        --host=x86_64-linux-gnu \
        --target=arm-rpi-linux-gnueabihf \
        --enable-version-specific-runtime-libs \
        --disable-libgomp \
        --with-headers=/usr/arm-rpi-linux-gnueabihf/sys-include \
        --with-sysroot=/usr/arm-rpi-linux-gnueabihf/sys-root \
        --enable-linker-build-id \
        --enable-libstdcxx-time=yes \
        --enable-gnu-unique-object \
        --enable-plugin \
        --enable-multiarch \
        --disable-sjlj-exceptions \
        --with-arch=armv6 \
        --with-fpu=vfp \

The build binaries for x86_64/amd64 Debian based systems are provided in our DEB tool-chains collection

* http://rtime.felk.cvut.cz/debian/pool/main/b/binutils-2.24/binutils-arm-rpi-linux-gnueabihf_2.24-1_amd64.deb
* http://rtime.felk.cvut.cz/debian/pool/main/g/gcc-4.9.1/gcc-arm-rpi-linux-gnueabihf_4.9.1-1_amd64.deb

Raspberry Pi JTAG debugguing

* RPi JTAG setup documentation http://sysprogs.com/VisualKernel/tutorials/raspberry/jtagsetup/

U-boot commands to enable JTAG pins

mw.l 0x20200000 0x04a020
mw.l 0x20200008 0x65b6c0

FTDI2232 JT_USB5 RPi Connection and Configuration

Interconnection of 10 pin JT_USB5 cable to RPi P1 connector

JT_USB5 pin Signal RPi P1 Type Description
1 TCK 22 Out Clock Signal Output
2 VREF 1 Out Target voltage reference 3.3 V
3 TDI 7 Out Serial Data Out
4 RTCK 16 In/Out General Purpose I/O
5 TDO 18 In Serial Data In
6 RST NC Reset
7 nTRST 15 In/Out Test system reset
8 GND 6, 9, 25 In/Out Target ground
9 TMS 13 Out Select Signal Out
10 GND 6, 9, 25 In/Out Target ground

telnet_port 4444
gdb_port 3333

interface ftdi

#ftdi_device_desc "Dual RS232"
ftdi_vid_pid 0x0403 0x6010

ftdi_layout_init 0x0cf8 0x0cfb
ftdi_layout_signal nTRST -data 0x0010 -noe 0x0800
ftdi_layout_signal nSRST -ndata 0x0040 -noe 0x0400

ftdi_layout_signal nTRST -data 0x0010
ftdi_layout_signal nSRST -ndata 0x0040
ftdi_layout_signal LED -ndata 0x0800

transport select jtag

adapter_khz 500

reset_config none

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

reset_config none

if { [info exists CPU_TAPID ] } {
} else {
   set _CPU_TAPID 0x07b7617F
jtag newtap $_CHIPNAME arm -irlen 5 -expected-id $_CPU_TAPID

target create $_TARGETNAME arm11 -chain-position $_TARGETNAME

adapter_khz 500


Complete setup with U-boot TFTP based kernel load can be found at

RTEMS Boot with use of U-boot

Setup of RTEMS image boot over TFTP with U-boot and static IP address

Copy u-boot.bin to RPi boot partition and setup first stage loader to run U-boot - i.e. modify config.txt select


Configure TFTP server on host system and convert binary to U-boot image format ( RTEMS tests applications in ELF format can be found after successful compilation in build samples subdirectory, i.e. for ticker arm-rtems4.11/c/raspberrypi/testsuites/samples/ticker/ticker.exe). Convert that to U-boot image.

arm-rtems4.11-objcopy -R -S --strip-debug -O binary ticker.exe ticker.bin || exit 1
cat ticker.bin | gzip -9 >ticker.gz
mkimage -A arm -O rtems -T kernel -a 0x00008000 -e 0x00008000 -n "RTEMS" -d ticker.gz ticker.img

Copy ticker.img to TFTP served directory (I use /srv/tftp/rpi/rtems on Debian).

Setup U-boot environment. One option is to use uEnv.txt file on the RPi SD-card boot partition with next content

bootcmd=mw.l 0x20200000 0x04a020; mw.l 0x20200008 0x65b6c0; usb start; tftp ${kernel_addr_r} ; bootm ${kernel_addr_r}

This sequence specifies default command invoked by boot and automatically during startup. The direct memory locations change is there to enable JTAG debugger pins on P1 connector.

Running RTEMS Under RPi2 QEMU

RTEMS BSP for RPi2 is configured for actual RTEMS 4.12 development sources

../../../git/rtems/configure --target=arm-rtems4.12 --prefix=/opt/rtems4.12 \
  --enable-rtems-inlines --disable-multiprocessing --enable-cxx \
  --enable-rdbg --enable-maintainer-mode --enable-tests=samples \
  --enable-networking --enable-posix --disable-itron --disable-ada \
  --disable-expada --disable-multilib --disable-docs \

QEMU version 2.6 introduces Raspberry Pi BSP support. But QEMU kernel parameter does not load right plain binary kernel image. But it recognizes and loads and starts right way U-boot images. The run of RTEMS applications build for RPi2 from 4.12 development GIT works well. The "kimage" U-boot utility has to be installed on system (Debian package u-boot-tools). Then RTEMS ELF application image can be prepared and run by QEMU


arm-rtems4.12-objcopy -R -S --strip-debug -O binary "$EXE_NAME" "$EXE_NAME.bin" || exit 1
cat "$EXE_NAME.bin" | gzip -9 >"$EXE_NAME.gz"
mkimage \
  -A arm -O rtems -T kernel -a $START_ADDR -e $START_ADDR -n "RTEMS" \
  -d "$EXE_NAME.gz" "$EXE_NAME.img"

qemu-system-arm -M raspi2 \
  -serial stdio \
  -kernel "$EXE_NAME.img"

Debugging RTEMS Under RPi2 QEMU

Start QEMU with request to wait for GDB

qemu-system-arm \
  -M raspi2 \
  -serial stdio \
  -s -S

The last two options enable GDB support and stop QEMU after initialization. I redirect serial line I/O to console to ease capture and copy pasting.

I have not succeed with RTEMS application load through -kernel option nor from SDcard (-sd qemu/rpi2-sd.img). I have tried plain binary. But I have no problem to debug RTEMS start by GDB which loads ELF application image

I start GDB with application image and qemu-debug-rpi2-app.gdb command script

arm-elf-gdb -x qemu-debig-rpi2-app.gdb rtems/arm-rtems4.12/c/raspberrypi2/testsuites/samples/ticker/ticker.exe

The "qemu-debug-rpi2-app.gdb" script content is

target remote localhost:1234
hbreak *0x0

# set breakpoint to the location where application
# is expected and QEMU jumps after initialization
hbreak *0x8000
# continue initialization till breakpoint at 0x8000
# is reached

# load RTEMS ELF application image
# set breakpoints to catch fatal exceptions
hbreak *0x0004
hbreak *0x0008
hbreak *0x000C
hbreak *0x0010
hbreak *0x001C

set $pc=0x8000
# set breakpoints of interrest for debugging
hbreak bsp_start_hook_0
hbreak bsp_start_hook_1

GDB starts, sets breakpoint at 0x8000 and releases QEMU from initial wait for GDB. QEMU/ARM CPU initializes and executes till it jumps to 0x8000 and stops on breakpoint. This returns control back to GDB. It loads application image and sets breakpoints and waits for user. You can step through code (si,s,ni,n commands) or let it run at "full" emulated speed (c). It stops at predefined breakpoints and state can be examined.