Netwerk booten van een Raspberry 4

Door synoniem op vrijdag 13 december 2019 22:20 - Reacties (4)
Categorie: Raspberry Pi, Views: 2.478

Mijn eerste post gaat over het netwerkbooten van de Raspberry Pi 2B, 3B en 3B+. Ik had op dat moment nog geen Raspberry Pi 4B en ik werd er al snel op gewezen dat voor de 4B het op een andere manier werkt. Inmiddels is de Sint langs geweest en heb ik een Pi 4B ontvangen hoog tijd voor een aanvulling dus.

In tegenstelling tot de voorgaande Pi's heeft de 4B geen One Time Programmable geheugen maar een echte EEPROM waarin firmware en configuratie in opgeslagen kunenn worden. Alleen had de Pi 4 bij de lancering nog geen mogelijkheid om van het netwerk te booten. Dat is pas mogelijk met de beta firmware vanaf 26 september 2019. Koop je nu op het moment dat ik dit schrijf een Pi 4B dan is de firmware hoogst waarschijnlijk nog niet up to date.

Wat heb je nodig: server
Voor de inrichting van de tftp- en nfsserver veranderd er feitelijk niets ten opzichte van mijn eerste post. Het grote verschil is dat de Pi 4 niet het bestand bootcode.bin gebruikt maar het bestand start4.elf. Daarnaast bepaald een instelling in de bootconfiguratie van de Pi waar het bestand start4.elf verwacht wordt. Standaard is dat weer in een directory met als naam het serienummer van de Pi.

Wat heb je nodig: client
Voor de client is er wat meer nodig om het werkend te krijgen. Om de firmware bij te werken en configuratie aan te passen moet je altijd eerst twee keer met een SD-kaart opstarten. En in het geval dat je Raspbian/Debian gebruikt moet dat versie 10 (Buster) zijn. Oudere versie werken volgens opgave van Raspbian niet en dit keer ben ik niet zo eigenwijs geweest het toch te proberen. Na de image op de gebruikelijke wijze op een SD-kaart gekopieerd te hebben en de Pi geboot is, werken we het systeem bij en installeren de rpi-eeprom software.
code:
1
2
3
$ sudo apt update
$ sudo apt full-upgrade
$ sudo apt install rpi-eeprom

Standaard staat rpi-eeprom zo ingesteld ingesteld dat deze alleen naar kritieke updates kijkt. Zoals gezegd is de nieuwe firmware nu nog beta en wijzigen we /etc/default/rpi-eeprom-update:
code:
1
2
3
4
5
FIRMWARE_RELEASE_STATUS="critical"

in

FIRMWARE_RELEASE_STATUS="beta"

Daarna is het tijd om de updates te controleren met in mijn geval deze mededeling:
code:
1
2
3
4
5
$ sudo rpi-eeprom-update

*** UPDATE REQUIRED ***
CURRENT: Tue 10 Sep 10:41:50 UTC 2019 (1568112110)
LATEST: Mon Nov 18 11:06:55 UTC 2019 (1574075215)

Tijd voor een update want deze versie heeft zeker nog geen netboot ondersteuning.
code:
1
2
3
4
$ sudo rpi-eeprom-update -a

*** INSTALLING REQUIRED UPDATE ***
Bootloader EEPROM update pending. Please reboot to apply the update.

Doe een reboot en controleer of Pi nu up to date is.
Dan is nu de firmware up to date maar de bootconfiguratie is nog niet veranderd. Afhankelijk of je voor de eeprom het critical of beta update channel ingesteld hebt, ga je naar /lib/firmware/raspberrypi/bootloader/critical/ of /lib/firmware/raspberrypi/bootloader/beta/. Vanaf hier gaan we eerst de huidige configuratie achterhalen, deze aanpassen naar netwerkboot en dan weer terugschrijven:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
$ cd /lib/firmware/raspberrypi/bootloader/beta/
$ sudo cp pieeprom-2019-11-18.bin new-pieeprom.bin
$ sudo rpi-eeprom-config new-pieeprom.bin > bootconf.txt
$ cat bootconf.txt

[all]
BOOT_UART=0
WAKE_ON_GPIO=1
POWER_OFF_ON_HALT=0
DHCP_TIMEOUT=45000
DHCP_REQ_TIMEOUT=4000
TFTP_FILE_TIMEOUT=30000
TFTP_IP=
TFTP_PREFIX=0
BOOT_ORDER=0x1
SD_BOOT_MAX_RETRIES=3
NET_BOOT_MAX_RETRIES=5
[none]
FREEZE_VERSION=0

$ sudo sed -i s/0x1/0x12/g bootconf.txt

$ sudo rpi-eeprom-config --out netboot-pieeprom.bin --config bootconf.txt new-pieeprom.bin
$ sudo rpi-eeprom-update -d -f ./netboot-pieeprom.bin

De bootvolgorde wordt bepaald aan de hand van de BOOT_ORDER variabele. 0x1 betekent boot van SD-kaart, 0x2 netboot. De waarde wordt van rechts naar links uitgelezen en in mijn geval wil ik eerst van het netwerk booten en dan eventueel van de SD-kaart. BOOT_ORDER wordt dan 0x12. Andersom, eerst SD-kaart en dan netwerk wordt 0x21 maar de wachttijd voordat er werkelijk gestart wordt vanaf het netwerk wordt dan behoorlijk langer.
TFTP_PREFIX bepaald waar er naar het bestand start4.elf gezocht wordt. De waarde 0 staat voor een directory met het serienummer. De waarde 2 voor een directory met het MAC adres van de netwerkinterface in de vorm van dc-a6-32-1c-5a-1a. En als laatste de waarde 1 gebruikt de tekst die je kan invullen bij TFTP_PREFIX_STR als waarde voor de directory.

Als alles goed gegaan is kun je je Pi 4 nu vanaf het netwerk booten.

Pi Zero als smart USB-stick 3

Door synoniem op vrijdag 6 december 2019 22:31 - Reacties (2)
Categorie: Raspberry Pi, Views: 2.383

Soms zit het mee, soms zit het tegen. Dat geldt ook voor mijn projectje met de Pi Zero. De uiteindelijke bedoeling is om een USB-stick te hebben met een ge-encrypte opslagmogelijkheid. Uitgerekend wanneer je daarmee bezig bent blijkt je SD-kaart het begeven te hebben. Gelukkig kon ik een voordelige 64 GB SD-kaart scoren met Black Friday.

De Pi om te toveren in een massaopslag is vrij eenvoudig. Dat is namelijk een kwestie van de module g_mass_storage laden met de juiste parameters. Er zijn twee maren:

1 - Je kunt betreffende fileimage of het block device niet gelijktijdig door de Pi en de host laten benaderen. Dit resulteert gegarandeerd in datacorruptie, als het al werkt. Ik heb het uiteraard wel geprobeerd met kopieeren maar bestanden stonden volgens de host op de stick maar de Pi leek ze volkomen te negeren. Maar zodra de Pi een keer ge-rebooted was bleken de bestanden verminkt te zijn. En volstrekt willekeurig of de data afkomstig is van de Pi of van de host.

2 - Je kunt de losse module g_serial en g_mass_storage niet gelijkertijd laden. Om dit laten werken moet je de module g_multi gebruiken met een configuratiebestand voor de parameters die je mee wil geven. Zoals gemeld in aflevering 2 is g_multi een composite driver en daarmee een combo van g_serial, g_ether en g_mass_storage. De parameters die je mee moet geven zijn overigens gelijk aan die van de losse g_ modules. Voor nu heb ik de parameters voor g_ether even gelaten voor wat het is.

Daarnaast was het mijn bedoeling om Veracrypt te gebruiken voor encryptie van de stick. Veracrypt is de opvolger van Truecrypt wat zowel onder Windows als Linux te gebruiken is. Het maakt standaard geen deel uit van Raspbian dus je moet het zelf downloaden en installeren. De laatste versie voor Raspbian is 1.21. Wil je versie 1.24 met hotfix dan zul je deze zelf moeten compileren (inclusief een patch aanbrengen en alle afhankelijkheden met de hand regelen).

Helaas is Veracrypt een maatje te groot voor de Pi Zero. Bij een ge-encrypte container van 8 GiB had de Zero bijna vijf minuten nodig om deze te openen. Mocht je Veracrypt willen gebruiken voor een Pi 3 of 4, versie 1.21 is te downloaden van Sourceforge.

