Debian Buster arm64 on a Raspberry Pi 3 Model B+

Early last week, I ordered a Raspberry Pi 3 Model B+ off of Amazon. At a first glance, this new model released in March 2018 comes with a slightly higher clock speed, as well as upgraded Ethernet, Wi-Fi, and Bluetooth capabilities over its immediate predecessor.

(RPi kit:

I decided I wanted to install Debian on my Pi and use it as a potential ARM build box. Although it’s not as supported as the official Raspbian release, this custom build did offer the ability to track the rolling release Debian testing (useful for development) and run a 64-bit system.


  • ARM64 support like all the latest smartphones (Raspbian uses 32 bit mode exclusively)
  • Tracking the latest code in Debian testing (currently buster)
  • A very lean base (a < 2GB disk image!) to start with


  • No support – every guide and support form assumes you’re using Raspbian and not Debian
  • No support – every support answer for firmware-related issues asks you to run rpi-update (what’s that?)
  • A very lean base to start with (where are my drivers?!)

Part 1 – Making the boot image

I based my setup off of the unofficial Debian image for the Raspberry Pi 3 over at Because this image targets the original Pi 3 and not the Model B+, some additional tweaks are needed to get the system working. After extracting the image to my SD card and expanding the root partition via GParted, here’s roughly the preparations I made:

Copying in new firmware

The first problem was an outdated firmware version – this can be fixed by copying newer versions (start*.elf fixup*.dat bootcode.bin bcm2710-rpi-3-b-plus.dtb) from the Raspberry Pi firmware repository into the boot partition of the SD card. Then, set device-tree in config.txt to use that .dtb: i.e. device_tree=bcm2710-rpi-3-b-plus.dtb

Building a custom kernel

The 4.14 kernel shipped in the Debian image unfortunately lacks support for Ethernet – complete support for the LAN7515 chip used by the Model 3 B+ only landed in kernel 4.18, which is currently in RC.

This essentially leaves two kernel options for the RPi: a mainline 4.18 kernel or the official Raspberry Pi kernel built for arm64. In my case, I actually started out with a 4.18 kernel before switching to the RPi fork, since there are a few components (e.g. a cpufreq driver) that haven’t been upstreamed yet. Both of these options involve a bit of kernel compiling, since Linux 4.18 was not in Debian as of writing.

To cross compile an ARM64 kernel from my AMD64 Debian machine, you will need to install gcc-aarch64-linux-gnu and build-essential (though this is not a complete list as other build-deps may have already been on my machine).

Option 1: Mainline kernel (4.18+)

After extracting or checking out the mainline kernel, use the arm64 default config:

cp arch/arm64/configs/defconfig .config

Unlike with 32 bit ARM, there is only one generic default config for ARM64 encompassing a variety of devices.

Note: if you use a mainline kernel, make sure to use the device tree blob shipped in mainline Linux (arch/arm64/boot/dts/broadcom/bcm2837-rpi-3-b-plus.dtb) instead of the one in the raspberrypi/firmware repo (bcm2710-rpi-3-b-plus.dtb). Otherwise, you may get stuck at the rainbow boot screen!

The compile+install process is similar to that of the RPi kernel (see below).

Option 2: Raspberry Pi kernel (4.14 LTS)

Although Raspbian does not use it, the Raspberry Pi kernel itself has supported 64-bit mode for quite some time. After checking out the sources:

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcmrpi3_defconfig

will configure a kernel build for the RPi 3.

Compilation and installation

First, mount the two SD card partitions on your machine; in this example, I used /mnt/boot for the first (boot) partition and /mnt/ext4 for the second (root) partition.

# Build
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-

# Install
sudo make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/mnt/ext4 modules_install
# You can replace kernel.img with a more descriptive name:
# e.g. I used something like raspberrypi-kernel_1.20180417-1_arm64.img
# for the RPi kernel
sudo cp arch/arm64/boot/Image /mnt/boot/kernel.img
sudo cp arch/arm64/boot/dts/broadcom/*.dtb /mnt/boot/

# For the RPi kernel, also install the following:
sudo cp arch/arm64/boot/dts/overlays/*.dtb* /mnt/boot/overlays/
sudo cp arch/arm64/boot/dts/overlays/README /mnt/boot/overlays/

Now, edit your config.txt to point to your new kernel (and keep a backup of it in case it gets overwritten!)

Part 2: Making things work

At this point, I could boot into what might be one of the world’s largest terminalsUSB, HDMI video, and Ethernet just about worked out of the box, though I had a minor issue with the default firewall provided in the Debian image (the -m comment module for iptables didn’t autoload with my custom kernel).

Because I was running a custom kernel at this point, I had to purge Debian’s raspi3-firmware since it automatically updates / overwrites config.txt to point to the Debian kernel on updates. Once Linux 4.18+ makes its way into Debian, this should no longer be necessary. (I also elected to remove the Debian kernel image since it wasn’t being used)

What didn’t work out of the box, but could be easily fixed

  • HDMI audio: required adding dtparams=audio=on to config.txt
  • Wi-Fi: need to copy brcmfmac43455-sdio.txt (an NVRAM config file) from the RPi-Distro/firmware-nonfree repository into /lib/firmware/brcm/, since Debian does not ship it in its firmware-brcm80211 package. (Raspbian’s fork of the package does though!)
  • Xorg: I had issues with Xorg only showing a cursor on startx and crashing a few seconds later. dmesg showed me errors like “vc4: Failed to allocate from CMA”, which I fixed by adding cma=256M to cmdline.txt

Now I have a Pi running Debian in working condition! 🍥🎉

Anything not mentioned in this article (Bluetooth, GPIO, etc.) has not been tested yet.


    1. Hi Ken,
      Unfortunately, I don’t have the time or spare hardware to properly test+maintain an unofficial image. Hopefully the instructions above suffice for making a bootable image – i.e. start with the Debian image and modify it from a card reader before sticking it into the Pi.

      I can’t dump my SD card in its current state either because it already has my setup and details on it.


    1. Right now I’m using a custom build of the RPi kernel fork, but I think it should work OK with a mainline kernel too. (The brcmfmac driver is in mainline)

      1. I thought so too, but it doesn’t.
        Right now I think it’s a problem with the mainline bcm2837-rpi-3-b-plus.dtb.

        I was just asking whether you had more luck with a vanilla kernel than I did.

        1. Sorry for the late response – apparently I had misconfigured email on my server, so I wasn’t getting any notifications for new comments.

          I’ll admit that I didn’t test this point very thoroughly. I had assumed that having the Wi-Fi device show up in ‘ip link’ meant that it would work, but in hindsight I realize that is really not the right way to think. In short I did not test Wi-Fi completely on a mainline kernel past having the device show up – my fault for not being clearer on this.

  1. Hi, I was trying to use kernel 4.19 as it will be LTS.

    The steps I fiollowed:
    Download and dd unofficial image for RasPI3:
    $ wget
    $ xzcat 2018-01-08-raspberry-pi-3-buster-PREVIEW.img.xz | dd of=/dev/sdb bs=64k oflag=dsync status=progress

    Overwrite the files: ‘start*.elf’ ‘fixup*.dat’ ‘bootcode.bin’

    Download ‘linux-4.19.2.tar.xz’, and extract it.

    Install build dependencies:
    # apt-get install gcc-aarch64-linux-gnu build-essential

    Copy default config:
    $ cp arch/arm64/configs/defconfig .config

    $ make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
    Makefile:595: include/config/auto.conf: No such file or directory
    HOSTCC scripts/basic/fixdep
    HOSTCC scripts/kconfig/conf.o
    YACC scripts/kconfig/
    /bin/sh: 1: bison: not found
    scripts/Makefile.lib:196: recipe for target ‘scripts/kconfig/’ failed
    make[2]: *** [scripts/kconfig/] Error 127
    Makefile:539: recipe for target ‘syncconfig’ failed
    make[1]: *** [syncconfig] Error 2
    Makefile:635: recipe for target ‘include/config/auto.conf’ failed
    make: *** [include/config/auto.conf] Error 2

    Do you know what I did wrong?

Leave a Reply

Your email address will not be published. Required fields are marked *