Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save ampaze/bd0b57a1848f4b46b91d9e799375f1bb to your computer and use it in GitHub Desktop.
Save ampaze/bd0b57a1848f4b46b91d9e799375f1bb to your computer and use it in GitHub Desktop.
How to cross compile the WireGuard® kernel module for QNAP® Arm® devices

How to cross compile the WireGuard® kernel module for QNAP® Arm® devices

Prerequisites

Information about your QNAP device

SSH into your QNAP device and run

echo Model: $(getsysinfo model)
echo Firmware: $(getcfg system version)
uname -a
cat /proc/version

This will give you information about which firmware version and kernel version the device runs on and the toolchain used to compile the kernel.

For example

NAS Model: TS-128A

Firmware: 5.0.1

Linux NAS 4.2.8 #1 SMP Thu Dec 15 02:09:07 CST 2022 aarch64 GNU/Linux

Linux version 4.2.8 (root@U16BuildServer54) (gcc version 5.3.1 20160113 (Linaro GCC 5.3-2016.02) ) #1 SMP Thu Dec 15 02:09:07 CST 2022

With this we now know, we need the toolchain Linaro GCC 5.3-2016.02 for aarch64.

Linaro Toolchains can be found at https://releases.linaro.org/components/toolchain/binaries/

In this example we are looking for 5.3-2016.02 so that gives us https://releases.linaro.org/components/toolchain/binaries/5.3-2016.02/

Looking at the Host Requirements

Linaro officially supports the current and previous Ubuntu LTS releases (as of the time of this release)

So we need the Ubuntu LTS that was current in 2016. Looking at https://wiki.ubuntu.com/Releases we see that Ubuntu 16.04 LTS might fit the bill.

Getting the host

On Windows 10/11 the easiest way is to use WSL2, for more information check https://learn.microsoft.com/en-us/windows/wsl/install-manual.

As the distribution we need is quite old, use the download link for Ubuntu 16.04 at https://learn.microsoft.com/en-us/windows/wsl/install-manual#downloading-distributions and install it. (Simply double clicking the appx file worked fine for me)

On other systems like (Linux or MacOS) Docker seems to be the best bet, starting here https://hub.docker.com/_/ubuntu/

Preparing the host

Open a shell inside the host we just installed and install make and gcc on the host.

sudo apt install make gcc 

Next we need to download three things:

  • the toolchain
  • the QNAP kernel files
  • the WireGuard® source code

As Ubuntu 16.04 is very old, SSL certificate checks when downloading files will likely not work. Thats why wget needs --no-check-certificate and git needs GIT_SSL_NO_VERIFY=true for the downloads to work.

Getting the toolchain

We already know which toolchain we need, in this example it was Linaro GCC 5.3-2016.02 for aarch64. So we download

wget --no-check-certificate https://releases.linaro.org/components/toolchain/binaries/5.3-2016.02/aarch64-linux-gnu/gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu.tar.xz

Getting QNAP kernel files

QNAP releases their kernel source files at https://sourceforge.net/projects/qosgpl/files/QNAP%20NAS%20GPL%20Source/. From there we need to find the correct or closest one for our device, in this example we need Firmware: 5.0.1.

 wget --content-disposition --no-check-certificate https://sourceforge.net/projects/qosgpl/files/QNAP%20NAS%20GPL%20Source/QTS%205.0.0/GPL_QTS-5.0.0-20211101_Kernel.tar.gz/download

Getting WireGuard® source code

GIT_SSL_NO_VERIFY=true git clone https://git.zx2c4.com/wireguard-linux-compat

Extracting the files

We need to extract the files we just downloaded

tar -xf gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu.tar.xz
tar -xf GPL_QTS-5.0.0-20211101_Kernel.tar.gz

Cross compiling aka the nitty gritty

With all files prepared we can finally cross-compile the kernel module.

Find and copy the kernel config file

The GPL_QTS folder contains the kernel config files (GPL_QTS/kernel_cfg/) for all devices and the kernel source files (GPL_QTS/src/).

In the example the device was TS-128A so we need to find it in GPL_QTS/kernel_cfg/. If you can't find it try replacing the first number with an X (TS-X28A). Next we need to copy the config file to the kernel sources files matching our kernel version (4.2.8), to configure the kernel for that device.

cp GPL_QTS/kernel_cfg/TS-X28A/linux-4.2-arm64.config GPL_QTS/src/linux-4.2/.config

Prepare the kernel

Now we use all the stuff we prepared so far to do even more preparing. In the following example you need to plug in your own toolchain and kernel source folder.

make ARCH=arm64 CROSS_COMPILE=$(pwd)/gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -C GPL_QTS/src/linux-4.2/ scripts prepare modules_prepare

Cross compile the kernel module

Again, plug in the corresponding values for your device.

make ARCH=arm64 KERNELRELEASE=4.2.8 KERNELDIR=$(pwd)/GPL_QTS/src/linux-4.2 CROSS_COMPILE=$(pwd)/gcc-linaro-5.3-2016.02-x86_64_aarch64-linux-gnu/bin/aarch64-linux-gnu- -C wireguard-linux-compat/src/

Copy the kernel module to the QNAP device

The next step depends on your preference where to put the module. You cannot put it in /lib/modules as this won't survive a reboot.

scp wireguard-linux-compat/src/wireguard.ko admin@nas:/opt/lib/wireguard.ko

In your wireguard config you can then use

[Interface]
PreUp = insmod /opt/lib/wireguard.ko || 0
PostDown = rmmod /opt/lib/wireguard.ko

WireGuard is a registered trademark of Jason A. Donenfeld.

QNAP is a registered trademark of QNAP Systems, Inc.

Arm is a registered trademark of Arm Limited (or its subsidiaries) in the US and/or elsewhere.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment