Cross-compiling 101

Geschrieben von MMind am Donnerstag, 11. November 2010 in Allgemein

Das Kompilieren eines bootfähigen Kernels für ein "embedded"-System ruft immer wieder den Geist des Cross-Kompilierens auf den Plan. Dabei wird der Kernel nicht auf dem Zielsystem selbst, sondern auf einem anderen Host mit einer anderen Prozessor-Architektur erstellt.

Nun gibt es bereits dutzende Howtos zu diesem Thema, und trotzdem habe ich festgestellt, dass ich immer eine größere Menge Browser-Tabs benötige, bis ich die entsprechenden Informationen wieder zusammen habe. Deswegen sind die folgenden Punkte eher für mich zum Nachschlagen gedacht - aber vieleicht helfen sie später auch mal jemand anderem.

Mal sehen, ob das jetzt mit dem „Erweiterten Eintrag“ von Serendipity klappt …

Das Ganze richtet sich jetzt vornehmlich an Debian-Benutzer, es dürfte aber nicht weiter schwierig sein, das meiste an andere Distributionen anzupassen. Weiterhin ist unsere Zielarchitektur armel [ARM EABI], d.h. wir werden nur entsprechende Cross-Compiler-Pakete für diese installieren.

Notwendige Pakete

Die Cross-Compiler-Umgebung wird vom emdebian-Projekt bereits als fertig Paketsammlung bereitgestellt, so dass wir nur einen Eintrag dafür in der sources.list benötigen:

deb http://www.emdebian.org/debian/ testing main

Die Pakete sind nun schnell installiert.

apt-get update && apt-get install libc6-armel-cross libc6-dev-armel-cross libdebian-dpkgcross-perl libgcc1-armel-cross libstdc++6-4.3-dev-armel-cross libstdc++6-armel-cross linux-libc-dev-armel-cross binutils-arm-linux-gnueabi cpp-4.3-arm-linux-gnueabi g++-4.3-arm-linux-gnueabi gcc-4.3-arm-linux-gnueabi gcc-4.3-arm-linux-gnueabi-base gcc-4.4-arm-linux-gnueabi-base

Da wir nur manuell einen Kernel kompilieren, reicht es bis hierher schon. Wenn aber Debian-Pakete cross-kompiliert werden sollen, geht die Anleitung auf der entsprechenden emdebian Wiki-Seiten weiter.

Kernel konfigurieren und bauen

Der Kernel wird wie immer mit

make ARCH=arm menuconfig
konfiguriert. Wichtig ist dabei für die Architektur „armel“ nur, dass die Option für die „ARM EABI“ aktiviert wird. Dann den Kernel kompilieren:
make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi vmlinux
Danach noch modules statt vmlinux (oder welcher Image-Typ auch immer gewählt wurde) als make-Ziel angeben, und es sollte nach einiger Warterei ein Kernel-Image nebst Modulen dabei herauskommen.

uzImage erstellen

Der Oyo scheint ein Kernel-Image auch von der SD-Karte laden zu können. Wie das genau geht, weiß ich noch nicht, habe aber nach längerer Suche herausgefunden, was nun überhaupt ein uzImage ist und vor allem, wie man eins erzeugt. Auch in dem Foren-Beitrag den ich gefunden habe, wird die Konvertierung eher als Voodoo empfunden, weswegen ich diese hier auch einfach nur mal so aufnehme:

arm-linux-gnueabi-objcopy -O binary -R .note -R .comment -S vmlinux linux.bin

mkimage -A arm -O linux -T kernel -C gzip \
   -a 0x00008000 -e 0x00008000 -n "Linux Kernel Image" \
   -d linux.bin.gz uzImage
Vermutlich passen die ganzen Werte noch nicht so richtig auf den Oyo – das wird sich aber hoffentlich noch finden.

Update: Das vermeintliche uzImage ist nur ein einfaches zImage was ich beim Stöbern in den Firmwares der Geschwistergeräte entdeckt habe. Also ist der ganze letzte Absatz eingentlich hinfällig und es reicht ein einfaches

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi zImage

Ebenso interessant zu wissen wäre, wie man den Oyo dazu bringt, diesen Kernel dann zu booten. :-)

Und noch ein Update:

Module erstellen

Da man zweckmässigerweise nicht alle Funktion fest in den Kernel einbaut folgt noch das erzeugen der zugehören Kernel-Module. Dies erfolgt mittels:

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi modules

Der eigentliche Kniff liegt dann darin die Module an einer Stelle zu sammeln. Ein einfaches modules_install möchte die Module nach /lib/modules/KERNEL_VERSION installieren was an dieser Stelle falsch ist. Nach etwas Sucherei habe ich dann den entsprechenden Parameter gefunden der die Module in ein anderes Verzeichnis kopiert. Mittels

make ARCH=arm modules_install INSTALL_MOD_PATH=/tmp
würden die Module beispielsweise nach /tmp/lib/modules/KERNEL_VERSION kopiert. Von dort kann man sie dann einfach auf das Zielgerät übertragen.


2 Kommentare für diesen Eintrag

Ansicht der Kommentare: Linear | Verschachtelt

  • Anonym
    Kann man statt make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi vmlinux und anschliessendem arm-linux-gnueabi-objcopy nicht gleich make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi uImage bzw. make ARCH=arm CROSS_COMPILE=arm-linux-gnueabi uzImage starten ?
  • MMind
    natürlich, nur die Anleitung die zu dem uzImage führte sprach vom vmlinux-Ziel um es dann nachzubearbeiten. Ausgehend davon, dass wir hier noch im Nebel stochern kann man ja eh noch nicht sagen was nun eigentlich richtig ist.

1 Trackback für diesen Eintrag

Kommentar schreiben

Umschließende Sterne heben ein Wort hervor (*wort*), per _wort_ kann ein Wort unterstrichen werden.
Standard-Text Smilies wie :-) und ;-) werden zu Bildern konvertiert.
Die angegebene E-Mail-Adresse wird nicht dargestellt, sondern nur für eventuelle Benachrichtigungen verwendet.

Um maschinelle und automatische Übertragung von Spamkommentaren zu verhindern, bitte die Zeichenfolge im dargestellten Bild in der Eingabemaske eintragen. Nur wenn die Zeichenfolge richtig eingegeben wurde, kann der Kommentar angenommen werden. Bitte beachten Sie, dass Ihr Browser Cookies unterstützen muss, um dieses Verfahren anzuwenden.
CAPTCHA

Suche

Nach Einträgen suchen in Outside the Walled Garden:

Das Gesuchte nicht gefunden? Gib einen Kommentar in einem Eintrag ab oder nimm per E-Mail Kontakt auf!