[Tutorial] Virtueller Pi — Crosscompiler für den Raspberry Pi

Hallo zusammen,
heute bauen wir uns (unter Ubuntu) einen virtuellen Raspberry Pi.
Warum sollte man das tun? Hauptsächlich weil man dann eine Umgebung hat, in der man Software für den Pi kompilieren kann. Klar kann man auch auf dem Pi direkt kompilieren, aber dann hat man eben nur die relative schwache Hardware des Pis zur Verfügung; gerade umfangreichere Kompilate dauern entweder extrem lange (gerade beim Linken werden teils extrem große Mengen RAM gebraucht..) oder gehen halt gar nicht. Alle solchen Beschränkungen kann man aufheben, wenn man sich eine virtuelle Umgebung aufbaut, die man auf dem Rechner seiner Wahl ausführen kann.
Bei unserer hier vorgestellten Methode gibt es außerdem den Vorteil, dass man sich aus dem Festplattenimage, in dem sich alles abspielen wird, direkt eine bootbare Version erstellen kann, die man dann auf eine SD-Karte ziehen kann und direkt im Pi verwenden kann. D.h. man kann sich auf einem schnelleren Rechner eine Umgebung seiner Wahl zusammenstellen und das dann unverändert auf den Pi kopieren.
Hört sich interessant an? Na dann: weiterlesen 🙂

Zum groben Überblick noch: Was werden wir gleich alles tun?

  • Wir bauen uns einen Crosscompiler, den wir benutzen um einen ARM-fähigen Linux-Kernel zu erzeugen. Wir werden auch eine zweite Variante vorstellen, bei der man einfach einen vorhandenen Crosscompiler runter lädt..
  • Wir bauen ein RootFS und erzeugen daraus ein Festplattenimage.
  • Wir bauen Qemu, um das Festplattenimage mit dem Kernel auf dem Rechner unserer Wahl ausführen zu können.
  • Wir richten die virtuelle Pi-Umgebung so ein, dass man startbereit für eigene Kompilate ist.

Crosscompiler erzeugen: Variante A — Selbst kompilieren mit crosstool-ng

  • Crosstool-ng laden, entpacken, bauen und installieren: wget http://crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.17.0.tar.bz2
    tar xf crosstool-ng-1.17.0.tar.bz2
    cd crosstool-ng-1.17.0 && ./configure --prefix=${HOME}/pi_cross && make && sudo make install
    (Ich mag es immer ganz gern, nicht direkt Pakete zu installieren, sondern das alles den Paketmanager verwalten zu lassen. Mit sudo checkinstall kann man sich das „sudo make install“ sparen, stattdessen wir ein DEB gebaut, dass danach mittels dpkg installiert wird und später auch wieder sauber deinstalliert werden kann.)
  • Einen temporären Ordner anlegen –hier werden alle für den Bau des Crosscompilers benötigten Ressourcen gespeichert, entpackt und bearbeitet–, hinein wechseln und das Config-Programm aufrufen: mkdir ${HOME}/cross-stage && cd ${HOME}/cross-stage && ct-ng menuconfig
  • Dort dann Folgendes auswählen:
    • In „Paths and misc options“: „Try features marked as EXPERIMENTAL.“ aktivieren
    • Hier wird auch der Zielpfad eingetragen bzw. wir lassen „Prefix directory“ wie es ist, merken nur, dass es da ist 🙂
    • In „Target options“: „Target architecture“ auf „arm“ setzen
    • In „Operating system“: „Target OS“ auf „linux“ setzen
    • In „Binary utilities“: binutils-Version auf „2.21.1a“ setzen
    • In „C Compiler“: „Show Linaro versions (EXPERIMENTAL)“ aktivieren
    • Dort im „gcc version“-Feld „linaro-4.6-2012.10 (EXPERIMENTAL)“ aktivieren
    • Speichern
  • ct-ng build ausführen und ein klein wenig warten..
  • Der fertige Compiler sollte dann in: ~/x-tools/arm-unknown-linux-guneabi/bin liegen.
  • Um den Compiler zu testen, kann man jetzt ein kleines Programm bauen und dann versuchen, es auf dem Pi auszuführen:
    cd ~
    cat > test.c
    #include
    int main() { printf("Hello, world!n"); return 0; }
    ^D
    ~/x-tools/arm-unknown-linux-guneabi/bin/arm-unknown-linux-gnueabi-gcc -o test test.c
    scp test pi@192.168.1.110:/home/pi
    ssh pi@192.168.1.110
    ./test

