Skip to content

Cross Compilation

Cross compilation means building code on one machine for a different target architecture.

In this project, the typical workflow is:

WSL / Ubuntu host
aarch64-linux-gnu-gcc
Raspberry Pi 5 / arm64 kernel module

Why It Matters

Cross compilation is useful when the target board is slower, has limited storage, or is less convenient for development.

For Embedded Linux kernel module development, it also helps separate:

  • source editing
  • build environment setup
  • target board testing

Key Variables

Variable Purpose
ARCH=arm64 Selects the target kernel architecture
CROSS_COMPILE=aarch64-linux-gnu- Selects the cross toolchain prefix
KDIR Points to the target kernel build directory or copied kernel headers

Example:

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- KDIR=/path/to/kernel/headers

Out-of-Tree Module Build

A common module Makefile pattern is:

obj-m += mydriver.o

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

all:
    $(MAKE) -C $(KDIR) M=$(PWD) modules

clean:
    $(MAKE) -C $(KDIR) M=$(PWD) clean

When cross-compiling, the important part is that KDIR must match the target kernel, not the host kernel.

Typical Checks

aarch64-linux-gnu-gcc -v
file mydriver.ko
modinfo mydriver.ko

Check that the generated module is for the expected target architecture and kernel release.

Common Pitfalls

Warning

Cross-compiling a module successfully does not guarantee that it can be inserted on the target. The target kernel version, configuration, and symbol versions must still match.

Common issues:

  • using host kernel headers instead of target kernel headers
  • missing ARCH=arm64
  • missing or incorrect CROSS_COMPILE
  • kernel release mismatch
  • vermagic mismatch
  • missing Module.symvers when symbol versioning is enabled