Mittwoch, 17. Februar 2021

BootStick für den RaspberryPi

Über USB Boot bei SD Card basierten SBCs hab ich schon mal was geschrieben, ab Version Pi2B v1.2 (Link) kann der Pi ohne SD Card direkt vom USB booten. Dazu muss man u.U. eine einmalige Programmierung vornehmen. Die Hardware und der Pi schon bereit ist, kann man leicht ermitteln:

# Die Hardwareversion ermitteln
cat /sys/firmware/devicetree/base/model
# ermitteln ob das Bit schon gesetzt ist
vcgencmd otp_dump | grep 17:
17:3020000a
#bei ausgabe 17:1020000a programmieren:
sudo cp /boot/config.txt /boot/config.bak
echo program_usb_boot_mode=1 | sudo tee -a /boot/config.txt
# einmal booten wenn erfolgreicher Test config wieder zurück
sudo mv /boot/config.bak /boot/config.txt

Ich hatte die Idee ob man den Pi temporär mit einem Stick booten kann um die SD Card zu sichern oder mit einem neuen Image zu versorgen. Ist vielleicht nur eine Machbarkeitsstudie - ich habe es ausprobiert und auf alle Fälle mal aufgeschrieben. Meine Beschreibung bezieht sich auf ein laufendes System mit RaspiOs lite.

Boot Stick im laufenden System erzeugen

Man benötigt einen USB Stick mit einer Kapazität von mindestens 8 GB. Es ist der einzige USB Speicherstick der gesteckt wird!

Als USB Stick geht natürlich auch ein SD Card Reader und eine SD Card. Es gibt aber offenbar Card Reader wo der erste Boot Vorgang (Expansion des Dateisystems) nicht funktioniert.

Die universelle URL für "immer die aktuellste"  RaspiOs Lite Version habe ich per Zufall gefunden, die kann sich in Zukunft auch wieder ändern! Man kann auch die versionsbezogene URL von der download Seite nehmen. 

Achtung
Der folgende Code überschreibt alle Daten auf dem gerade gesteckten USB Stick auf /dev/sda !

Das Image wird heruntergeladen, auf den Stick geschrieben und die boot Partition gemounted um ssh zu aktivieren und einen User zu erzeugen. 
Unbedingt die konkrete Situation vorher prüfen! z.B. lsblk

dev='sda'
# 32 bit Version
download='raspios_lite_armhf_latest'
# 64 bit Version
download='raspios_lite_arm64_latest'
url="https://downloads.raspberrypi.org/${download}"
img=$(basename $(wget -nv --spider --content-disposition $url 2>&1 |awk '{printf $4}') )
wget -N --content-disposition $url

Seit April 2022 ist das Image nicht mehr zip komprimiert sondern img.xz und es wird kein Standardbenutzer im System eingerichtet! Damit muss das Headless Setup etwas erweitert werden ( Link zur Info und zur offiziellen Doku). Um nur die img Datei zu entpacken und die gepackte Version zu behalten kann man den Befehl unxz -k $img verwenden.

Tipp: Nicht im Sinne des Erfinders aber man kann (noch?) den alten User pi mit Password raspberry einrichten. Im folgenden Code muss der gewünschte User und das Passwort eingetragen werden (die Box lässt sich editieren)

xzcat ${img} | sudo dd of=/dev/${dev} bs=4M status=progress conv=fsync
part=${dev}1
dest=/mnt/${part}
sudo mkdir -p ${dest}
sudo mount /dev/${part} ${dest}
sudo touch ${dest}/ssh
echo user:$(echo 'password' | openssl passwd -6 -stdin) | sudo tee ${dest}/userconf.txt
sudo umount ${dest}

Auffällig ist: mit der Version April 2022 erfolgt ein "automatic login" auf der Console mit dem default user!? 

Hinweis: Es geschieht mittels der Datei: /etc/systemd/system/getty@tty1.service.d/autologin.conf

Erläuterung zum Autologin.

Hier noch die alte Version des Setups:

