Skip to main content

Read Only Real-Time Linux: Eine Beispielumsetzung für den Raspberry Pi

More
10 years 2 weeks ago - 9 years 10 months ago #49 by Rainer Poisel
Kurzfassung

In einem der letzten Artikel wurde erläutert, wie ein echtzeitfähiger Linux-Kernel erstellt werden kann. Darauf aufbauend soll das System derart modifiziert werden, dass nie auf die eingebundenen Datenträger, wie z. B. die SD-Karte geschrieben wird. Natürlich ist es möglich persistente Datenspeicher einzubinden, auf denen Daten dauerhaft abgelegt werden können.

Als Nebeneffekt wird gezeigt, wie binäre Dateien fremder Architekturen auf dem lokalen System ausgeführt werden können. Im konkreten Fall werden Binaries für die ARM-Architektur auf einem x86_64 System ausgeführt.

Hinweis: Nutzung des Tutorials, sowie des Beispiel-Abbilds bitte auf eigene Gefahr. Ich habe die Beschreibung nach bestem Wissen und Gewissen ausgeführt, übernehme jedoch keine Haftung bei Nutzung, Nachmachen, usw.!

Übrigens: Alle Kommandos, mit Ausnahme der gekennzeichneten, können ohne Root-Rechte ausgeführt werden. Schützen Sie ihr System und verwenden sie sudo, su, usw. nur dann, wenn es wirklich notwendig ist!

Einführung

Das Verhindern von Schreibvorgängen auf die gewünschten Datenträger bzw. -bereiche wird durch zweierlei Maßnahmen erreicht. Einerseits werden Datenbereiche im read-only Modus in das laufende System eingehängt. Andererseits wird über die nur-lesbaren Bereiche eine transparente RAM-Disk gelegt in die alle Schreiboperationen "umgebogen" werden. Hinsichtlich der potentiellen Dateisysteme bieten sich unionfs, overlayfs, AUFS, usw. an. Im Rahmen dieses Artikels wird auf die Verwendung von AUFS eingegangen.

Installationsschritte

Die Installation lässt sich in 3 Teilbereiche untergliedern:
  1. Patchen des Linux-Kernels (PREEMPT_RT, AUFS)
  2. Erstellen einer initial RAM-Disk
  3. Konfiguration des Linux-Systems, sowie des Startvorganges

Als Vorlage für dieses Tutorial dient der Artikel " aufs root filesystem " von "kinsa". Zusätzlich zu den im genannten Tutorial erwähnten Schritte wird der Kernel auf den Echtzeiteinsatz vorbereitet und erklärt, wie sich das System auf elegante Weise aktualisieren lässt.

Patchen des Linux-Kernels

Im ersten Schritt werden einige der im referenzierten HowTo " Echtzeitfähige Linux-Systeme: Eine Beispielumsetzung anhand des Raspberry Pi's " angeführten Schritte ausgeführt: Klonen des Raspberry Pi Kernel Git-Repositoriums und Einspielen des PREEMPT_RT Patches .
Code:
git clone --depth=1 https://github.com/raspberrypi/linux.git linux-raspberrypi wget https://www.kernel.org/pub/linux/kernel/projects/rt/3.12/patch-3.12.26-rt40.patch.xz xz -d -c ../patch-3.12.26-rt40.patch.xz | patch --dry-run -p 1

Hinweis: Der eingesetzte Patch muss zur Kernel-Version passen. Es ist möglich, dass es in der Zwischenzeit bereits eine neuere Version gibt als die hier referenzierte!

Der Patch lässt sich bis auf einen kleinen Teil erfolgreich anwenden.
Code:
xz -d -c ../patch-3.12.26-rt40.patch.xz | patch -p 1

Bei den aktuellen Kernel-Versionen lässt sich der Fehler beim Patchen durch folgendes Kommando beheben:
Code:
echo 'obj-$(CONFIG_HWLAT_DETECTOR) += hwlat_detector.o' >> `find . -type f -iname '*.rej' | sed 's/.rej//'`

Nun können die AUFS-Patches eingespielt werden:
Code:
# Downloaden des AUFS Source-Codes git clone git://aufs.git.sourceforge.net/gitroot/aufs/aufs3-standalone.git cd aufs3-standalone git checkout remotes/origin/aufs3.12.x # Einspielen der Patches cp -a fs ../linux-raspberrypi cp include/uapi/linux/aufs_type.h ../linux-raspberrypi/include/uapi/linux cd ../linux-raspberrypi patch -p1 < ../aufs3-standalone/aufs3-kbuild.patch patch -p1 < ../aufs3-standalone/aufs3-base.patch patch -p1 < ../aufs3-standalone/aufs3-mmap.patch patch -p1 < ../aufs3-standalone/aufs3-standalone.patch

Das Übersetzen des Kernels erfolgt mit den im referenzierten Artikel erläuterten Kommandos:
Code:
export CROSS_COMPILE=/usr/local/toolchains/gcc-arm-bcm2708/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin/arm-linux-gnueabihf- export ARCH=arm make mrproper make bcmrpi_defconfig make xconfig