De eerste stap nu is het maken van een fileimage op de Pi om te kijken of alles werkt zoals geadverteerd. Het aanmaken van een ge-encrypted deel komt hier na daarom begin ik met een imagefile van 8 GiB.
code:
1
2
3
4
5
$ sudo dd bs=4M if=/dev/zero of=/usbshare.img count=2048

  2048+0 records in
  2048+0 records out
  8589934592 bytes (8.6 GB, 8.0 GiB) copied, 506.236 s, 17.0 MB/s

Vervolgens willen we hier een bestandssysteem op maken. Dat doen we door de imagefile te 'mounten' als een loop device, deze te partitioneren en vervolgens met FAT32 te formatteren. FAT32 omdat die zowel in Windows als Linux goed ondersteund wordt.
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
$ sudo losetup -f 

  /dev/loop0

$ sudo losetup -P  /dev/loop0 /usbshare.img

$ sudo fdisk /dev/loop0

Welcome to fdisk (util-linux 2.29.2).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.


Command (m for help): p
Disk /dev/loop0: 8 GiB, 8589934592 bytes, 16777216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Command (m for help): n
Partition type
   p   primary (0 primary, 0 extended, 4 free)
   e   extended (container for logical partitions)
Select (default p): p
Partition number (1-4, default 1): 
First sector (2048-16777215, default 2048): 
Last sector, +sectors or +size{K,M,G,T,P} (2048-16777215, default 16777215): 

Created a new partition 1 of type 'Linux' and of size 8 GiB.

