Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save Algorithm0/d2bd2f69ec863e9fe372888278eb0221 to your computer and use it in GitHub Desktop.
Save Algorithm0/d2bd2f69ec863e9fe372888278eb0221 to your computer and use it in GitHub Desktop.
Build Debian OS for the Raspberry Pi using Debootstrap

Introduction

The objective of these instructions is to create a complete Arm64 OS using Debian Debootstrap and RPI-Update for use on the Raspberry Pi 5.

Prerequisites:

  • An existing Debian/Raspbian/Fedora/Ubuntu system (any architecture will do) - host
  • An empty SD/USB/NVME formatted as per a standard Raspbian installation mounted to /mnt/sd on the build system
    • 1st Partition 0-512MB = FAT32 (Mount to /mnt/sd/boot/firmware)
    • 2nd Partition 512MB+ = EXT4 (Mount to /mnt/sd)

My way of getting sections

  1. Install the system (for example, Pi OS 64 Lite) on your disk using Raspberry Pi Imager;
  2. Wait until the installation is complete;
  3. Expand the root system to cover all unoccupied space (Substitute the name of your partition for the entry where you wrote the system in the previous step)
sudo e2fsck -f /dev/sda2
sudo growpart -v /dev/sda 2
sudo resize2fs /dev/sda2
  1. Create a mount point
sudo mkdir -p /mnt/sd
  1. Now we will clean the entire installed system and mount it correctly