Folgende Kernel-Optionen müssen aktiviert bzw. fix in den Kernel einkompiliert sein (also NICHT als Modul):
CONFIG_PREEMPT_RT_FULL=yEchtzeiterweiterungen
CONFIG_HIGH_RES_TIMERS=yNotwendig für die Echtzeiterweiterungen
AUFS_FS=yUnterstützung für das AUFS
AUFS_BR_HFSPLUS=nwird nicht benötigt
CONFIG_BLK_DEV_INITRD=yUnterstützung für Initial RAM-Disks

Das eigentliche Übersetzen des Kernels passiert idealerweise in einem Terminal-Multiplexer, wie z. B. tmux , sodass ein versehentliches Schließen des Terminal-Fensters nicht zum Abbruch des Kompilierens führt.
Code:
tmux make -j <Anzahl-CPU-Kerne + 1>

Während des Übersetzens kann bei Bedarf das Tutorial zur Verwendung von tmux zu Gemüte geführt werden.

Nach Beendigung des Kompiliervorganges steht das neue Kernel-Abbild im Verzeichnis arch/arm/boot/ zur Verfügung. Dieses wird im Folgenden in das Abbild einer Linux-Distribution transferiert. Als Vorlage dient " PipaOS " - eine etwas aktuellere und abgespecktere Variante der Raspbian Distribution.
Code:
wget "http://pipaos.mitako.eu/download/pipaos-2.6-tiny500mb.img.gz" gunzip pipaos-2.6-tiny500mb.img.gz # Installieren der sleuthkit Dateisystem-Tools (z. B. mmls) apt-get install sleuthkit mmls pipaos-2.6-tiny500mb.img

Das 'mmls'-Kommando hat folgende Ausgabe zur Folge:
Code:
DOS Partition Table Offset Sector: 0 Units are in 512-byte sectors Slot Start End Length Description 00: Meta 0000000000 0000000000 0000000001 Primary Table (#0) 01: ----- 0000000000 0000002047 0000002048 Unallocated 02: 00:00 0000002048 0000116735 0000114688 Win95 FAT32 (0x0c) 03: ----- 0000116736 0000118783 0000002048 Unallocated 04: 00:01 0000118784 0000993279 0000874496 Linux (0x83) 05: ----- 0000993280 0000993999 0000000720 Unallocated

Es lässt sich daraus ableiten, dass die Boot-Partition bei Sektor 2048, und das Root-Dateisystem bei Sektor 118784 beginnt. Mit Hilfe dieser Informationen kann das Dateisystem direkt aus dem Image in das laufende System eingehängt und modifiziert werden. Die Kommandos erfordern Root-Rechte!
Code:
# root werden sudo su - mkdir -p /mnt/{boot,root} modprobe loop mount -o rw,loop,offset=$((2048*512)) <pfad-zum-image>/pipaos-2.6-tiny500mb.img /mnt/boot mount -o rw,loop,offset=$((118784*512)) <pfad-zum-image>/pipaos-2.6-tiny500mb.img /mnt/root

Das Ergebnis des Kernel-Compiles kann nun in das Abbild übertragen werden (Root-Rechte erforderlich!)
Code:
cp arch/arm/boot/zImage /mnt/boot/kernel-rt-aufs.img

Dies gilt auch für die Kernel-Module:
Code:
# ohne root-Rechte make INSTALL_MOD_PATH=../modules.rt modules_install # mit root-Rechten cp -a ../modules.rt/* /mnt/root

Zur Verwendung des neuen Kernels, sowie zum Setzen der erforderlichen Kernel-Parameter müssen zwei Dateien der Boot-Partition angepasst werden:
Code:
# Nutzen des neuen Abbilds sed -i 's/^kernel/#kernel/' /mnt/boot/config.txt echo "kernel=kernel-rt-aufs.img" >> /mnt/boot/config.txt echo "# set initial ramdisk" >> /mnt/boot/config.txt echo "initramfs initrd.gz" >> /mnt/boot/config.txt # Setzen der Kernel-Parameter sed -i 's/$/ ro lapic sdhci_bcm2708.enable_llm=0 rwfs=tmpfs/' /mnt/boot/cmdline.txt

Damit sind die Anpassungen auf der Boot-Partition bereits abgeschlossen. Diese kann nun (mit root-Rechten) ausgehängt werden.
Code:
umount /mnt/boot

In den nächsten Schritten wird erklärt, wie die Initial RAM-Disk erstellt und in das System eingebunden wird. Weiters wird erläutert, welche Anpassungen am Betriebssystem notwendig sind und wie dieses im Bedarfsfalle aktualisiert werden kann.

Zusammenfassung und nächste Schritte

tbd.
Last edit: 9 years 10 months ago by Rainer Poisel.

Please Anmelden or Create an account to join the conversation.

Powered by Kunena Forum