unzip -p $img | sudo dd of=/dev/${dev} bs=4M status=progress conv=fsync
part=${dev}1
dest=/mnt/${part}
sudo mkdir -p ${dest}
sudo mount /dev/${part} ${dest}
sudo touch ${dest}/ssh
sudo umount ${dest}

Bootreihenfolge ändern

Verschiebt man nun einfach die Datei  bootcode.bin - kann die SD Card nicht mehr booten und die Bootreihenfolge wird abgearbeitet.

Anmerkung: Der Pi 4 kann die Bootreihenfolge über seine EEPROM Konfiguration festlegen siehe. Raspberry Doku Geht nicht schneller, sieht aber eleganter aus. 

sudo mv /boot/bootcode.bin /boot/bootcode.bak
sudo reboot

Hinweis: Hat man das System neu eingerichtet (Abschnitt oben) dann dauert der erste Start bei einem Pi3+ ca. 10 Minuten bis zum Login. 

Nach dem Neustart vom USB Stick ( /dev/sda) kann man die SD Card mounten und nach getaner Arbeit stellt man einfach die Datei bootcode.bin wieder her.

part='mmcblk0p1'
dest=/mnt/${part}
sudo mkdir -p ${dest}
sudo mount /dev/${part} ${dest}
sudo mv ${dest}/bootcode.bak ${dest}/bootcode.bin

Platz auf dem USB Stick schaffen 

Will man vor dem ersten Start noch etwas auf den Stick kopieren braucht man Platz.
Dazu wird die USB Stick Systempartition (Partition 2) vergrößert, damit z.B. das RaspiOs Lite Image darauf kopiert werden kann. Die Partition wird eigentlich beim ersten Start vergrößert, ich wollte nicht unnötig booten. Dieser Schritt ist nicht unbedingt notwendig, man kann nach dem Start auch mmcblk0p2 mounten und die Imagedatei von dort kopieren. 
dev='sda'
part=${dev}2
start_sector=$(sudo fdisk -l | grep ^/dev/${part} |  awk -F" "  '{ print $2 }')
  cat <<EOF | sudo fdisk -c -u /dev/${dev}
d
2
n
p
2
$start_sector
+4G
w
EOF
sudo fdisk -l /dev/${dev} # Nur zur Kontrolle
# Das Dateisystem muss noch überprüft und erweitert werden
sudo e2fsck -f /dev/${part}
sudo resize2fs /dev/${part}

Hintergrund: Eine Partition unter Linux wird vergrößert, in dem man sie löscht, mit gleichem Anfangssektor und neuem Endsektor wieder erstellt und das Dateisystem erweitert. Das Here Doc steuert hier die Befehle an fdisk über stdin als Alternative zur manuellen Eingabe.

Das RaspiOs Image kann nun auf den USB Stick kopiert werden.

part=${dev}2
dest=/mnt/${part}
sudo mkdir -p ${dest}
sudo mount /dev/${part} ${dest}
cp raspios_lite_armhf_latest.zip ${dest}/home/pi/

SD Card Systemimage neu schreiben

Das System ist vom USB Stick gestartet und wir wollen das neue RaspiOs Image auf die SD Card schreiben.

Achtung
Der folgende Code überschreibt alle Daten auf der SD Card!

Bitte die Kommentarzeichen entsprechend enfernen.
dev='mmcblk0'
# unzip -p raspios_lite_armhf_latest.zip | sudo dd of=/dev/${dev} bs=4M status=progress conv=fsync
part=${dev}p1
dest=/mnt/${part}
sudo mkdir -p ${dest}
sudo mount /dev/${part} ${dest}
# sudo touch ${dest}/ssh
# sudo mv ${dest}/bootcode.bak ${dest}/bootcode.bin # bzw. Pi4: sudo -E rpi-eeprom-config --edit
sudo reboot

Tipps

Wird nach dem Neustart der Hostname kritisiert muss man vorher die known_hosts Datei bereinigen:

ssh-keygen -R raspberrypi

Noch was vergessen?

Code Block


Keine Kommentare:

Kommentar veröffentlichen