Command (m for help): t
Selected partition 1
Partition type (type L to list all types): L

 0  Empty           24  NEC DOS         81  Minix / old Lin bf  Solaris        
 1  FAT12           27  Hidden NTFS Win 82  Linux swap / So c1  DRDOS/sec (FAT-
 2  XENIX root      39  Plan 9          83  Linux           c4  DRDOS/sec (FAT-
 3  XENIX usr       3c  PartitionMagic  84  OS/2 hidden or  c6  DRDOS/sec (FAT-
 4  FAT16 <32M      40  Venix 80286     85  Linux extended  c7  Syrinx         
 5  Extended        41  PPC PReP Boot   86  NTFS volume set da  Non-FS data    
 6  FAT16           42  SFS             87  NTFS volume set db  CP/M / CTOS / .
 7  HPFS/NTFS/exFAT 4d  QNX4.x          88  Linux plaintext de  Dell Utility   
 8  AIX             4e  QNX4.x 2nd part 8e  Linux LVM       df  BootIt         
 9  AIX bootable    4f  QNX4.x 3rd part 93  Amoeba          e1  DOS access     
 a  OS/2 Boot Manag 50  OnTrack DM      94  Amoeba BBT      e3  DOS R/O        
 b  W95 FAT32       51  OnTrack DM6 Aux 9f  BSD/OS          e4  SpeedStor      
 c  W95 FAT32 (LBA) 52  CP/M            a0  IBM Thinkpad hi ea  Rufus alignment
 e  W95 FAT16 (LBA) 53  OnTrack DM6 Aux a5  FreeBSD         eb  BeOS fs        
 f  W95 Ext'd (LBA) 54  OnTrackDM6      a6  OpenBSD         ee  GPT            
10  OPUS            55  EZ-Drive        a7  NeXTSTEP        ef  EFI (FAT-12/16/
11  Hidden FAT12    56  Golden Bow      a8  Darwin UFS      f0  Linux/PA-RISC b
12  Compaq diagnost 5c  Priam Edisk     a9  NetBSD          f1  SpeedStor      
14  Hidden FAT16 <3 61  SpeedStor       ab  Darwin boot     f4  SpeedStor      
16  Hidden FAT16    63  GNU HURD or Sys af  HFS / HFS+      f2  DOS secondary  
17  Hidden HPFS/NTF 64  Novell Netware  b7  BSDI fs         fb  VMware VMFS    
18  AST SmartSleep  65  Novell Netware  b8  BSDI swap       fc  VMware VMKCORE 
1b  Hidden W95 FAT3 70  DiskSecure Mult bb  Boot Wizard hid fd  Linux raid auto
1c  Hidden W95 FAT3 75  PC/IX           bc  Acronis FAT32 L fe  LANstep        
1e  Hidden W95 FAT1 80  Old Minix       be  Solaris boot    ff  BBT            
Partition type (type L to list all types): c
Changed type of partition 'Linux' to 'W95 FAT32 (LBA)'.

Command (m for help):  w
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.

$ sudo fdisk -l /dev/loop0
Disk /dev/loop0: 8 GiB, 8589934592 bytes, 16777216 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x00000000

Device       Boot Start      End  Sectors Size Id Type
/dev/loop0p1       2048 16777215 16775168   8G  c W95 FAT32 (LBA)

$ sudo mkfs -t vfat /dev/loop0p1
 mkfs.fat 4.1 (2017-01-24)

Vervolgens geven we in /etc/modprobe.d/usbgadget.conf de minimale parameters mee voor g_mass_storage:
code:
1
options g_multi file=/usbshare.img ro=0

De belangrijkste parameters voor g_mass_storage zijn file, removable, cdrom, ro en luns.
Hierbij is:
file=bestandsnaam|blockdevice
removable=0|1 Standaard 1 = ja
cdrom=0|1 Standaard 0 = nee tenzij één of meer cdroms wil emuleren
ro= 0|1 Standaard 0 tenzij het achterliggende bestand readonly is en als cdrom=1
luns=N Standaard 1 en specificeert het aantal logical units. Geef je twee bestandsnamen op bij file maar staat luns op 1 dan zal alleen het eerste bestand gebruikt worden.

En dan wordt het tijd om te testen door de module g_multi te laden:
code:
1
$ sudo modprobe g_multi

Is alles goed gegaan dan wordt op de host een USB-stick van 8 GiB zichtbaar. In de log op de Pi zie je dat de onderdelen van g_multi geladen worden:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
$ dmesg | tail -n 21
[   65.931527] using random self ethernet address
[   65.931548] using random host ethernet address
[   65.969728] Mass Storage Function, version: 2009/09/11
[   65.969751] LUN: removable file: (no medium)
[   65.970047] LUN: file: /usbshare.img
[   65.970062] Number of LUNs=1
[   65.971623] usb0: HOST MAC 9e:24:65:b1:c8:43
[   65.973026] usb0: MAC d2:95:c9:62:75:98
[   65.981082] g_multi gadget: Multifunction Composite Gadget
[   65.981106] g_multi gadget: userspace failed to provide iSerialNumber
[   65.981113] g_multi gadget: g_multi ready
[   65.981131] dwc2 20980000.usb: bound driver g_multi
[   66.045852] dwc2 20980000.usb: new device is high-speed
[   66.114088] dwc2 20980000.usb: new device is high-speed
[   66.336422] IPv6: ADDRCONF(NETDEV_UP): usb0: link is not ready
[   66.491877] dwc2 20980000.usb: new device is full-speed
[   66.558093] dwc2 20980000.usb: new device is high-speed
[   66.830857] dwc2 20980000.usb: new device is high-speed
[   66.899169] dwc2 20980000.usb: new address 32
[   66.978538] g_multi gadget: high-speed config #1: Multifunction with RNDIS
[   66.978895] IPv6: ADDRCONF(NETDEV_CHANGE): usb0: link becomes ready

Pi Zero als smart USB-stick 2

Door synoniem op zaterdag 23 november 2019 20:00 - Reageren is niet meer mogelijk
Categorie: Raspberry Pi, Views: 3.603

Om nog even terugkomen op de reactie bij aflevering 1 van Pi Zero als smart USB-stick wat kan je hier nu mee? Zoals gezegd heel veel. Hieronder een opsomming van de kernel modules die als linux gadget beschikbaar zijn.
  • Serial (g_serial), virtuele terminal ttyACM0 onder linux COM3 e.v. onder Windows
  • Ethernet (g_ether), virtuele ethernet adapter
  • Mass storage (g_mass_storage),virtuele USB-stick
  • MIDI (g_midi), virtuele MIDI apparaat
  • Audio (g_audio), virtuele audioapparaat
  • Keyboard/Mouse (g_hid), virtuele toetsenbord en muis
  • Mass storage and Serial (g_acm_ms), zowel USB-stick als virtuele terminal
  • Ethernet and Serial (g_cdc), zowel virtuele terminal als virtuele ethernet adapter
  • Multi (g_multi), tegelijkertijd terminal, seriële en ethernetadapter
  • Webcam (g_webcam), een webcam
  • Printer (g_printer), een printer
  • Gadget tester (g_zero), en een testmodule
Het eerste doel wat ik nu met de Pi wil bereiken is een ge-encrypte USB-stick waarbij je via zowel het netwerk als de virtuele terminal kan inloggen om de partitie beschikbaar te stellen en weer af te sluiten na gebruik. Om dat te realiseren heb ik uiteindelijk de g_multi module nodig maar ik begin simpel met alleen de g_serial module dan misschien g_ether en als laatste g_mass_storage. Werkt elke module afzonderlijk dan ga ik g_multi configureren (en nadenken over mijn volgende project).

Zoals altijd als je bezig gaat met dit soort projectjes ga er vanuit dat je rare dingen tegen gaat komen.
Maar laten we beginnen met USB OTG aan te zetten op de Pi. Dit doe je door in het bestand config.txt op de boot partitie de volgende regel toe te voegen:
code:
1
dtoverlay=dwc2

Vervolgens moet de module dwc2 (en g_serial) geladen worden. Normaliter doe ik dat in het bestand /etc/modules maar dit levert, in mijn geval, wat vage foutmeldingen en soms wel, soms niet goed opstarten op. Hierover niet getreurd je kan de te laden modules ook meegeven bij het opstarten door modules-load=dwc2 toe te voegen aan het bestand cmdline.txt op de boot partitie. Mijn cmdline.txt ziet er nu zo uit:
code:
1
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=PARTUUID=e934c5ce-02 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait modules-load=dwc2

Nu denk je misschien waarom laat je niet ook automatisch g_serial? Dat is een van de rare dingen waar ik tegenaan gelopen ben. Op het moment dat ik hier g_serial toevoeg zal het onder Windows gewoon werken maar onder Linux gaat het kennelijk iets te snel. In mijn logfile (dmesg) verscheen de volgende tekst:
code:
1
2
3
4
5
6
[24732.293784] usb 1-4: New USB device found, idVendor=0525, idProduct=a4a7, bcdDevice= 4.19
[24732.293787] usb 1-4: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[24732.293789] usb 1-4: Product: Gadget Serial v2.4
[24732.293791] usb 1-4: Manufacturer: Linux 4.19.85+ with 20980000.usb
[24732.317976] cdc_acm 1-4:2.0: ttyACM0: USB ACM device
[24732.318969] cdc_acm 1-4:2.0: failed to set dtr/rts

Met als gevolg dat het hele circus niet wil werken en minicom of screen een foutmelding geeft over device /dev/ttyACM0.

Het probleem heb ik ontweken door een vertragingstactiek toe te passen. Namelijk pas als laatste de module g_serial te laden in /etc/rc.local. Mijn rc.local ziet er nu zo uit:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.

# Print the IP address
_IP=$(hostname -I) || true
if [ "$_IP" ]; then
  printf "My IP address is %s\n" "$_IP"
fi
sleep 2
modprobe g_serial
exit 0

Is dit alles goed gegaan en de driver laadt zonder foutmeldingen, blijft er nog één ding over. Namelijk de Pi vertellen dat hij op de virtuele seriële poort ook een login kan verwachten. Dat kan op de twee manieren. De simpelste manier is vanaf de Pi zelf:
code:
1
sudo systemctl enable getty@ttyGS0.service

De andere manier is op de SD-kaart van de Pi deze kopieeractie uit te voeren, er vanuit gaande dat de SD-kaart gemount is onder /media/synoniem/rootfs.
code:
1
sudo ln -s /media/synoniem/rootfs/lib/systemd/system/getty@.service /media/synoniem/rootfs/etc/systemd/system/getty.target.wants/getty@ttyGS0.service


Onder linux kun je aan de logfile zien of het allemaal gelukt is en welk devicenaam de USB-stick gekregen heeft. Dit kun je controleren met;
code:
1
2
3
4
sudo dmesg | grep cdc
[21998.393504] cdc_acm 1-4:2.0: ttyACM0: USB ACM device
[21998.397107] usbcore: registered new interface driver cdc_acm
[21998.397108] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters

In dit geval is de seriële devicenaam /dev/ttyACM0. Met device kun je vanaf een linux systeem nu verbinding maken door middel van screen of minicom. Onder debian-achtigen distro's installeer je die met sudo apt-get install screen (of minicom).
code:
1
screen /dev/ttyACM0 115200

En het resultaat https://tweakers.net/ext/f/z22wH0FOtiJy1B4kizmt915O/full.png

Onder Windows gebruik je Putty met de virtuele COM poort toegewezen aan de USB-stick. Dit kun je eventueel terugvinden bij Apparaatbeheer. In mijn geval is dat COM3 en putty staat ingesteld op: serial, 115200 8N1.

Pi Zero als smart USB-stick 1

Door synoniem op dinsdag 12 november 2019 22:24 - Reacties (10)
Categorie: Raspberry Pi, Views: 3.635

De hardware
De Pi Zero is letterlijk en figuurlijk de kleinste Pi uit de serie. Fysiek maar een halve creditcard en maar een processor met één core en maar 512 Mb geheugen. Daarmee is hij echt voor inbouw in projecten bedoeld en niet voor een mediaspeler of andere zwaardere toepassingen. Daarnaast zijn ook niet alle connectoren aanwezig. En de wel aanwezige connectoren zijn ook nog eens micro en mini versie. Allemaal bedoeld om het printje zo klein mogelijk te houden.

Maar het interessantste onderdeel van een Zero is dat hij een USB OTG microconnector heeft. Daarmee kan de Zero tegelijk zowel een randapparaat/gadget als een master device zijn. Dat maakte mij nieuwsgierig naar de mogelijkheden om van de Zero een smart USB-stick te maken. Bij het rond zoeken op het web zijn er diverse handleidingen te vinden maar niet altijd compleet of voor een oude versie van Raspbian. Vandaar dat ik het resultaat van mijn projectje voor de liefhebbers in twee of drie afleveringen hier op schrijf.

Om het maximale aan functionaliteit uit de Zero te halen heb ik gekozen voor de Pi Zero W. Dus de versie met Wifi en Bluetooth aan boord. Ik wil ook dat het op een USB-stick lijkt met een gewone connector. Hier zijn verschillende oplossingen voor te koop met de keuze om zelf te solderen of door een tweede printplaatje met kunststof moertjes en boutjes vast te klemmen aan de Zero.


Zo ziet het printplaatje er uit, verkrijgbaar bij diverse leveranciers. De mijne heb ik op Aliexpress gekocht. (Geen affiliate je kan ook zelf zoeken op Pi Zero USB addon board).

En hier kun je zien dat de contacten op de Zero geklemd worden.

Overigens heb ik hiervoor ook een 3D geprinte behuizing gevonden op Thinkiverse waarmee het geheel echt op een USB-stick uit de begintijd lijkt. Lomp en zonder verloopje geen twee naast of onder elkaar te gebruiken. Wil je dat wel kun natuurlijk ook gelijk een micro - USB A verloopkabeltje gebruiken zonder het extra addon boardje.

De installatie
Als eerste wilde ik ssh en een wifi verbinding configuren zodat ik achter mijn gewone PC alles kan installeren en configuren. Dit doe je voor ssh door op een nieuw gekopieerd SD-kaartje in de root van de bootpartitie een leeg bestand ssh aan te maken:
code:
1
$ touch /ssh


Voor het inschakelen van wifi maak je op dezelfde locatie het bestand wpa_supplicant.conf met de volgende inhoud:
code:
1
2
3
4
5
6
7
8
9
10
11
country=NL
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
network={
    ssid="APnaam"
    psk="Wachtwoord"
    key_mgmt=WPA-PSK
    proto=RSN
    group=CCMP
    pairwise=CCMP
}


Helaas ben ik na veel gedoe er achter gekomen dat dit voor Raspbian 10/Buster niet werkt. Misschien dat er inmiddels een workaround is maar ik heb, na een halve dag hier aan verspild te hebben, er voor gekozen om Raspbian 9/Stretch te gaan gebruiken. Dat werkte direct bij de eerste keer opstarten met deze instellingen.

Wordt vervolgd.

Netwerk booten van een Raspberry Pi

Door synoniem op dinsdag 22 oktober 2019 23:41 - Reacties (7)
Categorie: Raspberry Pi, Views: 3.978

Inleiding
Zo in de loop van de tijd heb ik al aardig wat Raspberry Pi's draaien en daardoor ook te maken met de beperkte levensduur van SD-kaartjes. Vandaar dat ik op het idee kwam om te kijken of een Pi van het netwerk gestart kan worden. En dat kan! Voor de Pi 2B heb je dan nog steeds een SD-kaartje nodig maar daar staat maar één vfat partitie met één bestand op namelijk bootcode.bin. Staat dit bestand van ongeveer 52 K er op dan kan het SD-kaartje readonly gemaakt worden. Voor de Pi 3B, Pi 3B+ en Pi 4B heb je zelfs dat niet nodig. Overigens heb ik zelf nog geen Pi 4. maar volgens de documentatie die ik gevonden heb, werkt netbooten hetzelfde als bij de 3B+. De Pi 4 werkt niet hetzelfde, zie de link in de reactie van The Zep Man hier onder.

Wat heb je nodig: server
Om te beginnen heb je één of meer servers nodig die respectievelijk dhcp,tftp en nfs leveren. In mijn geval heb ik al een aparte dhcpserver en heb een sambaserver aanvullend geconfigureerd met tftp en nfs. In de dhcpserver heb ik option 66 next-server ingevuld met het ip-nummer van deze nieuwe server: 192.168.1.2. Daarnaast heb ik met dhcp static mappings voor vijf Pi's vaste ip-adressen ingesteld. Hiermee voorkom je een hoop problemen. Namelijk dat je Pi ineens twee ip-adressen krijgt of bij nfs startup crashed. De Pi geeft namelijk bij het booten vanaf het netwerk niet altijd een ACKnowledge naar de dhcpserver. Verderop na het laden van boot- en root-bestanden, bij het configureren van het network krijgt de Pi dan vrolijk een tweede ip-adres mee.

Voor de Pi's gebruik ik Raspbian 9 Lite en voor de samba/tftp/nfsserver Debian 9.
Wil je één server inclusief dhcp dan kan dat door het installeren en instellen van dnsmasq.

sudo apt install dnsmasq


Pas de inhoud van /etc/dnsmasq.conf aan naar:

port=0
dhcp-range=192.168.1.255,proxy
log-dhcp
enable-tftp
tftp-root=/srv/tftp
pxe-service=0,"Raspberry Pi Boot"


Voor het installeren van tftp en nfs:
sudo apt install tftpd-hpa nfs-kernel-server nfs-common

sudo mkdir /srv/tftp
sudo mkdir /srv/nfs


Controleer het tftpd-hpa configuratiebestand /etc/default/tftpd-hpa en pas het eventueel aan naar:

TFTP_USERNAME="tftp"
TFTP_DIRECTORY="/srv/tftp"
TFTP_ADDRESS="0.0.0.0:69"
TFTP_OPTIONS="--secure"


Maak een nfs exportdirectory door /etc/exports aan te passen. In mijn thuisnetwerk heb ik dit verder niet uitgebreid beveiligd. In een bedrijfsnetwerk of niet vertrouwde omgeving is het raadzaam om de manualpage van nfs er op na te slaan om uitgebreide beveiliging in te stellen.

/srv/tftp/      192.168.1.0/24(ro,sync,no_subtree_check,no_root_squash)
/srv/nfs/      192.168.1.0/24(rw,sync,no_subtree_check,no_root_squash)


Met deze instellingen kan het hele subnet 192.168.1.0 de export benaderen. De tftp directory hoeft alleen gelezen te worden en heeft read-only als kenmerk meegekregen. De nfs-directory moet straks door de Pi's gelezen en geschreven kunnen worden, vandaar read-write access. Om het root account (of pi met sudo) te kunnen gebruiken op de Pi's stel je no_root_squash in.
Start de export met:

sudo exportfs -a -v


De server heeft als vast ip-adres 192.168.1.2 dit adres heb je straks nodig voor het instellen van de clients.

Nu wil ik voor elke Pi een eigen configuratie en filesysteem hebben. Dat kan vrij eenvoudig omdat bij het opstarten van bootcode.bin geprobeerd wordt om ./<serienummer>/start.elf in te lezen. Is de directory <serienummer> aanwezig dan zullen alle ander bootbestanden ook uit die directory gelezen worden. Om het serienummer van de Pi te achterhalen gebruik je:

pi@rpi-1:~ $ cat /proc/cpuinfo|grep Serial

Serial		: 00000000d46ad669


Het serienummer zijn de laatste acht tekens. De laatste zes tekens zijn ook de laatste zes tekens van het MAC adres.
Met dit gegeven kun je aparte directories per Pi aanmaken op je bootserver:

mkdir /srv/nfs/d46ad669
mkdir /srv/tftp/d46ad669


De eenvoudigste manier om je huidige Pi één op één als netwerkboot versie terug te krijgen, is door je bestaande SD-kaartje te kopieeren. Dit kan in theorie vanaf een werkende Pi met rsync maar mijn ervaring is dat je beter offline het SD-kaartje kan kopieeren. Daar zijn vele manieren voor, bijvoorbeeld door een kaartlezer op je server aan te sluiten en dan als root de boot en root partitie te kopieeren. Je kan met Windows en Win32 Disk Imager de SD-kaart naar een image bestand op de server kopieeren en dan op de server als image bestand mounten met losetup. Het eindresultaat moet zijn dat van de boot partitie bootcode.bin in /srv/tftp komt te staan en de rest in /srv/tftp/d46ad669. De inhoud van de rootpartitie moet (ook als root) naar /srv/nfs/d46ad669 gekopieerd worden.

Na het kopieeren moet /srv/tftp/d46ad669/etc/fstab aangepast worden zodat alleen de regel voor proc blijft staan:

proc            /proc           proc    defaults          0       0


En /srv/tftp/d46ad669/cmdline.txt met opstartparameter moet per Pi aangepast worden naar:

dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/nfs nfsroot=192.168.1.2:/srv/nfs/d46ad669,tcp,v4 ip=192.168.1.10 rootfstype=nfs rw elevator=deadline rootwait


Gebruik je NFS versie 3 op de server dan wordt het v3 in plaats van v4. Het ip-adres 192.168.1.10 is het static mapped adres wat ik in de dhcpserver ingesteld heb staan voor deze Pi. In principe kan je ook de parameter ip=dhcp gebruiken in plaats van een ip-adres maar dat werkt dus niet altijd even betrouwbaar is mijn ervaring.

Als laatste, om het updaten van de boot bestanden mogelijk te houden, maken we een symbolic link naar de bootdirectory:

sudo ln -s /srv/tftp/d46ad669 /srv/nfs/d46ad669/boot


In principe kun je de bootdirectory ook als een nfsmount in /etc/fstab plaatsen. Maar omdat de tftp export bij mij read-only is, zou ik dan nog steeds niet de bootbestanden kunnen updaten.

Daarmee is de configuratie van de server klaar en wordt het tijd om de clients te configureren.


Wat heb je nodig: client
Het meest eenvoudig zijn de Pi 3B+ en de Pi 4B want daar hoeft niets aan te gebeuren. Netwerk aansluiten en ze kunnen booten.

De Pi 2B blijft een SD-kaartje nodig houden met een enkele vfat partitie en het bootcode.bin bestand. Vanaf daar boot hij verder op dezelfde manier als de andere modellen.

De Pi 3B vergt wat extra handelingen, namelijk het inschakelen van USB boot mode. Dit is een eenmalige actie waarbij je een stukje One Time Programmable geheugen overschrijft. Daarna kun je overigens desgewenst nog steeds van een SD-kaartje booten. Je kunt controleren of USB boot mode is ingeschakeld met het volgende commando:

$ sudo vcgencmd otp_dump | grep 17:


Is het resultaat 17:3020000a dan is het ingeschakeld.

Zo niet dan voeg je aan /boot/config.txt als laatste regel toe:

program_usb_boot_mode=1


en reboot je de Pi. Controleer of het vcgencmd commando nu wel het goede resultaat geeft en verwijder de laatste regel weer uit config.txt. Sluit de Pi af, verwijder de SD-kaart en laat hem netwerk booten!