Crosscompiler erzeugen: Variante B — Vorhandenen Crosscompiler runterladen

  • mkdir ${HOME}/pi_cross/src
    cd ${HOME}/pi_cross/src
    wget https://sourcery.mentor.com/sgpp/lite/arm/portal/package8734/public/arm-none-eabi/arm-2011.03-42-arm-none-eabi-i686-pc-linux-gnu.tar.bz2
    tar xf arm-2011.03-42-arm-none-eabi-i686-pc-linux-gnu.tar.bz2

Qemu kompilieren und startklar machen

  • Verschiedene Abhängigkeiten installieren, nicht nur für Qemu:
    sudo aptitude install libpixman-1-dev libglib2.0-dev libglib2.0-dev debootstrap
  • Qemu runterladen, kompilieren, installieren:
    mkdir -p ${HOME}/pi_cross/src
    cd ${HOME}/pi_cross/src
    git clone git://git.qemu-project.org/qemu.git
    cd qemu
    ./configure --target-list=arm-softmmu,arm-linux-user --prefix=${HOME}/pi_cross/tools
    make
    sudo make install
  • Qemu-System installieren:
    sudo add-apt-repository ppa:linaro-maintainers/tools
    sudo aptitude update
    sudo aptitude install qemu-system

Linux-Kernel für Arm kompilieren:

  • Kernel runterladen, entpacken und das Config-Programm startencd ${HOME}/pi_cross/src
    wget http://www.kernel.org/pub/linux/kernel/v3.0/linux-3.0.4.tar.bz2
    tar xf linux-3.0.4.tar.bz2
    wget http://thoronir.net/raspi-dev/linux-arm.patch
    patch -p1 -d linux-3.0.4/ < linux-arm.patch
    cd linux-3.0.4
    make ARCH=arm versatile_defconfig
    make ARCH=arm menuconfig
  • Kernel konfigurieren:
    • Crosscompiler einstellen:General Setup —> Cross-compiler tool prefix

      Bei mir steht da dann: “/home/maw/pi_cross/src/arm-2011.03/bin/arm-none-eabi-”

    • Richtige CPU wählen:System Type —>
      [*] Support ARM V6 processor
      [*] ARM errata: Invalidation of the Instruction Cache operation can fail
    • ARM EABI aktivieren:Kernel Features —>
      [*] Use ARM EABI to compile the kernel
      [*] Allow old ABI binaries to run with this kernel
    • Qemu Disk unterstützen:
      Bus Support —>
      [*] PCI Support
      Device Drivers —>SCSI Device Support —>
      [*] SCSI Device Support
      [*] SCSI Disk Support
      [*] SCSI CDROM support
      [*] SCSI low-lever drivers —>
      [*] SYM53C8XX Version 2 SCSI support
    • devtmpfs aktivieren:
      Device Drivers —>Generic Driver Options—>
      [*] Maintain a devtmpfs filesystem to mount at /dev
      [*] Automount devtmpfs at /dev, after the kernel mounted the root
    • tmpfs aktivieren:
      File systems —>Pseudo filesystems—>
      [*] Virtual memory file system support (former shm fs)
    • Event Interface aktivieren:
      Device Drivers —>Input device support—>
      [*] Event interface
  • Kernel kompilieren:make ARCH=arm

