Driver

Building from Source

This page covers how to build the ua_apollo kernel module from source, including prerequisites, build options, and DKMS setup for automatic rebuilds on kernel updates.

For the standard quick-start process (build, load, verify), see the Installation guide.


Prerequisites

You need the following packages installed on your system:

  • Kernel headers matching your running kernel
  • GCC (the kernel module build system requires it)
  • GNU Make
  • kmod tools (insmod, modprobe, depmod)

Fedora / RHEL

sudo dnf install kernel-devel gcc make kmod

Ubuntu / Debian

sudo apt install linux-headers-$(uname -r) build-essential kmod

Arch Linux

sudo pacman -S linux-headers gcc make kmod

Verify your kernel headers are installed and match:

ls /lib/modules/$(uname -r)/build

If this directory does not exist, your kernel headers are not installed or do not match the running kernel.


Build Process

Step 1: Clone the Repository

git clone https://github.com/open-apollo/open-apollo.git
cd open-apollo

Step 2: Build the Module

cd driver
make

This invokes the kernel build system:

make -C /lib/modules/$(uname -r)/build M=$(pwd) modules

On success, you will see ua_apollo.ko in the driver/ directory. The module is composed of three object files:

ObjectSourcePurpose
ua_core.oua_core.cPCIe probe, device detection, chardev, ioctls
ua_audio.oua_audio.cALSA PCM, mixer controls, DMA, transport
ua_dsp.oua_dsp.cDSP ring buffers, firmware loading, routing

Step 3: Install the Module

sudo make install

This runs modules_install and depmod -a, placing the module into your kernel's module tree so modprobe ua_apollo works.

Step 4: Install Firmware

The mixer DSP firmware blob must be placed in /lib/firmware/:

sudo make firmware-install

This copies ua-apollo-mixer.bin from the repository root to /lib/firmware/ua-apollo-mixer.bin. The driver loads this file automatically via the kernel's request_firmware() API during probe.


Make Targets

TargetDescription
make or make allBuild the kernel module (ua_apollo.ko)
make cleanRemove all build artifacts
make installInstall module to kernel tree and run depmod
make firmware-installInstall firmware blob to /lib/firmware/

Build Options

Custom Kernel Directory

To build against a different kernel (e.g., for cross-compilation or a non-running kernel):

make KDIR=/path/to/kernel/build

The default is:

KDIR ?= /lib/modules/$(shell uname -r)/build

Compiler Flags

The Makefile applies -Og (optimize for debugging) to both ua_core.c and ua_audio.c as a workaround for a GCC 13.3 internal compiler error (ICE in try_forward_edges at -O1/-O2). This is defined in the Makefile as:

CFLAGS_ua_core.o := -Og
CFLAGS_ua_audio.o := -Og

You do not need to change these unless you are working on the driver source code and want to test with different optimization levels.


Common Build Errors

Missing kernel headers

make[1]: *** /lib/modules/6.x.y/build: No such file or directory

Fix: Install the kernel-devel package matching your running kernel. On Fedora: sudo dnf install kernel-devel-$(uname -r).

Version mismatch

ERROR: modpost: module ua_apollo.ko is from kernel X but loaded on kernel Y

Fix: Rebuild after a kernel update: make clean && make. Or use DKMS (see below) to handle this automatically.

GCC ICE (Internal Compiler Error)

during GIMPLE pass: try_forward_edges
cfgcleanup.cc:580: ICE

Fix: This is a known GCC 13.3 bug triggered by large functions at -O1/-O2. The Makefile already works around this with -Og. If you see this error, ensure you are using the unmodified Makefile.

Symbol version warnings

WARNING: modpost: module ua_apollo.ko: symbol xyz has no CRC

Fix: This typically means the kernel was built with CONFIG_MODVERSIONS but the headers don't include CRC data. Ensure kernel-devel matches your exact running kernel version.


DKMS Setup

DKMS (Dynamic Kernel Module Support) automatically rebuilds the module whenever you install a new kernel.

Step 1: Install DKMS

# Fedora
sudo dnf install dkms

# Ubuntu/Debian
sudo apt install dkms

Step 2: Create a DKMS Configuration

Create /usr/src/ua_apollo-0.2.0/dkms.conf:

PACKAGE_NAME="ua_apollo"
PACKAGE_VERSION="0.2.0"
BUILT_MODULE_NAME[0]="ua_apollo"
BUILT_MODULE_LOCATION[0]="driver/"
DEST_MODULE_LOCATION[0]="/extra"
AUTOINSTALL="yes"
MAKE[0]="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build/driver modules"
CLEAN="make -C ${kernel_source_dir} M=${dkms_tree}/${PACKAGE_NAME}/${PACKAGE_VERSION}/build/driver clean"

Step 3: Copy Source and Register

sudo cp -r . /usr/src/ua_apollo-0.2.0/
sudo dkms add -m ua_apollo -v 0.2.0
sudo dkms build -m ua_apollo -v 0.2.0
sudo dkms install -m ua_apollo -v 0.2.0

Step 4: Verify

dkms status

You should see ua_apollo/0.2.0 listed as installed. On your next kernel update, DKMS will automatically rebuild the module.


Verifying the Build

After building, check the module information:

modinfo driver/ua_apollo.ko

Expected output includes:

description:    Universal Audio Apollo Thunderbolt PCIe driver
license:        GPL
author:         Open Apollo contributors

To confirm the module loads correctly:

sudo insmod driver/ua_apollo.ko
dmesg | tail -20

Look for lines like:

ua_apollo 0000:xx:00.0: Apollo x4: FPGA rev 0x........
ua_apollo 0000:xx:00.0: audio: 24 play ch, 22 rec ch, 4096 frame buf
Previous
Supported Devices