Compilation de Linux avec une toolchain embarquée native

Publié par cpb
Juil 10 2011

Nous avons compilé dans le précédent article une toolchain embarquée native, c’est-à-dire la chaîne de compilation qui pourra s’exécuter sur une cible embarquée (à processeur Arm dans notre cas) et qui sera susceptible de produire du code pour ce même processeur Arm.

Nous allons valider le fonctionnement de cette chaîne de compilation en lui soumettant un gros morceau de code : le noyau Linux.

Pour cela, commençons par copier les sources du noyau sur la cible. Pour cela, j’ai inséré la carte micro-SD de la Pandaborard directement dans le PC de compilation, et j’y télécharge le noyau :

[~]# cd /media/root/root/
[root]# wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.tar.gz
--2011-07-10 01:41:36--  http://www.kernel.org/pub/linux/kernel/v2.6/linux-2.6.39.tar.gz
[...]
2011-07-10 01:43:12 (984 KB/s) - “linux-2.6.39.tar.gz” saved [95993809/95993809]
[root]# cd ../..
[media]# umount /media/*oot

Puis, je démarre la Pandaboard (après y avoir réinséré la mémoire flash) et je m’y connecte.

[media]# telnet 192.168.3.152
Trying 192.168.3.152...
Connected to 192.168.3.152.
Escape character is '^]'.
(none) login: root
Password:
BusyBox v1.18.4 (2011-06-22 12:27:46 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
[PANDABOARD]$ cd /root/
[PANDABOARD]$ ls
hello                hello.c              linux-2.6.39.tar.gz
[PANDABOARD]$

Nous retrouvons l’exemple “hello” de l’article précédent. La version de tar que j’ai compilée dans ma Busybox ne connaît pas les options “z” ou “j” pour décompresser les archives .gz ou .bz2. Aussi je décompresse d’abord manuellement le fichier.

[PANDABOARD]$ gunzip  linux-2.6.39.tar.gz 
[PANDABOARD]$ tar xf linux-2.6.39.tar 
[PANDABOARD]$

Étant donné que je cherche à valider ma chaîne de compilation, et non ma configuration du noyau, je vais utiliser comme fichier de configuration .config celui de mon système en cours de fonctionnement. Pour cela, je vais utiliser l’entrée /proc/config.gz qui permet de récupérer la configuration du noyau en marche. Cette entrée n’est pas toujours disponible – notamment la plupart des distributions ne la proposent pas – et c’est dommage. Pour activer la présence de /proc/config.gz, il faut activer l’option “Kernel .config Support” dans le menu “General Setup” lors de la compilation du noyau.

[PANDABOARD]$ cd linux-2.6.39/
[PANDABOARD]$ zcat /proc/config.gz > .config
[PANDABOARD]$

Avant de lancer la compilation, il est nécessaire de mettre la carte Pandaboard à l’heure. Par défaut elle s’initialise à l’heure Unix zéro (1er janvier 1970 à minuit), et la commande make se basant sur les horodatages des fichiers, la compilation peut poser des problèmes.

[PANDABOARD]$ date -s 2011.07.10-02:00
Sun Jul 10 02:00:00 UTC 2011
[PANDABOARD]$

La commande make oldconfig génère les fichiers de dépendances à partir du .config existant. Il est possible d’éditer le fichier .config à la main pour y faire d’éventuelles modifications (la commande habituelle make menuconfig ne fonctionnera pas à cause de l’absence de la biblipthèque nCurses sur la cible). Entre autre, l’option CONFIG_LOCALVERSION= peut être renseignée pour indiquer un nom spécifique à ajouter en suffixe au numéro de noyau. Ici j’ai utilisé la chaîne pandanatif.

[PANDABOARD]$ make ARCH=arm oldconfig
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/basic/docproc
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/kxgettext.o
  SHIPPED scripts/kconfig/zconf.tab.c
  SHIPPED scripts/kconfig/lex.zconf.c
  SHIPPED scripts/kconfig/zconf.hash.c
  HOSTCC  scripts/kconfig/zconf.tab.o
  HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf --oldconfig Kconfig
#
# configuration written to .config
#
[PANDABOARD]$

Nous lançons la compilation en tirant parti des deux coeurs de la Pandaboard, en demandant à make de paralléliser son travail sur quatre jobs.

[PANDABOARD]$ make ARCH=arm -j 4 
scripts/kconfig/conf --silentoldconfig Kconfig
  CHK     include/linux/version.h
  UPD     include/linux/version.h
  CHK     include/generated/utsrelease.h
[...] 
  LD [M]  net/bluetooth/bluetooth.ko
  AS      arch/arm/boot/compressed/piggy.gzip.o
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready
[PANDABOARD]$

Nous avons obtenu ici une “zImage”, c’est-à-dire une image brute compressée et préfixée par un petit auto-décompresseur. Toutefois, le bootloader de la carte Pandaboard attend une uImage, une image formatée pour U-boot. Pour l’obtenir il suffit de le demander à la chaine de compilation du noyau. Toutefois celle-ci s’appuie sur un petit utilitaire, mkimage, qui n’est pas présent sur le système minimal construit avec Busybox.
Pour compiler mkimage, nous devons télécharger les sources de U-boot et y chercher ce petit outil. Téléchargeons les sources dans le répertoire /root de notre cible (en montant la carte micro-SD sur l’hôte de développement).

[root]# cd /media/root/root/
[root]# wget ftp://ftp.denx.de/pub/u-boot/u-boot-2011.06.tar.bz2
--2011-07-10 08:09:50--  ftp://ftp.denx.de/pub/u-boot/u-boot-2011.06.tar.bz2
[...]
2011-07-10 08:10:00 (996 KB/s) - “u-boot-2011.06.tar.bz2” saved [8469694]
[root]# cd ../..
[media]# umount /media/*oot
[media]#

Après avoir redémarré la Pandaboard (et pensé à la remettre à l’heure) préparons les sources de U-Boot :

[PANDABOARD]$ cd /root/
[PANDABOARD]$ bunzip2 u-boot-2011.06.tar.bz2
[PANDABOARD]$ tar xf u-boot-2011.06.tar
tar: warning: skipping header 'g'
[PANDABOARD]$

La compilation que nous lançons n’a pour unique but que la préparation de l’utilitaire mkimage. Je vous conseille de vous connecter sur un second terminal, et de surveiller le répertoire /root/u-boot-2001-06/tools. Dès que l’exécutable mkimage est présent, on peut arrêter la compilation complète de U-Boot.

[PANDABOARD]$ make OMAP4_PANDA_config
awk '(NF && $1 !~ /^#/) { print $1 ": " $1 "_config; $(MAKE)" }' boards.cfg > .boards.depend
Generating include/autoconf.mk
Generating include/autoconf.mk.dep
Configuring for omap4_panda board...
[PANDABOARD]$ make
Generating include/autoconf.mk
Generating include/autoconf.mk.dep
gcc -DDO_DEPS_ONLY 
                -g  -Os   -fno-common -ffixed-r8 -msoft-float   -D__KERNEL__ -DCONFIG_SYS_TEXT_BASE=0x80e80000 -I/root/u-boot-2011.06/include -fno-builtin -ffreestanding -nostdinc -isystem /usr/lib/gcc/arm-unknown-linux-uclibcgnueabi/4.3.5/include -pipe  -DCONFIG_ARM -D__ARM__ -marm  -mabi=aapcs-linux -mno-thumb-interwork -march=armv5 -Wall -Wstrict-prototypes -fno-stack-protector   
                -o lib/asm-offsets.s lib/asm-offsets.c -c -S
[...]
drivers/video/libvideo.o drivers/watchdog/libwatchdog.o fs/cramfs/libcramfs.o fs/ext2/libext2fs.o fs/fat/libfat.o fs/fdos/libfdos.o fs/jffs2/libjffs2.o fs/reiserfs/libreiserfs.o fs/ubifs/libubifs.o fs/yaffs2/libyaffs2.o lib/libfdt/libfdt.o lib/libgeneric.o lib/lzma/liblzma.o lib/lzo/liblzo.o lib/zlib/libz.o net/libnet.o post/libpost.o board/ti/panda/libpanda.o --end-group /root/u-boot-2011.06/arch/arm/lib/eabi_compat.o -L /usr/lib/gcc/arm-unknown-linux-uclibcgnueabi/4.3.5 -lgcc -Map u-boot.map -o u-boot
objcopy -O srec u-boot u-boot.srec
objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
[PANDABOARD]$

Notre utilitaire étant prêt, installons-le dans un répertoire système, puis retournons dans les sources de Linux pour obtenir une uImage.

[PANDABOARD]$ cp tools/mkimage /usr/bin/
[PANDABOARD]$ cd /root/linux-2.6.39/
[PANDABOARD]$ make uImage
  CHK     include/linux/version.h
  CHK     include/generated/utsrelease.h
make[1]: `include/generated/mach-types.h' is up to date.
  CALL    scripts/checksyscalls.sh
  CHK     include/generated/compile.h
  Kernel: arch/arm/boot/Image is ready
  SHIPPED arch/arm/boot/compressed/lib1funcs.S
  AS      arch/arm/boot/compressed/lib1funcs.o
  LD      arch/arm/boot/compressed/vmlinux
  OBJCOPY arch/arm/boot/zImage
  Kernel: arch/arm/boot/zImage is ready
  UIMAGE  arch/arm/boot/uImage
Image Name:   Linux-2.6.39-pandanatif
Created:      Sun Jul 10 08:30:58 2011
Image Type:   ARM Linux Kernel Image (uncompressed)
Data Size:    3048144 Bytes = 2976.70 kB = 2.91 MB
Load Address: 80008000
Entry Point:  80008000
  Image arch/arm/boot/uImage is ready
[PANDABOARD]$

Installons le noyau sur la partition de boot en la montant dans l’arborescence et en y copiant la nouvelle uImage.

[PANDABOARD]$ mount /dev/mmcblk0p1 /mnt/
[PANDABOARD]$ cp /mnt/uImage /mnt/uImage-precedent
[PANDABOARD]$ cp arch/arm/boot/uImage /mnt/
[PANDABOARD]$ umount /dev/mmcblk0p1 
[PANDABOARD]$ reboot
Connection closed by foreign host.
[media]#

Après redémarrage de la carte Pandaboard, re-connectons nous et vérifions la version du noyau en fonctionnement…

[media]# telnet 192.168.3.152
Trying 192.168.3.152...
Connected to 192.168.3.152.
Escape character is '^]'.
(none) login: root
Password:
BusyBox v1.18.4 (2011-06-22 12:27:46 CEST) built-in shell (ash)
Enter 'help' for a list of built-in commands.
[PANDABOARD]$ uname -a
Linux (none) 2.6.39-pandanatif #1 SMP Sun Jul 10 02:36:03 UTC 2011 armv7l GNU/Linux
[PANDABOARD]$

Et voilà ! Notre cible embarquée est devenue relativement autonome, puisqu’elle est capable de fonctionner sur un noyau recompilé sur cette même cible. Ceci nous permet de valider le fonctionnement de la chaîne de compilation obtenue dans l’article précédent. Remarquons toutefois que cette toochain pourrait être étendue car nous n’avons intégré aucun outil de débogage (gdb, gdbserver, etc.)

Une réponse

  1. fcollet dit :

    Bonjour,

    Je lis vos articles avec beaucoup d’intérêts, j’ai en revanche quelques questions :
    – Avez-vous tenter de compiler le kernel 3.0 ; celui-ci intègre le hardware spinlock pour les processeurs OMAP4? quelles sont les avantages/inconvénients d’activer cette option?
    – Avez-vous tenter de compiler le noyau et les utilitaires avec l’option hardware float? l’OMAP4 étant capable d’effectuer des opérations sur les nombres flottants.

    Merci encore de nous faire partager vos compétences en matière de linux embarqué.

URL de trackback pour cette page