sudo mount /dev/sda1 /mnt/sd/
sudo rm -rf /mnt/sd/*
sudo umount /mnt/sd/
sudo mount /dev/sda2 /mnt/sd
sudo rm -rf /mnt/sd/*
sudo mkdir -p /mnt/sd/boot/firmware
sudo mount /dev/sda1 /mnt/sd/boot/firmware/

Set-up basic Debian system

The utility used by the Debian installer, and recognized as the official way to install a Debian base system, is debootstrap. We will also need QEMU if we are building an Arm64 system on another host architecture (x64 or ArmHF most likely)

So lets install them.

sudo apt install debootstrap qemu-system

Now lets tell debootstrap to set-up a base Debian Arm64 installation on our SD card. This may take a while and will download an entire basic Debian system.

sudo debootstrap --arch arm64 bookworm /mnt/sd http://ftp.ru.debian.org/debian/

Before we can do anything with our new system we have to make it accessible from our hosts architecture, we do this using QEMU.

sudo cp /usr/bin/qemu-aarch64-static /mnt/sd/usr/bin

Now we have a basic Debian system we can chroot into and start setting up.

sudo mount -t proc /proc /mnt/sd/proc/ && sudo mount -t sysfs /sys /mnt/sd/sys/ && sudo mount -o bind /dev /mnt/sd/dev/
sudo chroot /mnt/sd /bin/bash

Configure your new system

Set-up APT

Now we are chrooted into our new Debian system there are a few things we need to configure to make it useable. Lets deal with "apt" first so we can install new packages.

To set-up "apt" we need to tell it which sources to use, I'll use the UK Debian mirror in this example.

apt install ca-certificates ntp ssh sudo wget xz-utils -y
editor /etc/apt/sources.list
deb https://mirror.yandex.ru/debian bookworm main non-free-firmware non-free
deb https://mirror.yandex.ru/debian bookworm-updates main non-free-firmware non-free
deb https://mirror.yandex.ru/debian-security bookworm-security main non-free-firmware non-free
# Backports are _not_ enabled by default.
# Enable them by uncommenting the following line:
# deb https://mirror.yandex.ru/debian bookworm-backports main non-free-firmware

To minimise the number of packages that apt installs you can also disable the automatic installation of Recommended packages

editor /etc/apt/apt.conf.d/99_norecommends
APT::Install-Recommends "false";
APT::AutoRemove::RecommendsImportant "false";
APT::AutoRemove::SuggestsImportant "false";

Once that file is saved we can update the apt repositories and make sure everything is updated.

apt update
apt upgrade

Configure Basic System Settings

Now we can set-up some other basic system settings.

Timezone

Select your Timezone.

dpkg-reconfigure tzdata

Locales

Select your language and input settings.

apt install locales
dpkg-reconfigure locales

SSH Server

Select your language and input settings.

apt install openssh-server

Networking

Basic Setup

Don't trust manual setup. Just install NetworkManager.

apt install network-manager

Setup your hostname (Example using Pi-Example)

echo 'rpi5' > /etc/hostname

Set-up your hosts file (including IPV4 and IPV6)

echo \
'127.0.0.1       localhost
::1             localhost ip6-localhost ip6-loopback
ff02::1         ip6-allnodes
ff02::2         ip6-allrouters
127.0.0.1       rpi5' \
> /etc/hosts

Drive Mounts (Fstab)

We need to execute some commands on the host. But don't rush to close the current console, just open another window/tab.

lsblk -o name,mountpoint,size,uuid,partuuid

Find your sections. We'll need some data from here. You should get something like this:

NAME        MOUNTPOINT              SIZE UUID                                 PARTUUID
sda                               238,5G                                      
├─sda1      /mnt/sd/boot/firmware   512M 4EF5-6F55                            8a438930-01
└─sda2      /mnt/sd                 238G ce208fd3-38a8-424a-87a2-cd44114eb820 8a438930-02

Set-up your basic drive mounts for / & /boot

editor /etc/fstab

This example assumes a standard Raspberry Pi SD card set-up. Replace UUID's with your values

UUID=ce208fd3-38a8-424a-87a2-cd44114eb820      /               ext4    rw                0       1
UUID=4EF5-6F55                                 /boot/firmware  vfat    rw                0       2

Install Additional Basic Packages

These are additional packages you may expect to find on a basic (Commandline) Debian system on the Raspberry Pi

apt install aptitude ca-certificates crda fake-hwclock firmware-brcm80211 gnupg man-db manpages net-tools ntp usb-modeswitch ssh sudo wget xz-utils

Install additional packages if you want to use a GUI and RDP (lxqt as an example)

apt install xorg xorgxrdp xrdp lxqt lightdm

Install mesa drivers to enable 3D acceleration (Note: I'm unsure of which specific packages are required but this should cover all bases)

apt install libegl-mesa0 libgbm1 libgl1-mesa-dev libgl1-mesa-dri libglapi-mesa libglx-mesa0 libosmesa6  mesa-opencl-icd mesa-va-drivers mesa-vdpau-drivers mesa-vulkan-drivers mesa-utils

Set-up user account

Creating a new user account

Standard Raspbian has the "pi" user so I'll use that as an example.

Create a user called "pi" that uses the "bash" shell, who has a home directory of "/home/pi" and is a member of the same groups as in a standard Raspbian install.

groupadd spi && groupadd i2c && groupadd gpio && groupadd docker
useradd -s /bin/bash -m -G sudo,video,adm,dialout,cdrom,audio,plugdev,games,users,input,netdev,spi,i2c,gpio,docker pi

Set the users password

passwd pi

Install the Kernel and Userland Firmware

Install rpi-update script

echo 'FIRMWARE_RELEASE_STATUS="default"' > /etc/default/rpi-eeprom-update
cd /usr/local/bin
wget https://raw.githubusercontent.com/raspberrypi/rpi-update/master/rpi-update
chmod +x rpi-update

Install dependencies

apt install curl binutils cmake git build-essential

Install Kernel

WANT_64BIT=1 WANT_PI5=1 rpi-update

Configure Kernel

Set-up cmdline.txt. Replace the PARTUUID with the one you got through the lsblk for the main (large) disk.

echo 'console=tty0 console=ttyS1,115200 root=PARTUUID=8a438930-02 rw fsck.repair=yes net.ifnames=0  rootwait  systemd.unified_cgroup_hierarchy=false' > /boot/firmware/cmdline.txt

Set-up config.txt

editor /boot/firmware/config.txt
# For more options and information see
# http://rptl.io/configtxt
# Some settings may impact device functionality. See link above for details

# Uncomment some or all of these to enable the optional hardware interfaces
#dtparam=i2c_arm=on
#dtparam=i2s=on
#dtparam=spi=on

# Enable audio (loads snd_bcm2835)
dtparam=audio=on

# Additional overlays and parameters are documented
# /boot/firmware/overlays/README

# Automatically load overlays for detected cameras
camera_auto_detect=1

# Automatically load overlays for detected DSI displays
display_auto_detect=1

# Automatically load initramfs files, if found
auto_initramfs=1

# Enable DRM VC4 V3D driver
dtoverlay=vc4-kms-v3d
max_framebuffers=2

# Don't have the firmware create an initial video= setting in cmdline.txt.
# Use the kernel's default instead.
disable_fw_kms_setup=1

# Run in 64-bit mode
arm_64bit=1

# Disable compensation for displays with overscan
disable_overscan=1

# Run as fast as firmware / board allows
arm_boost=1

[cm4]
# Enable host mode on the 2711 built-in XHCI USB controller.
# This line should be removed if the legacy DWC2 controller is required
# (e.g. for USB device mode) or if USB support is not required.
otg_mode=1

[all]
usb_max_current_enable=1

Finally

If there is anything else you wish to configure such as SSH keys (Note SSH is enabled in this build but not configured), this can be done in the chroot environment you have been working.

Once complete you should be able to exit the chroot environment and unmount your new SD card.

exit
sudo umount /mnt/sd/*
sudo umount /mnt/sd

Your 64-bit Debian Bookworm is now ready for use, Just insert the card into your PI and power on.

Run on live system

All the following steps are not so important, but I personally do them.

Update kernel and bootloader

Last time the system missed the bootloader update, but now we will fix it. Log in to the Raspberry Pi (from ssh - variant) itself. Use superuser.

sudo su
apt install pciutils
rm /boot/firmware/.firmware_revision /boot/firmware/.bootloader_revision
WANT_64BIT=1 WANT_PI5=1 rpi-update
reboot

Generate initrd

sudo su
apt install initramfs-tools
modprobe configs
zcat /proc/config.gz > /boot/config-$(uname -r)
update-initramfs -c -k $(uname -r)

DNS

Run and find your connection

nmcli con show

In the following commands, use your connection name instead of NAME

sudo nmcli con mod "NAME" ipv4.ignore-auto-dns yes
sudo nmcli con mod "NAME" ipv6.ignore-auto-dns yes
sudo nmcli con mod "NAME" ipv4.dns "8.8.8.8 8.8.4.4"
sudo nmcli con mod "NAME" ipv6.dns "2001:4860:4860::8888 2001:4860:4860::8844"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment