Slackware ARM64 AArch64 on a Raspberry Pi


SARPi64 Project - Build a 64-bit ARM64 AArch64 kernel & modules for the Raspberry Pi

In order to build a 64-bit kernel and modules on Slackware ARM you will need to have:

• A 32/64Gb microSD card with Slackware ARM -current installed [and fully up-to-date] on a Raspberry Pi 3 or 4.

• Completed the "HOW TO build a gcc-9.1.x aarch64-linux cross-compiler on Slackware Arm for the Raspberry Pi" process, with a 64-bit gcc cross-compiler installed on your system.

We will be using a Raspberry Pi 4 Model B [4GB] in this guide with a minimum install of Slackware ARM -current, in order to have as much available free disk space as possible on our 32Gb microSD card. You may have an external HDD/SDD mounted but we're not going to do that here as it's not required for a single kernel/modules build on this size of microSD card.

NB: You will certainly struggle with free disk space if you're using using a 16Gb microSD card. In which case, an external storage device [i.e. USB HDD/SDD] will be prudent, and necessary.

* This procedure may be possible to perform on Slackware ARM 14.2 soft-float port but has not been attempted.

Preparation

In order to compile binary files from source code for AArch64 architecture you'll need to set the PATH to your gcc cross-compiler 'bin' directory as the first item in your $PATH. If you have followed the "HOW TO build a gcc-9.1.x aarch64-linux cross-compiler on Slackware Arm for the Raspberry Pi" guide and have installed it in the default location [i.e. /tmp/.gcc-cross/] you can export the gcc cross-compiler PATH to to your $PATH like this:

root@slackbox:~# export PATH=/tmp/.gcc-cross/bin:$PATH

Now if you type 'echo $PATH' it will show you the full $PATH with the PATH to your gcc cross-compiler at the beginning.

root@slackbox:~# echo $PATH
/tmp/.gcc-cross/bin:/usr/local/sbin:/usr/sbin:/sbin:/usr/local/bin:/usr/bin:/bin:/usr/games:/usr/lib/qt/bin
root@slackbox:~#

The above is what you're trying to achieve. The PATH to the gcc cross-compiler 'bin' directory [/tmp/.gcc-cross/bin] is first in the $PATH. If you have installed the gcc cross-compiler in another location then the $PATH should display that instead.

Now create a 'BUILD' directory in which to work. We usually work from the /tmp directory so that's where we'll put our 'BUILD' directory and then 'cd' to it. We're going to create '/tmp/build-dir' and use it for our 'BUILD' directory.

root@slackbox:~# mkdir -p /tmp/build-dir
root@slackbox:~# cd /tmp/build-dir
root@slackbox:/tmp/build-dir#

Downloading the Linux kernel source

Download the Linux kernel source, from the Raspberry Pi Foundation GitHub repository, using the 'git' command. There's no need to download the entire Linux repository content. We're going to build with kernel 4.19.x ['x' = subversion] so the branch we will download is 'rpi-4.19.y'. You'll only download the kernel branch which you've specified if you use the following command, substituting 'rpi-4.19.y' for your own choice.

root@slackbox:/tmp/build-dir# git clone --depth=1 --single-branch -b rpi-4.19.y http://github.com/raspberrypi/linux.git linux

The above command will 'clone' the RPi GitHub Linux kernel 'rpi-4.19.y' branch to our '/tmp/build-dir/linux' directory. The folder in which to store the downloaded data is specified last in the command.

Remember, we have selected kernel branch 'rpi-4.19.y'. You don't have to use the same branch. To view a list of available RPi GitHub branches use this command:

root@slackbox:/tmp/build-dir/linux# git branch -a

If you already have downloaded the RPi GitHub Linux kernel source and only need to update it, you can do so easily from within the Linux source directory using the following commands.

root@slackbox:/tmp/build-dir# cd /tmp/build-dir/linux
root@slackbox:/tmp/build-dir/linux# git checkout -f rpi-4.19.y
root@slackbox:/tmp/build-dir/linux# git fetch --all
root@slackbox:/tmp/build-dir/linux# git reset
root@slackbox:/tmp/build-dir/linux# git pull http://github.com/raspberrypi/linux.git
root@slackbox:/tmp/build-dir/linux#

Preparing the system to build a 64-bit kernel

There's a few steps to perform in order to prepare the system to compile the Linux source code, and for AArch64 architecture.

First 'cd' to the linux source directory if you're not already there.

root@slackbox:~# cd /tmp/build-dir/linux

