Skip to content

Instantly share code, notes, and snippets.

@Zixuan-Qiao
Last active March 17, 2024 15:31
Show Gist options
  • Save Zixuan-Qiao/c0692b3bd970ddd1858235bf2ad003ae to your computer and use it in GitHub Desktop.
Save Zixuan-Qiao/c0692b3bd970ddd1858235bf2ad003ae to your computer and use it in GitHub Desktop.
Summary on how to setup cross compilation environment for Beaglebone Black

BeagleBone Black - Setting Up Cross Compilation Environment

Having a cross compilation environment on the host PC can bring great convenience to the development of kernel modules. In the process, there are a lot of things that require attention. The process I followed is documented here for future reference.

Necessities for Cross Compiling Out-of-tree Modules

The building of out-of-tree modules depends on many files (configs, kernel Makefile, headers, /scripts directory etc.) from the kernel. They can be obtained by downloading and building a kernel or installing the headers directly. The first approach is introduced here. Note that a full kernel build is not necessary, since the kernel image itself is not required.

To make the setup capable of cross compilation, the kernel source code, configuration and compiler need to match those of the target device.

Required Hardware

Beaglebone Black, PC running on Linux system (Ubuntu ver 20.04)

Serial to USB cable, USB type A to mini B cable

Getting the Required Information

On the board, find out the version of the kernel image and the compiler used to build it with:

cat /proc/version

My kernel version was linux 5.10.168-ti-r71 and compiler version was gcc 10.2.1 (Debian).

Installing the Cross Compiler

The closest compiler I could get was arm-linux-gnueabihf-gcc 10.5.0 (Ubuntu), which can be installed by:

sudo apt-get update
sudo apt-get install gcc-10-arm-linux-gnueabihf

Check if it is the default cross compiler:

which arm-linux-gnueabihf-gcc
arm-linux-gnueabihf-gcc --version

If it is not, find its location by running:

ls -al /usr/bin | grep gcc

Configure it as the default cross compiler with update-alternatives, which can handle the coexistence of multiple different versions of the same package:

sudo update-alternatives --install /usr/bin/arm-linux-gnueabihf-gcc arm-linux-gnueabihf-gcc /usr/bin/arm-linux-gnueabihf-gcc-10 60

Building the Kernel

On the host, create a directory for the kernel source. Since this kernel source is not intended for the host, it is suggested to put it under /home/user:

mkdir /path/to/kernel

Initialize the directory with:

git init

Download the kernel source with:

git clone https://github.com/beagleboard/linux.git

Switch to the required version:

git checkout $version-of-your-kernel$

Check under the /arch/arm/config directory of the kernel source, there should be a bb.org_defconfig file. Copy it to the main directory to act as the .config file with:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- bb.org_defconfig

Check the default configuration with:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- menuconfig

I did not make any modification to it.

Run the following to prepare the source for module compilation:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- modules_prepare

It only took a few seconds on my host, which was much faster than building a whole kernel.

Testing the Setup by Cross Compiling a Module

Write a simple module in hello_module.c:

#include <linux/module.h>
#include <linux/init.h>

static int __init hello_module_init(void) {
  printk("Hello!\n");
  return 0;
}

static void __exit hello_module_exit(void) {
  printk("Byebye!\n");
}

module_init(hello_module_init);
module_exit(hello_module_exit);

MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Testing kernel source for cross compilation");

Compose a Makefile:

KERN_DIR := /path/to/kernel/linux
PWD := $(shell pwd)

obj-m := hello_module.o

ARCH=arm
CROSS_COMPILE=arm-linux-gnueabihf-

all:
  make $(ARCH) $(CROSS_COMPILE) -C $(KERN_DIR) M=$(PWD) modules
  
clean:
  make $(ARCH) $(CROSS_COMPILE) -C $(KERN_DIR) M=$(PWD) clean 

Run make to compile the module:

make

The result should contain a hello_module.ko file. Move it the NFS shared directory. Setting up NFS is introduced in https://gist.github.com/Zixuan-Qiao/20fa82699fb0e01119b79eeaee56d3a3. On your board, load the module with:

sudo insmod hello_module.ko

Run the following to varify if it is loaded successfully:

lsmod | grep hello

Check the printk message with:

sudo dmesg

Unload it with:

sudo rmmod hello_module

References

  1. https://www.modbus.pl/bbb/cross-compile-kernel-for-beaglebone-black/
  2. https://stackoverflow.com/questions/70707519/how-can-i-prepare-a-linux-source-tree-so-an-external-module-can-be-compiled-agai
  3. http://charette.no-ip.com:81/programming/2011-12-24_GCCv47/
  4. https://askubuntu.com/questions/1152383/how-to-switch-the-version-of-arm-linux-gnueabihf-gcc
  5. https://stackoverflow.com/questions/25572395/cross-compiling-a-kernel-module-arm
  6. https://unix.stackexchange.com/questions/202910/how-to-check-a-kernel-version-which-was-used-when-building-package
  7. https://packages.debian.org/bullseye/gcc-10-arm-linux-gnueabihf
  8. https://askubuntu.com/questions/1412122/how-to-install-debian-package-in-ubuntu
  9. https://lwn.net/Articles/81398/
  10. https://unix.stackexchange.com/questions/213947/some-questions-regarding-linux-kernel-external-module-build-process
  11. https://www.kernel.org/doc/Documentation/kbuild/modules.txt
  12. http://derekmolloy.ie/writing-a-linux-kernel-module-part-1-introduction/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment