In diesen Beitrag möchte ich zeigen wie man ein SD-Card Image für den Raspberry Pi 4 erstellt und zwar von Grund auf. Warum die Mühe und kein fertiges Raspbian ? Nun ich wollte gerne ein 64 bit System mit 64 bit Kernel und bassierend auf dem Debian Repository von Buster, damit ich zeitnah aktuelle Sicherheitsupdates bekomme. Das ist z.B. relevant, wenn man den Raspberry als Gateway oder auch für andere Dienste im Netz nutzen möchte.

Weitere Anleitungen in Bezug auf diesen Beitrag: Zum einem wie man den Mesa 3d Treiber kompiliert und so mit Hardwarebeschleunigung auf den Desktop des neuen Raspberry 4 64bit Systems bekommt.

Desweiteren habe ich auch Kodi Lea 18.5 auf diesem System kompiliert. Die Systemauslastung beim Abspielen eines 1080p Films liegt damit bei ca 50% Systemauslastung.

 

Für die Erstellung des Grundsystems bietet sich ein normaler PC an, da er in angemessener Zeit den Kernel kompiliert. Ich verwende für diesen Zweck eine virtuelle Debian Buster Installation. Ich nutze gerne KVM unter Linux, aber man kann es natürlich auch auf einem Mac oder Windows machen.

Ich gehe davon aus man hat jetzt also das Terminal in dieser Maschine laufen. Ausnahmsweise arbeite ich hier als User root, da ich die Maschine nicht produktiv einsetzte. Also genug geschrieben, es geht los.

Installation Grundsystem

Installation der nötigen Programme

apt install debootstrap dosfstools qemu-user-static binfmt-support build-essential git bison flex libssl-dev cmake libncurses-dev
apt install binutils-aarch64-linux-gnu gcc-aarch64-linux-gnu g++-8-aarch64-linux-gnu
ln -s /usr/bin/aarch64-linux-gnu-g++-8 /usr/bin/aarch64-linux-gnu-g++

Das vorläufige Image ist knapp 4GB groß, mehr macht zur Zeit keinen Sinn. Da man nur unötig Nullen speichert. Wir expandieren nachher das Filesystem auf die Größe der SD-Card.

BaseWorkDir=/rpi4    # Basis Arbeits Verzeichnis
mkdir -p $BaseWorkDir
cd $BaseWorkDir
dd if=/dev/zero of=debian-rpi4.img iflag=fullblock bs=1M count=3600

Nun das Image als Loop Device einrichten und partitionieren.

losetup -f -P --show debian-rpi4.img
Loop_Dev=/dev/loop0     # Achtung das von losetup angezeigte loop Device nehmen !
parted $Loop_Dev "mklabel msdos"			
parted $Loop_Dev "mkpart p fat32 1 255"	# 254MB Boot Partition
parted $Loop_Dev "mkpart p ext4 255 -1"	# Rest eine Partition

 Filesysteme auf den Partitionen erstellen und in das Dateisystem einhängen.

mkfs.vfat /dev/loop0p1
mkfs.ext4 /dev/loop0p2

mount /dev/loop0p2 /mnt
mkdir /mnt/boot
mount /dev/loop0p1 /mnt/boot
mount -i -o remount,exec,dev /mnt

Nun sollte lsblk unser Loop Device so zeigen.

[root@damu:~]# lsblk
NAME      MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
loop0       7:0    0  7,6G  0 loop
  loop0p1 259:2    0  243M  0 part /mnt/boot
  loop0p2 259:3    0  7,4G  0 part /mnt
vda       254:0    0   16G  0 disk
  vda1    254:1    0   16G  0 part /

Da wir uns ja auf einer anderen CPU Architektur als unser Zielsystem befinden,  arbeiten wir mit dem CPU Emulator und installieren mit ihm das Basissystem auf unserem Loop Device.

Man nenn dies Crosscompiling, in unseren Fall arbeiten wir zur Zeit auf der amd64 oder x64 Architektur und erstellen ein System für die arm64 (ARMv8 Rechenkerne) Architektur. Nur der Raspberry Pi 4 hat eine ARMv8 CPU ! Der Raspberry Pi 3+ hat zwar auch eine CPU (ARMv7) die 64 Bit tauglich ist, aber diese Anleitung ist ausschließlich für den Pi 4 und wird nicht ohne Änderung auf dem PI 3+ laufen !

qemu-debootstrap --arch=arm64 buster /mnt

Nun wird das neue Basis System auch ins Dateisystem eingebunden, damit wir mittels chroot in unser neues Minisystem wechseln können.

mount -o bind /sys /mnt/sys
mount -o bind /proc /mnt/proc
mount -o bind /dev /mnt/dev
mount -o bind /dev/pts /mnt/dev/pts