Create a default kernel .config file for the Raspberry Pi 4. This is a list of settings which the kernel will be configured from during the build process. Take note that you are inserting build -options into the command to instruct 'gcc' to compile the source code for a specified architecture. In this case these build -options are 'ARCH=arm64 CROSS_COMPILE=aarch64-linux-'. So go ahead and type the following command:

root@slackbox:/tmp/build-dir/linux# make ARCH=arm64 CROSS_COMPILE=aarch64-linux- bcm2711_defconfig

NB: For the Raspberry Pi 3 the default config is 'bcm2709_defconfig'.

Also note the trailing hyphen of 'CROSS_COMPILE=aarch64-linux-' which is NOT a typo and needs to be EXACTLY like that!

You need to make a backup of the new .config file, because you are going to edit this file before you compile the kernel. There are some settings within this .config file for VideoCore VI which are not compatible with 64-bit architecture and needs to be disabled. Make a backup of the .config file by copying it to the 'build-dir' directory:

root@slackbox:/tmp/build-dir/linux# cp -av .config /tmp/build-dir/config.bak

Editing the kernel .config file

Within the kernel .config file there are three (3) settings which much be disabled in order for the build process to be successful. You can achieve this with vi, vim, nano, or any other text editor available. The settings in question are listed below and this is how they will appear in the file.

CONFIG_VIDEO_BCM2835=m
CONFIG_BCM2835_VCHIQ_MMAL=m
CONFIG_BCM_VC_SM_CMA=m

You need to change these settings so they appear like this:

# CONFIG_VIDEO_BCM2835 is not set
# CONFIG_BCM2835_VCHIQ_MMAL is not set
# CONFIG_BCM_VC_SM_CMA is not set

Once you have edited the settings to match what's shown above, save the file.

You can also achieve this by using 'sed' if a text editor is not available, with the following commands:

sed -Ei 's/^CONFIG_VIDEO_BCM2835=.*/# CONFIG_VIDEO_BCM2835 is not set/' /tmp/build-dir/linux/.config
sed -Ei 's/^CONFIG_BCM2835_VCHIQ_MMAL=.*/# CONFIG_BCM2835_VCHIQ_MMAL is not set/' /tmp/build-dir/linux/.config
sed -Ei 's/^CONFIG_BCM_VC_SM_CMA=.*/# CONFIG_BCM_VC_SM_CMA is not set/' /tmp/build-dir/linux/.config

You do not have to edit the .config file. If you'd prefer to use 'make menuconfig' to disable the above then that works too.

IMPORTANT! DO NOT modify ANYTHING ELSE in the kernel .config file unless you know what you're doing! It's safe to disable the three (3) settings shown. That's all you need to do and nothing more!

NB: A great number of Linux users will rebuke you for editing the kernel .config file directly! It's generally considered unsafe [and rightly so] to edit the kernel .config because there are a multitude of CONFIG -options that are dependent on other -options and if they aren't all present and correct, or don't correlate, then success will not be in your favour. As an alternative to editing the kernel .config directly, if you'd rather use 'make menuconfig' which is a much safer way to modify these settings then that's your prerogative.

Building a 64-bit kernel

Ordiniarily 'gcc' will compile based on the current system architecture. You can easily check and verify your own system's architecture with the 'echo $MACHTYPE' command. However, we're going to instruct 'gcc' to build different from our current system architecure because right now we're running Slackware ARM -current [32-bit] and we need to build for AArch64 [64-bit]. We will do this using exactly same build -options as before, only this time you're going to add '-j4' into the command to build the kernel. This '-j4' is a setting called "multijobs" and it's basically saying to the system 'do a maximum of 4 different jobs simultaneously'. It makes the time it takes to compile much quicker on the Raspberry Pi 4.

When building the kernel, you'll use the same build options as before. You can even set a 'LOCALVERSION' here which appends whatever you set to the end of the kernel version (e.g. LOCALVERSION=“-aarch64” would eventually give you 4.19.x-v8-aarch64) once the kernel and modules have been built [NB: where the 'x' in the kernel subversion is the current kernel you're compiling - e.g. '4.19.63-v8']. Type the following command to start compiling a 64-bit kernel:

root@slackbox:/tmp/build-dir/linux# make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux- Image

So, here you 'make' the kernel which will be saved with the name 'Image'. The rest you should be familiar with. This process will take a while.

Building the 64-bit device tree blob(s)

Device tree is a means of describing hardware which is read by the kernel at boot time to tell it what hardware exists on the system. In our case it relates to the Raspberry Pi 4 and is the method by which the systems knows which drivers to load for the hardware. On ARM-based devices the use of device trees has become mandatory for all new SOCs, including the Raspberry Pi devices.

