Fonera 2 : Personnaliser, compiler, regénérer OpenWRT
Nous allons voir dans cet article l'environnement de développement de OpenWRT (kamikaze). Étant un système embarqué, OpenWRT est souvent destiné à fonctionner sur des architectures différentes de votre machine de bureau. Pour cela il faut mettre en place un environnement de cross-compilation permettant de compiler des binaires pour une architecture différente. Pour la Fonera, par exemple, il me faut générer des binaires MIPS à partir d'une machine x86.
L'équipe d'OpenWRT propose plusieurs outils qui permettent de réaliser cette tâche, réputée compliquée, avec une facilité indécente. Nous allons passer en revue ces différents outils de manière à trouver celui en adéquation avec chaque besoin. Tout au long nous prendrons en exemple la Fonera.
Selon ce que vous voulez faire, vous n'aurez pas besoin d'installer l'environnement complet de développement. Nous pouvons distinguer trois niveaux en fonction de la tâche :
- ImageBuilder pour générer un firmware personnalisé ;
- le SDK pour compiler de nouveaux paquets ;
- BuildRoot qui est l'environnement complet.
Les deux premiers sont en fait des version allégées et adaptées du 3ème.
ImageBuilder
Avec ImageBuilder, nous allons pouvoir adapter la distribution OpenWRT à nos besoins (le filesystem pour être précis). Typiquement pour ajouter des paquets non présents dans la version de base, en retirer, préparer une configuration spécifique ... Cet outil vient donc avec des versions binaires de tous les paquets standards.
Pour la Fonera et kamikaze 7.09, vous le téléchargez ici. Prenez le fichier ImageBuilder correspondant à votre architecture de développement (i686 ou x86_64).
Pour ajouter un paquet :
$ cp /tmp/hello_1-1_mips.ipk packages/ $ make image PACKAGES="hello"
Pour ajouter des fichiers, construisez votre arborescence dans un répertoire (par exemple /tmp/files/etc/monfichier.conf)
$ make image FILES="/tmp/files"
et monfichier.conf sera ajouté au répertoire etc de votre image.
$ make help
vous explique tout cela.
Note: Il semble que les Profiles ne fonctionnent pas avec ImageBuilder.
SDK
Le SDK va nous permettre de compiler de nouveaux paquets pour OpenWRT. Il inclu donc les binaires de compilation croisées (mips-linux-uclibc-gcc par exemple) qui vont vous permettre de générer des exécutables MIPS à partir d'une machine PC. Nous pouvons donc l'utiliser pour générer des paquets existants avec une configuration différente voir créer carément de nouveaux paquets.
Vous le téléchargez au même endroit mais cette fois il s'agit du fichier SDK. De même décompressez le dans un répertoire de travail.
Deux erreurs ?
Avant d'aller plus loin, chez moi j'ai rencontré deux erreurs lors du make avec le SDK Kamikaze 7.09 pour Atheros.
$ make /bin/sh: Syntax error: "&" unexpected make: *** [world] Erreur 2
Bizarement celle-la se résoud en augmentant le niveau de verbosité :
$ make V=99
à chaque fois que vous utilisez make
Deuxième erreur :
make: option requires an argument -- C Usage: make [options] [target] ... Options: -b, -m Ignored for compatibility. -B, --always-make Unconditionally make all targets. -C DIRECTORY, --directory=DIRECTORY Change to DIRECTORY before doing anything. ...
Il suffit de remplacer le ; par un . à la ligne 79 du Makefile :
xargs -n1 $(MAKE) compile -C. \\
Ce qui est étrange, c'est que je n'ai pas ces problèmes avec le BuildRoot.
Ajouter un paquet existant
Pour générer un paquet que vous n'avez pas, il vous suffit de copier le répertoire source dans package et de taper make à la racine du SDK.
Avant de vous lancer dans la création d'un nouveau paquet, je vous invite à aller voir si quelqu'un ne s'en ai pas déjà chargé. Dans le cas contraire, suivez le guide ...
Hello world!
Pour commencer essayons de générer le fameux Hello world!. Positionnez vous dans le répertoire du SDK puis :
$ cd tmp $ cat > hello.c #include <stdio.h> int main (int argc, char * argv) { printf ("Hello world!\\n"); return 0; } ^D
Compilons le et exécutons le sur la Fonera[1] :
$ ../staging_dir_mips/bin/mips-linux-uclibc-gcc hello.c -o hello -I../staging_dir_mips/include $ scp hello root@fonera:/tmp $ ssh root@fonera /tmp/hello Hello world!
Construire un paquet
Bon, c'est bien joli, mais ça manque d'automatisation. Nous allons en faire un paquet. Créez les répertoires hello/src dans le dossier package du SDK et copiez y hello.c.
Voici donc les sources de notre paquet. Maintenant il faut créer un fichier de contrôle pour que le SDK sache comment générer et installer nos fichiers. Créons donc un fichier Makefile situé dans package/hello. Il doit contenir :
include $(TOPDIR)/rules.mk PKG_NAME:=hello PKG_RELEASE:=1 PKG_VERSION:=1 PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-$(PKG_VERSION) include $(INCLUDE_DIR)/package.mk define Package/hello SECTION:=utils CATEGORY:=Utilities TITLE:=hello DESCRIPTION:=The Hello World endef define Build/Compile mkdir -p $(PKG_BUILD_DIR) $(CP) ./src/* $(PKG_BUILD_DIR)/ $(TARGET_CC) $(PKG_BUILD_DIR)/hello.c -o $(PKG_BUILD_DIR)/hello ## $(MAKE) CC=$(TARGET_CC) -C $(PKG_BUILD_DIR) endef define Package/hello/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/hello $(1)/usr/bin endef $(eval $(call BuildPackage,hello))
Voyons rapidement la syntaxe : au début et dans la section Package/hello on renseigne des variables décrivant le paquet (nom, versions, description ...).
Dans la section Build/Compile, la manière de compiler les sources. Copie des fichiers dans le répertoire de compilation et appel du compilateur croisé (TARGET_CC). Notez aussi la ligne en commentaire qui servirait dans le cas ou on aurait un Makefile pour les sources.
Enfin viens la section Package/hello/install qui indique quels fichiers installer ou. Création de /usr/bin et copie de hello dedans.
Vous pouvez trouver une description plus détaillée du format de fichier dans la doc BuildRoot. Enfin, il faut signaler que le SDK est capable de télécharger automatiquement des sources[2] simplifiant encore le fichier de contrôle.
Je vous invite aussi à aller voir les sources pour pleins d'exemples.
Une fois ceci fait, positionnez vous à la racine du SDK et tapez simplement :
$ make
le SDK va détecter les nouveaux packages et lancer le processus de génération de ceux-ci. Une fois terminé, vous trouverez les fichiers .ipk dans bin/packages. Il ne vous reste plus qu'a le copier sur la Fonera pour l'installer.
$ scp bin/packages/hello_1-1_mips.ipk root@fonera:/tmp $ ssh root@fonera ... root@OpenWrt:~# ipkg install hello_1-1_mips.ipk root@OpenWrt:~# hello Hello world!
\\o/ Youhou !
Vous trouverez ici les sources et binaires
Buildroot
Alors la, c'est du lourd. L'environnement complet de développement, vous allez pouvoir tout recompiler et hacker le noyau comme des petits fous. :) Comme il s'agit d'un sur-ensemble des deux outils précédents, vous pouvez bien sur utiliser BuildRoot pour simplement compiler un package ou générer un filesystem perso. A noter qu'une très bonne documentation est disponible.
Génération
Pour récupérer le BuildRoot Kamikaze 7.09, faites simplement :
$ svn co https://svn.openwrt.org/openwrt/tags/kamikaze_7.09/
ou alors :
$ wget http://downloads.openwrt.org/kamikaze/7.09/kamikaze_7.09.tar.bz2 && tar xvjf kamikaze_7.09.tar.bz2
Les gentils dev d'OpenWRT nous ont concocté un joli menu pour configurer tout ceci :
$ make menuconfig
Vous pouvez alors choisir la cible, quelques options de configuration, les images à générer et les paquets à inclure dans votre image. Vous pouvez aussi reconstruire ImageBuilder et le SDK. Si vous voulez changer des options du noyau[3], utilisez :
$ make kernel_menuconfig
Pour la Fonera, choisissez Atheros [2.6] comme cible.
Enfin, il est temps de compiler/générer tout cela. tapez simplement :
$ make
et allez raconter 12 histoires à vos enfants. Chez moi (Athlon XP 1600+) ça a mis 1h30. Toutes les sources nécessaires sont téléchargées, patchées, le compilateur croisé est construit ainsi que le noyau et le filesystem. A la fin, vous trouvez ce qui vous intéresse dans le répertoire bin.
$ ls bin/ openwrt-atheros-2.6-root.jffs2-128k openwrt-atheros-2.6-vmlinux.elf openwrt-atheros-2.6-root.jffs2-256k openwrt-atheros-2.6-vmlinux.gz openwrt-atheros-2.6-root.jffs2-64k openwrt-atheros-2.6-vmlinux.lzma
Lors des prochains make seules les parties nécessaires seront reconstruites. En particulier le compilateur ne sera pas recompilé à chaque fois. :)
A noter quelques autres répertoires intéressants :
- build_mips : contient tout ce qui a été compilé et généré. En particulier build_mips/root le système de fichiers ;
- staging_dir_mips : le cross-compiler ;
- package : les sources des paquets (fichiers de contrôle, patchs ...) ;
- dl : les sources téléchargées lors de la construction.
Packages
Pour ajouter votre propre package, procédez comme avec le SDK. Puis lors du menuconfig, sélectionnez le simplement.
Fichiers
Si vous voulez ajouter des fichiers à cette image, créez un répertoire files. Par exemple pour changer la configuration réseau par défaut :
mkdir -p files/etc/config cat > files/etc/config ## Attention, il manque lo !! config interface lan option ifname eth0 option proto dhcp option hostname fonera
Lors du prochain make, BuildRoot remplacera la configuration réseau de package/base_files par la votre.
Émulation MIPS
Autant vous prévenir tout de suite, il ne semble pas possible d'émuler votre Fonera, même si quelques travaux existent.
Par contre, il est possible de lancer un programme MIPS sur votre PC :
$ cd /data/OpenWrt/kamikaze_7.09/build_mips/ $ qemu-mips -L /data/OpenWrt/kamikaze_7.09/build_mips/root root/bin/busybox
avec le SDK et notre programme hello ci-dessus :
$ qemu-mips -L /data/OpenWrt/OpenWrt-SDK-atheros-2.6-for-Linux-i686/staging_dir_mips/ hello
Cela peut vous permettre de tester quelques commandes. Mais à priori pour le kernel, il vous faudra flasher.
Visiblement il existe pleins d'émulateurs MIPS mais je n'ai pas eu le courage d'en tester d'autres.
Voila, nous sommes maintenant capables de
- ajouter des fichiers et des paquets dans une image sans rien recompiler ;
- compiler des programmes, des paquets et en faire de nouveaux ;
- regénerer un OpenWrt complet noyau y compris.
Nous voila prêts pour de nouvelles aventures au prochain épisode, porter open2300 sur la Fonera et lui donner accès au port série.
Liens
La doc de WhiteRussian, plutôt obsolète.
La doc de Kamikaze :
- BuildRoot
- Personnaliser Kamikaze chez Nantes Wireless
- Building OpenWrt Kamikaze from source avec les targets spéciaux
- Emuler du x86
- Moteur de recherche de paquets ipkg