Skip to content

Build ‐ RPi ‐ Alpine

Parracodea edited this page Mar 23, 2024 · 1 revision

ℹ️ Consider this a pre-release guide.

Setting up the host.

Get yourself an Alpine install (hard disk, VM, docker... up to you!).

This is for your host system - do not get the RPi version (...yet).

Cross-compiler sysroot

ℹ️ The guide assumes an RPi2 Model B setup (armv7). Replace with aarch64 for a more recent model.

Create a sysroot that will contain all the arm packages:

# Run as root.
mkdir /sysroot
# Init the sysroot
apk --root /sysroot --initdb --arch armv7 add
# Copy repositories
cp /etc/apk/repositories /sysroot/etc/apk/
# Get trust keys (so we don't have to 'allow untrusted' each time)
apk --root /sysroot --allow-untrusted add alpine-keys
# Get development packages
apk --root /sysroot add build-base sdl2-dev freetype-dev opus-dev

Host compiler

On the host, we are going to use Clang and llvm. First off download the necessary packages

# Run as root
apk add clang lld git cmake ninja llvm pkgconf

CMake toolchain

Now we need a CMake toolchain for our cross-compiler. Create a file rpi2b.cmake with the following contents:

# Pi-specific. Adapt to yours!
# https://en.wikipedia.org/wiki/Raspberry_Pi#Specifications
# Pi 2B: armv7
# Pi 2B 1.2, 3*, 4: aarch64
set(CMAKE_SYSTEM_PROCESSOR armv7)

# Pi 2B: Cortex-a7
# Pi 2B 1.2: Cortex-a53
# Pi 3B(+): cortex-a53
set(pi_cpu "cortex-a7")

# Pi 2B and up: neon-vfpv4
set(pi_fpu "neon-vfpv4")

# Common for all RPi versions.
set(CMAKE_SYSROOT /sysroot)
set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_CROSSCOMPILING ON)

set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)

set(pi_flags "-mcpu=${pi_cpu} -mfpu=${pi_fpu} -mfloat-abi=hard")

set(triple ${CMAKE_SYSTEM_PROCESSOR}-alpine-linux-musleabihf)
set(CMAKE_C_COMPILER_TARGET ${triple})
set(CMAKE_CXX_COMPILER_TARGET ${triple})

set(CMAKE_C_FLAGS "${pi_flags}" CACHE STRING "")
set(CMAKE_CXX_FLAGS "${pi_flags}" CACHE STRING "")
set(CMAKE_EXE_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "")
set(CMAKE_SHARED_LINKER_FLAGS "-fuse-ld=lld" CACHE STRING "")

set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)

# https://stackoverflow.com/a/9234452
set(ENV{PKG_CONFIG_DIR} "")
set(ENV{PKG_CONFIG_LIBDIR} "${CMAKE_SYSROOT}/usr/lib/pkgconfig:${CMAKE_SYSROOT}/usr/share/pkgconfig")
set(ENV{PKG_CONFIG_SYSROOT_DIR} ${CMAKE_SYSROOT})

Building

With the host setup, we can build! Refer to the [Build] guide for up-to-date information but it should look like this:

git clone https://github.com/daid/EmptyEpsilon
git clone https://github.com/daid/SeriousProton
mkdir build_pi
cd build_pi
cmake -G Ninja -DCMAKE_TOOLCHAIN_FILE=path/to/rpib.cmake -DCPACK_GENERATOR=TGZ -DWITH_OPUS=system -DCMAKE_BUILD_TYPE=Release ../EmptyEpsilon
ninja package

Current build caveats (2021-10-29)

As of this writing there are a couple minor tweaks to be able to build with this setup:

  • in EmptyEpsilon/src/hardware/serialDriver.cpp, remove the __THROW on the functions somewhere around the top (it's a gcc extension)

Setting up the Pi

⚠️ Follow closely! We are going to do a sys install to reclaim RAM.

You will need an SD card of at least 512MB (1GB if you want a remote debugger). Format your SD card with two partitions:

  • a 128MB bootable FAT.
  • The rest as ext4 (or leave as free space)

Download Alpine's Raspberry Pi. Extract the tarball on the bootable FAT. At the root of the SD FAT partition, create a usercfg.txt with the following contents:

# Enable audio
dtparam=audio=on

# 3D hardware acceleration
dtoverlay=vc4-fkms-v3d
gpu_mem=256

# If you need this, ymmv:
#disable_overscan=1

Eject from your host computer and boot up the Pi with it.

Initial setup

Run the initial setup through setup-alpine. I recommend using busybox for ntp and dropbear for ssh.

** ⚠️ Say none to the last two questions (store config and apk cache) ⚠️ **

Sys install (persistence)

Alpine on the Pi is a ram-based OS. We are going to make it persistent.

To please the setup-disk script we need to remount the current boot partition at a place it understands.

# Mount the second partition.
mount /dev/mmcblk0p2 /mnt
# Create mountpoint for the boot partition
mkdir /mnt/boot
mount -o remount,rw /media/mmcblk0p1
mount /dev/mmcblk0p1 /mnt/boot
setup-disk -m sys /mnt

This should fill up the partition with your system. Now reboot, and you should be on a system taking very little ram running from the SD card (~50MB).

Setting up the system.

Install the necessary packages to run the game:

# The following to run the game
setup-xorg-base
apk add mesa-dri-vc4 mesa-egl sdl2 alsa-utils alsaconf alsa-lib opus

# This to copy the build over SSH
apk add dropbear-scp

Setup a user for your screen (unless you enjoy running stuff as root):

adduser eescreen
addgroup eescreen audio

Updating from SSH

Remember the cross-compiler host? From it, you can scp the necessary files:

# Assuming you're in the `build_pi` folder.
cat EmptyEpsilon.tar.gz | ssh eescreen@<pi_address> tar xzf -

Running the game

Create a ~/.xinitrc:

#!/bin/sh
cd $HOME
exec ./EmptyEpsilon

Now call startx and voila!

Auto start

If you want to auto start, edit /etc/inittab:

tty1::respawn:/bin/login -f eescreen

Add a ~eescreen/.profile:

#!/bin/sh
exec startx

The pi will log right into the game on boot.

References

Clone this wiki locally