To build the Raspberry Pi device tree blob(s) run the following command:

root@slackbox:/tmp/build-dir/linux# make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux- dtbs

It's basically the same as you did to build the kernel, only where 'Image' is substituted for 'dtbs'.

Building the 64-bit kernel modules

To build the kernel modules you do it in much the same way as before. Run the following command:

root@slackbox:/tmp/build-dir/linux# make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux- modules

Notice how each time the command is the same except when specifying what you're building. If you have set a 'LOCALVERSION' then it must be kept the same for building the kernel and modules. This process will probably take a while longer than building the 64-bit kernel.

Once the modules have been built, you have to 'make modules_install' in order to install them. The process will install your kernel modules to '/lib/modules/4.19.x-v8-aarch64' [were 'x' is the sublevel of the kernel version]. You could build out-of-tree kernel modules but, to keep things simple, you're going to install them to the usual location. Again, you will use the same build options as before but without any 'LOCALVERSION' set.

To install the aarch64 kernel modules run the following command:

root@slackbox:/tmp/build-dir/linux# make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux- modules_install

After installing the kernel modules has completed, that signals the end of the build process.

Copying the arm64 kernel, modules, and device tree blobs (DTB)

Connect the (spare) microSD card containing a working Slackware ARM current system to your Raspberry Pi 4 using a USB microSD card reader. You'll need to mount the partitions first, before copying the arm64 kernel, modules, and device tree blob(s) onto it.

Use the 'fdisk' command to determine the device name of your (spare) microSD card:

root@slackbox:/tmp/build-dir/linux# fdisk -l

Your (spare) microSD card will most likely be '/dev/sda' or '/dev/sdb'. Ours is '/dev/sda'. So, we will mount the boot and root partitions in order to copy over the new files. We'll do this in the '/tmp' directory. Like this:

root@slackbox:/tmp/build-dir/linux# cd /tmp
root@slackbox:/tmp# mkdir rpi-boot
root@slackbox:/tmp# mkdir rpi-root
root@slackbox:/tmp# mount /dev/sda1 rpi-boot
root@slackbox:/tmp# mount /dev/sda3 rpi-root

The above has mounted the boot [/dev/sda1] and root [/dev/sda3] partitions on our system and they can now be accessed just like any other directory.

The next thing to do is copy the arm64 kernel, modules, and device tree blobs to your newly mounted directories. It's important to get this right. After all the hard work you've done it would be a shame to mess it up at this stage. To copy these files, run the following commands:

root@slackbox:/tmp# cp build-dir/linux/arch/arm64/boot/Image rpi-boot/boot/kernel8.img
root@slackbox:/tmp# cp build-dir/linux/arch/arm64/boot/dts/broadcom/bcm*.dtb rpi-boot/boot
root@slackbox:/tmp# cp -rv /lib/modules/4.19.x-v8* rpi-root/lib/modules/

NB: Where the 'x' in the kernel subversion is the current kernel you're compiling. [e.g. '4.19.63-v8']

Once you have done that, check that the files you have copied are present and in the right place using the 'ls' command.

root@slackbox:/tmp# ls -lah rpi-boot/boot/kernel*
root@slackbox:/tmp# ls -lah rpi-boot/boot/bcm*-rpi-4-b.dtb
root@slackbox:/tmp# ls -lah rpi-root/lib/modules/4.19.x-v8*

If all the files are correct then the next thing you need to do is delete the previous kernel in the rpi-boot/boot directory. This old kernel is named 'kernel7.img' and to avoid any conflicts with the new 64-bit 'kernel8.img' you should remove it.

root@slackbox:/tmp# rm -rf rpi-boot/kernel7.img

Now you can unmount the boot and root partitions.

root@slackbox:/tmp# umount rpi-boot
root@slackbox:/tmp# umount rpi-root

Power off your Raspberry Pi.

root@slackbox:/tmp# poweroff

Remove the USB microSD card reader and swap microSD cards. Power on the Raspberry Pi and boot the microSD card on which you copied the arm64 kernel, modules, and device tree blobs.

You should now be booting into Slackware ARM -current with a 64-bit kernel. Well done!

Support for Slackware ARM

If you're in need of help, or have something to contribute, one of the best places to get (and offer) support for Slackware ARM is on the Linux Questions Forum. Another valuable resource is the Slackware Documentation Project.

Updated: 04 Aug 2019 16:08:54