Build a 64-bit Kernel for your Raspberry Pi 3

EDIT : After writing this blog post I’ve started a 64-bit OS for the Raspberry Pi 3, based on Debian. You can find it here.

The Raspberry Pi 3 ships with a Broadcom BCM2837 64bit ARMv8 quad core Cortex A53 processor, which is a 64-bit CPU. If you own one of these, running the following command might surprise you :

> uname -a
Linux raspberrypi 4.4.34-v7+ #930 SMP Wed Nov 23 15:20:41 GMT 2016 armv7l GNU/Linux

Yes, this is a 32-bit kernel. The reason for this is that the Raspberry Pi foundation doesn’t yet provides a 64-bit version of Raspbian, the official OS for Raspberry Pi. It is however possible to build one, thanks to the various patches sent by Electron752.

Build the Kernel

The Raspberry Pi foundation maintains their own fork of the Linux Kernel which is especially tailored for their devices, while upstream gets merged regularly.

We’re going to adapt instructions from that page to build a 64-bit Kernel.

We cannot use the “Local building” method as it’d require a 64-bit Raspberry Pi, which we obviously don’t have yet. So we have to cross-compile it, Ubuntu is the recommended OS for this. I personally don’t have Ubuntu so I’ll make my build on a 2 CPUs Ubuntu 16.04 Digital Ocean droplet, which should cost me $0.03. If you also want to proceed like this, you can get $10 free credits through this link. Alternatively, you could use a Ubuntu VM through Virtualbox for instance.

First, we’d need a few build tools and the aarch64 cross-compiler :

> apt-get update
> apt-get install -y bc build-essential gcc-aarch64-linux-gnu git unzip

Then we can download the Linux Kernel sources :

> git clone –depth=1 -b rpi-4.8.y

Enter now inside the created git directory. Optionally, you can add an extra version tag for your kernel. This is done by editing the beginning of the Makefile :


In order to build it, run the following commands :

> make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcmrpi3_defconfig
> make -j 3 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

The first one should be pretty fast. For the second one it’s a whole different story, I haven’t timed it exactly but it was around 30 minutes for me. Make sure to adapt the -j flag depending on your number of CPUs (nproc * 1.5).

Choose a Linux distribution

While the Kernel is being built, we can start preparing a Linux distribution for it. I’ll be using Raspbian for simplicity in this tutorial, even though this is a 32-bit only distribution.

If you want to go 64-bit all the way you should pick up a distribution available in aarch64, Debian has a robust ARM64Port. To grab it there are basically 3 options :
– download a pre-built root filesystem, this would most likely give you an outdated one as mentioned in that page
– build your own with debootstrap if you’re familiar with it (otherwise it can be tricky as it requires some manual tweaks, the original purpose of it is to chroot from an already running host, not build a root filesystem for another machine).
– the one I’d recommend, using multistrap, there seems to be a nice tutorial on this page :

Back to Raspbian, we can now download the official OS and start preparing it.

Open a new shell session and run the following commands :

> wget -O
> unzip

We can inspect it with the following command :

> fdisk -l 2016-11-25-raspbian-jessie-lite.img
Disk 2016-11-25-raspbian-jessie-lite.img: 1.3 GiB, 1390411776 bytes, 2715648 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x244b8248

Device Boot Start End Sectors Size Id Type
2016-11-25-raspbian-jessie-lite.img1 8192 137215 129024 63M c W95 FAT32 (LBA)
2016-11-25-raspbian-jessie-lite.img2 137216 2715647 2578432 1.2G 83 Linux

We can see it has two partitions. The first one is the boot partition, it mainly contains the bootloader, the Linux Kernel and a few config files. The second one is the root partition.

We can mount those partitions on our filesystem, starting with the root partition :

> mount -o loop,offset=70254592 2016-11-25-raspbian-jessie-lite.img /mnt

The offset depends on the sector size, which is 512 : 70254592 = 512 * 137216

Then the boot partition :

> mount -o loop,offset=4194304,sizelimit=66060288 2016-11-25-raspbian-jessie-lite.img /mnt/boot

(offset : 4194304 = 512 * 8192, sizelimit: 66060288 = 512 * 129024)

The Raspbian OS can now be seen under /mnt. We’re almost there.

Wrapping it up

Once the Kernel build is finished, the last steps involve copying the Linux Kernel and the device tree to the boot partition :

> cp arch/arm64/boot/Image /mnt/boot/kernel8.img
> cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb /mnt/boot/

Tweaking config.txt :

> echo “kernel=kernel8.img” >> /mnt/boot/config.txt

Installing Kernel modules :

> make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu INSTALL_MOD_PATH=/mnt modules_install
> umount /mnt/boot
> umount /mnt

And… that’s it, a freshly baked ARM64 Linux Kernel for our Raspberry Pi 3!

You can now compress the image, download it through scp for instance and follow the standard instructions to put it on your SD card.

Eventually you’ll get :

> uname -a
Linux raspberrypi 4.8.13+bilal-v8+ #1 SMP Wed Dec 14 14:09:38 UTC 2016 aarch64 GNU/Linux

  • Sébastien Gaïde

    Hi Bilal,

    thanks a lot for this tutorial, it really helps.
    i was wondering, if i go to the ‘raspbian distro’ route as described, will it be possible to make a full 64 bits executable then ? i mean with a 64 bits libc/libc++ and all the 64 bits dependencies, i guess i will have to build/install all this, would it be possible or are we stuck to the 32 bits world ?

    in other word, to be able to compile and run 64 bits app, do i have to use the native ARM64Port distro ?

    thanks a lot,


    • Bilal

      Glad it helped.

      Indeed you’d need a bit more steps to build / run 64 bits programs on raspbian. Personally as it is more for testing purpose I’ve just downloaded a rootfs from from within the raspberry, chrooted inside, updated apt sources and installed what I need to build / run 64-bit stuff from the chroot.

      Otherwise if you want to build a 64 bit distro instead, there are a few params to remove in /boot/cmdline.txt : “quiet init=/usr/lib/raspi-config/”. This is a trick for raspbian so that the root partition is expanded on first boot, then the script edits the cmdline file and reboots, but if the rootfs is not raspbian that can give some fun debugging sessions 🙂

      I also saw recently which seems pretty neat.

  • jo hawkins

    would it be possible for you to upload the .iso?