How to create from the ground up a Debian 9 image for the Raspberry PI 3

This guide explains step by step how to create from the ground up a Debian 9 (stretch) image for the Rasperry PI 3, using Buildroot and a Linux host system (such as Fedora, Debian or Ubuntu).
Buildroot is used to create a small initramfs bootstrap image.
Althought the Debian image created is minimalist (by choice), you can then add later all the packages you want (for instance, I usually add xfce4).

If you want to skip these steps, and just use the Debian stretch aarch64 root filesystem archive I created, just jump to here.

The first step is to generate a Debian aarch64 stretch root filesystem image.

There are several methods available. I choose to use multistrap.
Since multistrap only runs on a Debian based system, and since I am using Fedora, I used Debian 9 (netinst) within VirtualBox.
Please note that a Debian based distribution is needed only for this for step of creating the Debian root fileystem.
You can use any Linux distribution for the 2nd step involving Buildroot.
If you are using a Debian based system, you might be able to use it natively without having to use a VM.

Packages to install in your Debian based distribution:
root@test-debian9:/home/osingla# sudo apt-get install multistrap qemu qemu-user-static binfmt-support dpkg-cross
We will use this multistrap configuration, which I created from the one provided under /usr/share/doc/multistrap/examples/full.conf
aarch64-debian-rootfs.conf

Basically, this configuration will create a Debian root filesystem (without the kernel and few other files):
  • Debian 9 (strech)
  • aarch64 binaries
  • With these packages installed: apt systemd init base-passwd passwd iproute2 isc-dhcp-client network-manager kmod

  • Use these steps to create a basic root filesystem:
    osingla@debian9:~$ wget https://raw.githubusercontent.com/osingla/LinuxFromScratch/gh-pages/rpi3/debian_img/aarch64-debian-rootfs.conf
    osingla@debian9:~$ multistrap -a arm64 -d debian-rootfs -f aarch64-debian-rootfs.conf
    Use these steps to configure the root filesystem (use either su or sudo):
    root@debian9:/home/osingla# cp /usr/bin/qemu-aarch64-static debian-rootfs/usr/bin/
    root@debian9:/home/osingla# mount -o bind /dev/ debian-rootfs/dev/
    root@debian9:/home/osingla# LC_ALL=C LANGUAGE=C LANG=C chroot debian-rootfs dpkg --configure -a
    When asked about using dash as default system shell (/bin/sh), say N (you want to use bash instead).

    Now setup the root password:
    root@debian9:/home/osingla# chroot debian-rootfs passwd
    Some clean up:
    root@debian9:/home/osingla# umount debian-rootfs/dev
    root@debian9:/home/osingla# rm debian-rootfs/usr/bin/qemu-aarch64-static
    Create now an archive for the Debian strech aarch64 root filesystem:
    root@debian9:/home/osingla# cd debian-rootfs
    root@debian9:/home/osingla# tar -j -c -f ../debian-rootfs.tar.bz2 .
    root@debian9:/home/osingla# cd ..

    The second step is to create an initramfs image using buildroot

    The initramfs image we will create will be able to bootstrap Debian:

  • The kernel is 4.9.x armv8 (64-bits) since the SOC used in RPI3 is a quad A53.
  • We use uCLibc, and not glibc.
  • We build only the C toolchain (no need for C++).
  • We will use a small initramfs image (no need for ssh or any additional package).
  • Since we are using later switch_root, we are NOT using any init system.
  • All system files are stored in a single fat32 partition of the uSD card (firmware, DTBs, kernel, initramfs image).
  • Download first these files (buildroot, configuration file, init script):
  • rpi3_debian_img_defconfig

  • If you choose to skip the 1st step and did not built the Debian root fileystem image yourself, you can download the aarch64 Debian stretch root filesystem archive:
  • debian-rootfs.tar.bz2

  • You can then use these steps:
    ~/lfs/rpi3/small_img$ wget https://raw.githubusercontent.com/osingla/LinuxFromScratch/gh-pages/rpi3/debian_img/rpi3_debian_img_defconfig
    ~/lfs/rpi3/small_img$ wget https://github.com/osingla/LinuxFromScratch/raw/gh-pages/rpi3/debian_img/rootfs.tar
    ~/lfs/rpi3/small_img$ wget https://raw.githubusercontent.com/osingla/LinuxFromScratch/gh-pages/rpi3/debian_img/debian-rootfs.tar.bz2
    ~/lfs/rpi3/small_img$ wget https://raw.githubusercontent.com/osingla/LinuxFromScratch/gh-pages/rpi3/debian_img/create-sdcard.sh
    ~/lfs/rpi3/small_img$ chmod a+x create-sdcard.sh
    ~/lfs/rpi3/small_img$ tar -f root.tar -x
    ~/lfs/rpi3/small_img$ wget https://buildroot.org/downloads/buildroot-2017.11.1.tar.bz2
    ~/lfs/rpi3/small_img$ tar -f buildroot-2017.11.1.tar.bz2 -x
    ~/lfs/rpi3/small_img$ cd buildroot-2017.11.1
    ~/lfs/rpi3/small_img/buildroot-2017.11$ cp ../rpi3_debian_img_defconfig configs/
    ~/lfs/rpi3/small_img/buildroot-2017.11$ make rpi3_debian_img_defconfig
    ~/lfs/rpi3/small_img/buildroot-2017.11$ make
    It might takes 20 minutes or even more to download all the packages, and build everything.
    Once the build is done, you will have the kernel, the Device Tree Blob (DTB), and the root filesystem tar file:
    ~/lfs/rpi3/debian_img/buildroot-2017.11$ tree --charset unicode -L 2 output/images/
    output/images/
    |-- bcm2710-rpi-3-b.dtb
    |-- Image
    |-- rootfs.cpio
    |-- rootfs.cpio.gz
    |-- rootfs.tar
    `-- rpi-firmware
        |-- bootcode.bin
        |-- cmdline.txt
        |-- config.txt
        |-- fixup.dat
        |-- overlays
        `-- start.elf

    2 directories, 10 files
    If you are curious, here is the init script I am using:    /sbin/init
    Now the last step is to create a uSD card. For convenience, I created a basic shell script, which:
  • create two partitions (fast32, ext4).
  • copy firmware, kernel, DTBs, initramfs image in fat32 partition.
  • copy the Debian root filesystem in the ext4 partition.
  • we also copy the kernel modules in the Debian root filesystem.

  • Before running this script, please check which device is used for the uSD card.
    In my case, it is /dev/sdg, but it might be a different value on your system.
    Use then the option --device /dev/XX


    To run the script:
    ~/lfs/rpi3/small_img$ ../create-sdcard.sh

    After you boot the uSD card

    If everything went well, you should boot Debian and be able to login (root, whatever password you choose).

    Ethernet should be up and running.
    Run the command "ip a" to verify you got an IP address.

    The first things you might want to do:
  • run apt_get update
  • install vi and ssh server: apt_get instal vim openssh-server

  • Remember that if you want to ssh the unit as root, you need to change the ssh server configuration:
  • vi /etc/ssh/sshd_config
  • PermitRootLogin yes
  • systemctl restart sshd
  • From there, you have a full Debian 9 64-bits operational on your raspberry PI 3, so the sky is the limit ;-)

    I usually install a full Desktop, such as XFCE.
    Since the default Debian use a framebuffer (no acceleration), we might want to install an X driver specifically done for the RPI3.
    Time permitting, I'd describe how to do this...