PC Engines WRAP als WLAN-Router

Und es routet doch

Die «Wireless Router Application Platform» (WRAP) war ein sparsamer Kleincomputer lange bevor das Raspberry Pi und seine Kollegen die Gattung der Kleincomputer salonfähig machten. Für die meisten heutigen Aufgaben ist das System deutlich zu langsam, mit der richtigen Software kann es seiner ursprünglichen Berufung als WLAN-Router aber weiterhin gerecht werden.

Bei mir musste das WRAP seinerzeit einem ALIX-System weichen weil es von der Leistung her nicht mehr mit den steigenden Bandbreiten zurecht kam. Seit einer Weile verwaltet es als Router das Zweit-WLAN wo es mit pfSense bestückt zuverlässig seinen Dienst tat. Leider stellte pfSense mit Version 2.4 die Unterstützung für 32-bit-Systeme ein so dass ich entweder das Gerät oder das Betriebssystem tauschen musste – letzteres schien mir sinnvoller. Nach einigen Experimenten gelang ich schliesslich zur Einsicht, dass es an der Zeit ist, wieder einmal selbst Hand anzulegen und dem WRAP ein massgeschneidertes Kostüm zu verleihen, ein klassisch gebautes Betriebssystem für ein klassisches Gerät.

Die Anforderungen

Die Erwartungen für den Einsatz in unserem Zweit-WLAN sind recht bescheiden: das Gerät soll WLAN routen. Es soll dies im Frequenzbereich von 2.4 GHz nach IEEE 802.11b/g tun so dass das Netz auch für ältere Geräte erreichbar ist, selbstverständlich WPA2-verschlüsselt. Darüberhinaus schienen mir folgende Punkte relevant:

Die Hardware

Die Denkarbeit auf dem WRAP erledigt eine CPU des Typs Geode SC1100 (GX1) mit 266 MHz, 128 MB Arbeitsspeicher sind ebenfalls vorhanden. Für die Verbindung ans Netzwerk stehen drei 100mbps-Ethernet-Anschlüsse zur Verfügung, eine Mini-PCI-Karte mit Atheros AR5213A schliesslich erledigt die Drahtloskommunikation. Das Betriebssystem wird auf einer CompactFlash-Karte installiert.

Das Betriebssystem beschreibt die CPU wie folgt:

$ cat /proc/cpuinfo processor : 0 vendor_id : Geode by NSC cpu family : 5 model : 9 model name : Unknown stepping : 1 cpu MHz : 266.579 fdiv_bug : no f00f_bug : no coma_bug : no fpu : yes fpu_exception : yes cpuid level : 2 wp : yes flags : fpu tsc msr cx8 cmov mmx cxmmx bogomips : 88.47 clflush size : 32 cache_alignment : 32 address sizes : 32 bits physical, 32 bits virtual power management:

Das System

Um das WRAP nicht mit unnötigem Ballast zu quälen sollte die Software möglichst genau auf das System und den Einsatz als WLAN-Router abgestimmt sein. Insbesondere brauchen wir:

Die ganze Software wird auf einem Drittrechner für das WRAP kompiliert, einerseits um Zeit zu sparen und andererseits um etwaige Huhn-Ei-Probleme zu umschiffen.

Partitionierung

Bevor wir loslegen müssen wir die Speicherkarte vorbereiten. Das selbstgebaute System wird recht wenig Speicherplatz belegen, ein paar Megabytes sollten reichen. Ich hatte noch eine 64-MB-Karte aus einer alten Photokamera herumliegen und habe darum diese gewählt; auf all dem überflüssigen Platz können wir noch eine zweite Kopie des Betriebssystem installieren, für Notfälle oder Wartungsarbeiten.

Die Karte wird etwa so partitioniert:

Das sieht dann folgendermassen aus:

$ fdisk -l /dev/sdx Disk /dev/sdx: 61.3 MiB, 64225280 bytes, 125440 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/sdx1 2048 43007 40960 20M 83 Linux /dev/sdx2 43008 83967 40960 20M 83 Linux /dev/sdx3 83968 124927 40960 20M 83 Linux

Danach formatieren wir die Partitionen und konfigurieren die Dateisysteme:

$ mkfs.ext3 /dev/sdx1 $ mkfs.ext3 /dev/sdx2 $ mkfs.ext3 /dev/sdx3 $ tune2fs -o ^user_xattr,^acl -i 0 /dev/sdx1 $ tune2fs -o ^user_xattr,^acl -i 0 /dev/sdx2 $ tune2fs -o ^user_xattr,^acl -i 0 /dev/sdx3

Die CompactFlash-Karte ist nun bereit um bespielt zu werden.

Bootloader

Als Bootloader verwenden wir GNU GRUB, zur Zeit ist Version 2.02 aktuell. Bereits beim Kompilieren können wir einige unnötige Features deaktivieren und mit der Angabe des Präfix sicherstellen, dass der WRAP-GRUB nicht die Dateien des GRUB unserer Kompiliermaschine überschreibt:

$ ./configure --disable-liblzma --disable-device-mapper --disable-efiemu --prefix=/tmp/grub

Danach wird GRUB mit make und make install installiert. Falls auf einem allzu modernen System kompiliert wird ist ein kleiner Patch mit Anpassungen nötig; alternativ sollte auch die jeweils aktuelle GIT-Version von GRUB funktionieren.

Nach dem Kompilieren können wir den Bootloader auf die CompactFlash-Karte installieren. Dazu binden wir die erste Partition ein:

$ mount /dev/sdx1 /mnt/cf

Danach wird das Installationsskript (als root) aufgerufen. Die Angabe des Boot-Verzeichnisses verhindert dabei wieder, dass bestehende Dateien verändert werden und die explizite Liste der zu installierenden Module sorgt dafür, dass GRUB statt seiner vollständigen Modulsammlung lediglich die gelisteten Module installiert; das spart Speicherplatz und auch Zeit beim Start:

$ ./grub-install --locales= --boot-directory=/mnt/cf/ /dev/sdx \ --install-modules="ext2 part_msdos serial terminfo normal linux"

Schliesslich kommt noch die GRUB-Konfigurationsdatei auf die CF-Karte. Mit dieser Konfiguration ist GRUB über die serielle Konsole zu steuern und beide Betriebssysteme können aus dem Menü gestartet werden:

$ cat /mnt/cf/grub/grub.cfg serial --speed=57600 terminal_input serial terminal_output serial set timeout_style=countdown set timeout=2 insmod part_msdos insmod ext2 menuentry 'buildroot' { set root='hd0,msdos1' linux /bzImage-3.16 console=ttyS0,57600n8 root=/dev/sda2 ro notsc } menuentry 'buildroot (recovery)' { set root='hd0,msdos1' linux /bzImage-3.16 console=ttyS0,57600n8 root=/dev/sda3 ro notsc }

Kernel

Die genaue Kernel-Version spielt keine grosse Rolle, alle Treiber für das WRAP sind schon lange dabei. Wichtig ist, dass wir einen aktuellen LTS-Kernel mit allen Sicherheitspatches einsetzen, hier exemplarisch die aktuellste Version von Kernel 3.16. Kernel-Konfigurationen für verschiedene Versionen finden sich auf git, beim Einsatz anderer oder zusätzlicher Kernel-Versionen ist die GRUB-Konfiguration entsprechend anzupassen bzw. zu ergänzen.

Da sich die Regeln bezüglich Drahtlosübertragung (Frequenzbänder, Sendestärke) von Land zu Land unterscheiden wacht normalerweise auf GNU/Linux-Systemen der CRDA-Dienst darüber, dass die jeweiligen Gesetze eingehalten werden. Um uns diesen Dienst zu sparen kopieren wir vor dem Kompilieren die statische Liste der erlaubten Frequenzbänder nach net/wireless/db.txt.

Danach können wir den Kernel kompilieren. Den fertig kompilierten Kernel kopieren wir zu den GRUB-Dateien auf der ersten Partition der CF-Karte. Das sieht dann folgendermassen aus:

$ ls -1 /mnt/cf/ bzImage-3.16 grub lost+found

Nun werfen wir die Partition wieder aus:

$ umount /mnt/cf

User-Space

Unser eigentliches Betriebssystem kommt von Buildroot, einer sparsamen Distribution die für den Einsatz auf Geräten mit begrenzten Ressourcen spezialisiert ist. Ähnlich wie schon beim Linux-Kernel werden auch bei Buildroot die (meisten) Optionen in einer zentralen Konfigurationsdatei verwaltet und mit make menuconfig bearbeitet.

Meine Buildroot-Konfiguration für WRAP sieht zwei zusätzliche Verzeichnisse vor: overlay beinhaltet von Hand angepasste Dateien die ebenfalls im fertigen System landen, custom_config enthält Konfigurationsschnipsel die nicht in der Hautpkonfigurationsdatei verwaltet werden können, zur Zeit lediglich eine Option von busybox. Die beiden Verzeichnisse sind auf git zu finden, die Konfigurationsdatei ebenfalls; letztere muss vor dem Gebrauch in .config umbenannt werden.

Meine Buildroot-Konfiguration ist noch in folgenden Punkten anzupassen:

Nach dem Kompilieren mit make sollte in output/images/rootfs.tar unser frisch kompiliertes System bereitstehen. Dieses können wir nun (wieder als root) auf die beiden leeren Partitionen schreiben:

$ mount /dev/sdx2 /mnt/cf $ tar -C /mnt/cf -xf output/images/rootfs.tar $ umount /mnt/cf $ mount /dev/sdx3 /mnt/cf $ tar -C /mnt/cf -xf output/images/rootfs.tar $ umount /mnt/cf

Danach ist die CF-Karte bereit.

System starten

Die fertig beschriebene Karte bauen wir nun ins WRAP ein. Damit wir sehen können ob alles korrekt funktioniert verwenden wir die serielle Konsole. Die korrekten Parameter für das WRAP sind:

Falls die BIOS-Meldungen nicht sichtbar sind ist die Geschwindigkeit der seriellen Schnittstelle im BIOS wahrscheinlich falsch eingestellt. Der Standardwert beim WRAP ist 38400 bps, es können aber auch 9600 bps eingestellt sein – da hilft nur ausprobieren.

Das Gerät sollte je nach CF-Karte nach ca. 15 – 25 Sekunden fertig gestartet haben und ist dann bereit für seinen Einsatz als WLAN-Router. Meines hängt an einem rudimentären Kabelanschluss der lediglich 10 Mbps liefert, da passt das WRAP perfekt und liefert ebenso viel Leistung wie dies ein aktueller Router auch täte, ist für Updates jedoch nicht auf den guten Willen eines Hardware-Herstellers angewiesen und wird auch nicht vorzeitig geplant obsolet.

Und wunderschön rot ist es auch.