cp /etc/resolv.conf /mnt/etc/resolv.conf 

chroot /mnt

Als erstes unserem Paktemanager (apt) bekannt machen, was für ein System er hier hat.

echo "deb http://deb.debian.org/debian/ buster main non-free contrib
deb-src http://deb.debian.org/debian/ buster main non-free contrib

deb http://security.debian.org/debian-security buster/updates main contrib non-free
deb-src http://security.debian.org/debian-security buster/updates main contrib non-free

deb http://deb.debian.org/debian/ buster-updates main contrib non-free
deb-src http://deb.debian.org/debian/ buster-updates main contrib non-free" > /etc/apt/sources.list

Wir installieren die ersten neuen Pakete in unserem Mini System.

Desweiteren konfigurieren wir unsere Systemsprache, Tastaturlayout und Zeitzone.

apt install console-setup debconf locales wget

dpkg-reconfigure locales          
dpkg-reconfigure keyboard-configuration 
dpkg-reconfigure tzdata

Passwort für den User root setzten und einen neuen User anlegen.

# Passwort root setzen
passwd		  
# User anlegen, mit dem Namen Eurer wahl ;-)
adduser NAME
# Hier den Benutzernamen den ihr eben angelegt habt, die nötigen Rechte geben
usermod -a -G video,audio,render NAME   
# diese udev Regel benötigen wir, da der Grafiktreiber leider die Benutzer Rechte für das video Device nicht für normale Benutzer setzt.  
echo 'SUBSYSTEM=="vchiq",GROUP="video",MODE="0660"' > /etc/udev/rules.d/10-vchiq-permissions.rules

Den Systemdienst dbus installieren und starten.

Sowie den Rechnernamen vergeben.

apt install ca-certificates dbus
service dbus restart

echo „raspberry-pi4“ >  /etc/hostname

In die Datei /etc/fstab schreiben wir, welche Dateisysteme wie eingebunden werden.

echo "
/dev/mmcblk0p1 /boot   vfat    noatime,nodiratime                   0  2
/dev/mmcblk0p2 /       ext4    noatime,nodiratime,errors=remount-ro 0  1
tmpfs          /tmp    tmpfs   nosuid                               0  0
" > /etc/fstab

Installation von dhcp Client und Netzwerk Tools, sowie das Aktivieren der entsprechenden Systemd Dienste.

apt install dhcpcd5 net-tools ssh ntp

systemctl enable systemd-networkd.service
systemctl enable systemd-resolved.service

Ich installiere mir immer noch gleich ein paar Standardtools mit, kann man natürlich auch später machen, wenn die SD-Card im Raspberry gestartet wurde.

apt install screen vim multitail bc most cpufrequtils psmisc dnsutils htop mc autofs 

Um Audio zu haben, wird ja bei einem reinen Netzwerkdienst nicht benötigt, wer aber einen Desktop nutzen möchte, will ja auch Ton ;-) Also wenn benötigt abarbeiten, oder überspringen.

apt install alsa-utils pulseaudio
echo "# Raspberry Config

load-module module-alsa-sink device=hw:2,0 sink_name=jack sink_properties=device.description=Kopfhörer
load-module module-alsa-sink device=hw:0,1 sink_name=hdmi0 sink_properties=device.description=HDMI_0
load-module module-alsa-sink device=hw:1,0 sink_name=hdmi1 sink_properties=device.description=HDMI_1
load-module module-combine-sink sink_name=combined slaves=hdmi0,hdmi1,jack sink_properties=device.description=Kombiniert
set-default-sink combined" >> /etc/pulse/default.pa

# Achtung hier als NAME den angelegten Benutzer nehmen
usermod -a -G pulse,pulse-access NAME

Wer WLAN benötigt macht jetzt hier weiter, ansonsten einfach diesen Teil überspringen.

apt install wpasupplicant wireless-tools git

# Installieren wenn eine Grafische Oberfläche benutzt werden soll 
apt install network-manager-gnome   

echo "ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=DE"  > /etc/wpa_supplicant/wpa_supplicant.conf

# Automatischer mac Adressenwechsel deaktivieren.
# (Benötige ich zu Hause nicht und spamt nur das Log voll)
echo "[device-mac-randomization]
wifi.scan-rand-mac-address=no

[connection-mac-randomization]
wifi.cloned-mac-address=stable" > 30-mac-randomization.conf

cd /tmp
git clone https://git.kernel.org/pub/scm/linux/kernel/git/sforshee/wireless-regdb.git
cd wireless-regdb
mkdir -p /lib/firmware/brcm
cp regulatory.db.p7s regulatory.db /lib/firmware
cd /lib/firmware/brcm
ln -s brcmfmac43455-sdio.bin brcmfmac43455-sdio.raspberrypi,4-model-b.bin
ln -s brcmfmac43455-sdio.clm_blob brcmfmac43455-sdio.raspberrypi,4-model-b.clm_blob
ln -s brcmfmac43455-sdio.txt brcmfmac43455-sdio.raspberrypi,4-model-b.txt

Das gleiche Spiel für Bluetooth.

apt install bluetooth bluez git

# Wenn X genutzt werden soll
apt install blueman  

wget -P /mnt/lib/udev/rules.d\
 https://raw.githubusercontent.com/RPi-Distro/raspberrypi-sys-mods/master/etc.armhf/udev/rules.d/99-com.rules
cd /tmp
git clone https://github.com/RPi-Distro/pi-bluetooth
cd pi-bluetooth
cp usr/bin/* /usr/bin
cp lib/udev/rules.d/90-pi-bluetooth.rules /lib/udev/rules.d
cp debian/pi-bluetooth.bthelper\@.service /lib/systemd/system
cp debian/pi-bluetooth.hciuart.service /lib/systemd/system
systemctl enable pi-bluetooth.hciuart.service

Zu guter letzt noch VNC, aber Achtung ! Diesen Dienst so nur im lokalen Netzwerk nutzen, da Passwörter und alle anderen Daten unverschlüsselt übertragen werden !

apt install x11vnc
x11vnc -storepasswd /etc/x11vnc.pass	# Passwort für vnc login vergeben

echo "[Unit]
Description=Start x11vnc
Requires=display-manager.service

[Service]
Type=simple
ExecStart=/usr/bin/x11vnc -display :0 -auth /var/lib/lightdm/.Xauthority -noncache -forever -loop -noxdamage -repeat -rfbauth /etc/x11vnc.pass -rfbport 5900 -shared

[Install]
WantedBy=multi-user.target" > /lib/systemd/system/x11vnc.service

systemctl enable x11vnc.service

Nun verlassen wir unser Mini System wieder.

exit    

 Jetzt alle Dateisysteme die chroot benötigte aushängen. Aber Achtung das Loop Device bleibt noch, denn wir sind ja noch nicht fertig.

cd /
umount --recursive 
umount /mnt/dev/pts
mount -o remount,ro /mnt/dev
umount /mnt/dev
umount /mnt/proc
umount /mnt/sys

Manchmal gibt es Fehlermeldungen beim aushängen, insbesondere bei /mnt/dev. Dann erstmal einfach weitermachen und vor dem Schreiben der Image Datei auf die SD-Card das System neustarten.

 

Für unser neues System brauchen wir auch Software, die sogenannte nicht freie Firmware. Diese ist nicht frei von Rechten des Herstellers. Daher ist diese Firmware nicht im Linux Kernel enthalten und muß von der Raspberry Organisation heruntergeladen werden.

cd /mnt/boot
URL="https://github.com/raspberrypi/firmware/raw/master/boot/"
for FILE in fixup4cd.dat fixup4.dat fixup4db.dat fixup4x.dat start4cd.elf start4db.elf start4.elf start4x.elf;\
do wget $URL/$FILE;\
done

mkdir /tmp/firmware
git clone https://github.com/RPi-Distro/firmware-nonfree /tmp/firmware
cp -va /tmp/firmware/* /mnt/lib/firmware

Jetzt geht es ans eingemachte :-) Das Herz unseres neuen Systems, der Kernel.

In dem Moment wo ich dies hier niederschreibe, ist der aktuelle Kernel der 4.19.y Da ich aber die neusten Patches und Verbesserungen haben möche nehme ich den 5.4.y Das ist ein Kernel an dem täglich Veränderungen statt finden, daher kann es auch sein das mal was nicht funktioniert, dafür aber paar Tage später schon wieder gefixt wurde. Bisher hatte ich aber keine Probleme mit diesem Kernel.

cd $BaseWorkDir
# aktueller Mainstream Kernel
#git clone --depth=1 --branch rpi-4.19.y https://github.com/raspberrypi/linux

# neuster Kernel Stand 24.11.19
git clone --depth=1 --branch rpi-5.4.y https://github.com/raspberrypi/linux 

cd linux
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig

Warum auch immer ist merkwürdigerweise in der Kernel Konfiguration etwas deaktiviert, was man doch gerne mal braucht und zwar der GPIO Support über das /sys Filesystem !

Viele Hardware Erweiterungen nutzen dieses File System. Daher aktivieren wir es jetzt per Hand.

Dafür rufen wir die Konfiguration des Kernels wie folgt auf:

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

Nun hangeln wir uns durch das Menu: Device Drivers ---> *- GPIO Support ---> und aktivieren -> /sys/class/gpio/... (sysfs interface)

Dann speichern und das Menü wieder verlassen.

Zeit den Kernel zu kompilieren, dies wird einige Zeit, je nach Rechner in Anspruch nehmen, so ca 20-30min.

# Kernel kompilieren und in unser neues System kopieren
make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
cp arch/arm64/boot/Image /mnt/boot/kernel8.img
# Kernel Module installieren
make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=/mnt modules_install
# Device Tree auf unser System kopieren
make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_DTBS_PATH=/mnt/boot dtbs_install
cp /mnt/boot/broadcom/bcm2711-rpi-4-b.dtb /mnt/boot

Wir benötigen noch ein Stück Firmware und dann ist es fast geschaft.

cd $BaseWorkDir
git clone https://github.com/raspberrypi/tools.git tools
cd tools/armstubs
make -j4 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- armstub8-gic.bin
cp armstub8-gic.bin /mnt/boot

Jetzt erstellen wir noch die Datei /boot/config.txt, in der steht wie die Hardware konfiguriert werden soll.

echo "[HDMI:0]
# HDMI output mode will be used, even if no HDMI monitor is detected
hdmi_force_hotplug=1

# Passthrough of DTS/AC3 even when this is not reported as supported
#hdmi_force_edid_audio=1

# Falls DVI bzw HDMI Schnittstelle nicht erkannt wird. 1=DVI Mode no Audio / 2 HDMI Mode with Audio
#hdmi_drive=2

# Sollte man einen schwarzen Rand um das Bild haben, aktivieren!
#disable_overscan=1

# VGA RAM Größe minimum 16MB (wenn zB kein X benutzt wird)
# max 944MB, mehr als 512MB macht jedoch keinen Sinn !
gpu_mem=256

# Enable DRM VC4 V3D driver on top of the dispmanx display stack
dtoverlay=vc4-fkms-v3d
max_framebuffers=2

# Notwendig für 64bit
armstub=armstub8-gic.bin
enable_gic=1
arm_64bit=1

# Auskommentieren um wifi deaktivieren
#dtoverlay=disable-wifi

# Audio aktiviren
dtparam=audio=on
" > /mnt/boot/config.txt

Erzeugen der /boot/cmdline.txt mittls derer Parameter dem startenden Kernel mitgegeben werden.

echo "root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait\
 snd_bcm2835.enable_headphones=1 snd_bcm2835.enable_hdmi=1 snd_bcm2835.enable_compat_alsa=1" > /mnt/boot/cmdline.txt

Das System ist jetz so weit fertig. Da Raspbian ein paar Tools mitbringt die ganz praktisch sind, installieren wir die auch.

cd $BaseWorkDir
apt-install pkg-config
git clone https://github.com/raspberrypi/userland
cd userland
sed s/sudo// -i buildme		#sudo entfernen
./buildme --aarch64 /mnt
echo "/opt/vc/lib" > /mnt/etc/ld.so.conf.d/userland.conf
cp -va build/bin/* /mnt/usr/local/bin

Anmerkung noch, zu den Userland Tools gehören auch die "Hello" Prgramme. die habe ich nicht kompiliert bekommen, unter anderen deswegen, weil es für 64 Bit einen anderen Grafiktreiver gibt. Der nennt sich v3d.

umount /mnt/boot
umount /mnt
losetup –d /dev/loop0

cd $BaseWorkDir
ACHTUNG: Jetzt keinen Fehler machen! Genau schaun welches Device der USB Reader ist in dem die SD-CARD für unser neues System steckt.

dd if=debian-rpi4.img of=/dev/[device name] bs=4M status=progress

So wenn nun alles glattgelaufen ist, die SD-Card in den Raspberry stecken und booten.

Hat das alles geklappt, das Filesystem auf die Größe der SD-Card erweitern und man kann in seinem neuen 64bit System mit 64bit Kernel spielen.

apt install parted
parted /dev/mmcblk0 "resizepart 2 -1"
resize2fs /dev/mmcblk0p2

Ich hoffe die lange Anleitung schreckt nicht ab, aber wenn man es geschaft hat, darf man wohl zurecht auch ein wenig Stolz sein.

Die Anleitung habe ich Schritt für Schritt geprüft und hoffe es haben sich nicht Fehler beim veröffentlichen eingeschlichen.

Ich freue mich über jeden Kommentar, also ran an das Terminal und los.

klaus
Autor: klaus
Diese Seite dient als Speicher für mein Linux Wissen, das ja doch nach einiger Zeit in Vergessenheit gerät. Vielleicht hilft es ja auch dem Ein oder Anderem ein Problem zu lösen.


Comments powered by CComment