RootFS vorbereiten:

  • mkdir -p ${HOME}/pi_cross/rootfs/debian_armhf
    cd ${HOME}/pi_cross/rootfs
    sudo debootstrap --foreign --arch armhf wheezy debian_armhf http://ftp.debian.org/debian
    cd ${HOME}/pi_cross/src/linux-3.0.4
    sudo make ARCH=arm INSTALL_MOD_PATH=../../rootfs/debian_armhf modules_install

    cd ${HOME}/pi_cross/roots
    qemu-img create pi_disk.img 3000M
    mkfs.ext2 -F pi_disk.img
    sudo mkdir mnt
    sudo mount -o loop pi_disk.img mnt
    sudo cp debian_armhf/* mnt -a
    sudo umount mnt
    cp ../src/linux-3.0.4/arch/arm/boot/zImage .

VM vorbereiten:

  • VM starten:sudo qemu-system-arm -M versatilepb -cpu arm1176 -m 256 -hda pi_disk.img -kernel zImage -append "root=/dev/sda rw init=/bin/bash" -serial stdio
  • In der VM dann ausführen:
    mount /proc /proc -t proc
    ./debootstrap/debootstrap --second-stage
    printf "auto eth0niface eth0 inet dhcpn" >> etc/network/interfaces
    echo "raspberry-pi" > /etc/hostname
    passwd
  • VM ausschalten
  • VM neustarten mit:sudo qemu-system-arm -M versatilepb -cpu arm1176 -m 256 -hda pi_disk.img -kernel zImage -append "root=/dev/sda" -serial stdio
  • Aptitude mit Paketquellen versorgen:printf "deb http://ftp.debian.org/debian/ squeeze main contrib non-freendeb-src http://ftp.debian.org/debian/ squeeze main contrib non-free" > /etc/apt/sources.list
    aptitude update
  • Ein paar wahrscheinlich benötigte Pakete installieren:
    aptitude install build-essential libssl-dev checkinstall

VM für Dateiaustausch einrichten:

  • VM für Dateiaustausch starten mit: sudo qemu-system-arm -M versatilepb -cpu arm1176 -m 256 -hda pi_disk.img -kernel zImage -append "root=/dev/sda" -serial stdio -redir tcp:2222::22Die IP der VM findet man raus, indem man auf dem Host ifconfig eingibt, und die „inet Adresse“ von virbr0 nimmt.
  • In der VM dropbear (oder einen anderen beliebigen SSH Server deiner Wahl) installieren:aptitude install dropbear
  • Per SSH sollte man nun vom Host aus die VM erreichen können mit: ssh -p 2222 root@192.168.0.101
  • SCP sollte so gehen: scp -P 2222 bla.file root@192.168.0.101:~

VM benutzen:

  • Starten kann man ab jetzt die VM mit:sudo qemu-system-arm -M versatilepb -cpu arm1176 -m 256 -hda pi_disk.img -kernel zImage -append "root=/dev/sda" -serial stdio

Wie man nun diese VM auf eine SD-Karte bekommt, wird hier erklärt.

Viel Spaß beim kompilieren 😉

Und wie immer gilt, falls das Tutorial gefallen hat würde ich mich über einen kleinen Kommentar freuen – das gleiche gilt natürlich auch für Kritik oder Verbesserungsvorschläge 😀 Natürlich dürft ihr auch gerne euren Adblocker auf Kopfkino deaktivieren und den kleinen Banner am Ende des Posts klicken – ist aber natürlich absolut freiwillig 😉 Die Werbung ist dezent gehalten und es gibt keine nervigen Flashbanner oder ähnliches 🙂 Einnahmen kommen vollständig neuen Projekten zu Gute 😀

 

#sources
link1: http://www.bootc.net/archives/2012/05/26/how-to-build-a-cross-compiler-for-your-raspberry-pi/
link2: http://www.cnx-software.com/2011/10/18/raspberry-pi-emulator-in-ubuntu-with-qemu/

2 Kommentare zu „[Tutorial] Virtueller Pi — Crosscompiler für den Raspberry Pi

  1. Hab mich ziemlich weit durchgekämpft. (Methode B)
    Hier die changes:
    Aus aptitude mach apt-get
    Zusätzlich erforderlich: sudo apt-get install ncurses-dev
    Den SYM53C8XX Version 2 SCSI support hab ich nicht gefunden
    Kernel kompilieren klappt leider nicht… Er bleibt mit „nicht erkannten Kommandozeilenoptionen“ hängen. „Littel endian“ „mno-thumb-interwork“
    Dazu kommen noch kerne-bounds Fehler (unbekanntes ABI (aapcs-linux), falscher Wert (armv5t) und strongarm — weiß leider nicht mehr weiter.
    Gruß Walter.

    • a) aptitude muss vorher auch über apt-get installiert werden, aber das ist im Zusammenhang natürlich egal..
      b) Benutzt du genau die Crosscompiler- bzw. Kernelversion wie im Artikel angegeben? (Der Artikel hat schon ein paar Monate auf dem Buckel – mit aktuelleren Versionen wird sicher das ein oder andere, v.a. natürlich der spezielle Patch nicht mehr funktionieren.) Die verschiedenen Einstellungen sollten, wenn die entsprechenden Versionen (v.a. natürlich Kernelversion) benutzt werden, eigentlich schon vorhanden sein..
      c) Wie lautet denn die Fehlermeldung *genau* und welches Kommando hast du direkt davor eingegeben?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

*

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre mehr darüber, wie deine Kommentardaten verarbeitet werden.