Yohann Martineau, blog

Posts from 2009-10

Compiler un firmware de clubinternet box

2009-10-29 14:48:36
Date originale : 5 février 2007

Bonjour,
voici un petit tutorial pour compiler un firmware de clubinternet box, et ainsi pouvoir peronnaliser les fonctions de sa boîte.

Les différentes étapes à suivre sont les suivantes :

  • récupérer les sources du firmware de la clubinternet box (dans mon cas le modèle est AH4222, mais celà devrait être assez proche pour un modèle AH4021),
  • installer la chaîne de compilation fournie,
  • corriger les petites erreurs des sources fournies,
  • compiler les sources et créér une image de système de fichier à flasher sur la ROM de la boîte,
  • transférer cette image sur la boîte.
Cet article décrit la marche à suivre pour compiler ces sources depuis un système GNU/Linux, plus particulièrement Debian Etch.

Obtention des sources

Pour pouvoir compiler les sources, il faut d'abord les obtenir les sources du firmware de la clubinternet box sont disponibles ici. Les versions du firmware doivent à priori évoluer souvent, donc il est possible que ce lien ne marche pas éternellement. En revanche, lorsque ces sources sont mises à disposition du public, une annonce est effectuée sur le forum technique de club-internet, dans la rubrique "Modem ADSL et Téléphonie clubinternet.box et AH-4021". Cette anonce est acutellement intitulée "Code source du firmware Hitachi (V44)", elle contient un lien vers les sources du firmware.

L'accueil des forums de club-internet est accessible ici. Attention, ces sources font quand même environ 84Mo, prévoir un peu de temps pour les télécharger, donc.

Deuxième étape : exploration du contenu de cette archive.

Cette archive contient elle-même deux autres archives et un script d'installation. Une des deux archives (bcm963xx_AH4222.01.2.01L.300L01.V44-08_consumer.tar.gz) contient véritablement le code source du firmware et la seconde archive (bcm963xx_uclibc_crosstools_3.4.2_0.9.27.tar.gz) contient la chaîne de compilation (uclibc) nécessaire pour compiler les sources du firmware avec la bonne cible.

La chaîne de compilation est fournie sous forme de deux paquets rpm, si vous utilisez une distribution gerrant directement les rpm (Mandriva, RedHat, Suse, etc.) vous pouvez vous contenter de lancer le script d'installation en root. L'installation à partir du script d'installation "consumer_install" va créér deux répertoires sous /opt. Si, en revanche vous avez une distribution utilisant des paquets au format debian (Debian, Ubuntu, etc.), comme c'est mon cas, il va falloir décompresser l'archive contenant les deux rpms, puis transformer ces paquets RPM en paquets deb.

Pour cela, on peut utilser le programme alien accouplé à rpm pour générer des paquets .deb à partir de paquets .rpm. La commande suivante, lancée en root permet donc d'installer les programmes nécessaires :

# apt-get install alien rpm

Ensuite pour convertir les paquets il suffit de lancer alien avec en paramètre le paquet à convertir.

# alien uclibc-crosstools-mips.i386.rpm
# alien -scripts uclibc-crosstools-common.i386.rpm

Attention : il faut rajouter l'option -scripts pour le paquet uclibc-crosstools-common.i386.rpm car ce paquet contient des scripts de post-installation, de pré-installation, ou d'un autre type, mais il est nécessaire d'inclure ces scripts dans le paquet généré (pas fait par défaut).

Deux paquets sont normalement disponibles au format .deb maintenant. Pour les installer, il suffit donc de lancer la commande suivante en root :

# dpkg -i *.deb

Les sources du firmware n'utilisent pas directement l'emplacement par défaut de la chaîne de compilation, il est donc nécessaire de rajouter un lien vers la chaîne :

# ln -s /opt/toolchains /opt/toolchains_3_00
Victoire ! La chaîne de compilation est désormais installée, et opérationnelle !

Patchs à effectuer

Avant de se casser les dents sur la compilation, mieux vaut effectuer quelques modifications dans les sources fournies.

Tout d'abord, il est nécessaire de patcher la génération de configuration du noyau linux. Il faut modifier le fichier suivant :

/opt/bcm963xx_router/kernel/linux/scripts/kconfig/mconf.c
Dans ce fichier, il faut remplacer toutes les occurences de current_menu par un autre nom non déjà pris, par exemple current_mconf_menu.

Ensuite, il faut patcher le système de gestion de la configuration de la clubinternet box.

Dans le fichier :

/opt/bcm963xx_router/userapps/broadcom/cfm/util/system/syscall.c
Supprimer les références à sha1.h, c'est à dire :
  • supprimer la ligne #include "sha1.h"
  • supprimer tout ce qu'il y a après la ligne :
    /********************** end base64 decode and encode functions **********************/
Cela correspond aux méthodes liées à sha1.h dont l'implémentation n'est pas fournie.

Compilation

Ouf, la compilation va maintenant pouvoir commencer.

Les cibles disponibles pour la compilation sont présentes dans le répertoire targets des sources du firmware, désormais installées dans /opt/bcm963xx_router. Dans notre cas, il y a un répertoire 96348GWV ou similaire qui nous donne le nom de la cible à passer en paramètre à la compilation.

La commande à taper (toujours en root) pour lancer la compilation est donc la suivante :

# make PROFILE=96348GWV
Là, on croise bien fort les doigts et quelques minutes plus tard, une image de disque ROM a été générée et est prête à être transférée dans la mémoire de la clubinternet box. Si la compilation s'est bien passée, un message l'indique en donnant le nom de l'image du système de fichier à ralonge qui a été générée. Dans mon cas le nom de l'image générée est la suivante :
bcm96348GWV_fs_kernel_AH4222.01.2.01.300L01.V44-08.mgcp.dspApp3341_fxo.LE9500-070204_1656

Transfert de l'image

Maintenant que nous avons notre image, le plus dûr à été effectué. Il reste tout de même à installer sur sa machine un serveur tftp pour pouvoir transférer l'image sur la boîte. En effet, lorsque la boîte effectue ses mises à jour en tant normal, elle transfert son image en utilisant un client tftp un peu allégé. Ce client récupère en tant normal l'image sur le site suivant : tftp-ht.voip.club-internet.fr mais nous allons désormais lui faire utiliser notre machine, sur laquelle vient d'être générée une image toute neuve.

Sous debian, il suffit d'utiliser la commande apt-get install tftpd pour installer un serveur tftp, il doit certainement y avoir l'équivalent pour les distributions au format rpm. La racine du serveur tftp sous debian se trouve dans /srv/tftp, il suffit donc de copier l'image générée dans ce répertoire.

Ensuite on peut se connecter via telnet à la clubinternet box :

$ telnet 192.168.1.1
L'utilisateur est root, et le mot de passe est clubadmin. Une fois connecté, une invite de commande commançant par > s'affiche. Il est désormais possible de transférer l'image et de la flasher immédiatement avec la commande suivante :
> tftp -g -f bcm96348GWV_fs_kernel_AH4222.01.2.01.300L01.V44-08.mgcp.dspApp3341_fxo.LE9500-070204_1656 192.168.1.2
-g est l'option correspondant à get
-f pour spécifier le nom du fichier distant à transférer et l'adresse de la machine sur laquelle on est à passer à la fin (éventuellement à adapter)

Si vous vous trompez de fichier ou que vous ne spécifiez pas une image valide à transférer, la clubinternet box va le détecter et à son prochain reboot, elle téléchargera l'image du firmware depuis le site de club-internet.

Après le "flashage", la boîte redémarre, il faut lui laisser quelques minutes, et si après ces quelques minutes vous pouvez vous connecter à internet, c'est gagné ! vous avez réussi à installer votre image de système de fichier sur la boîte !

Personnaliser sa boîte

Maintenant que nous savons compiler notre image et la transférer sur la boîte, nous allons (enfin) pouvoir commencer à faire des choses amusantes avec la boîte. Nous allons réalser les étapes suivantes :

  • écrire un "Hello world" en c,
  • le compiler au bon format,
  • placer le binaire au bon endroit,
  • recompiler l'image,
  • la transférer,
  • tester notre super programme.
Ecrire un fichier helloworld.c :
#include

int main() {
  printf("Hello, world!\n");
  return 0;
}
C'est rudimentaire, mais très utile pour pouvoir effectuer des tests simples.

Maintenant, nous pouvons compiler notre premier programme avec la chaîne de compilation :

/opt/toolchains/uclibc-crosstools/bin/mips-uclibc-gcc helloworld.c
Nous avons donc maintenant un fichier binaire a.out. Ce fichier est au format MIPS, nous pouvons le vérifier avec la commande suivante :
# file a.out
a.out: ELF 32-bit MSB executable, MIPS, MIPS-I version 1 (SYSV), dynamically linked (uses shared libs), not stripped

Une fois que nous avons ce fichier binaire exécutable sur la clubinternet box, nous pouvons le placer au bon endroit dans l'arborescence du système de fichier utilisé pour créér l'image de disque ROM :

# cp a.out /opt/bcm963xx_router/targets/fs.src/usr/bin
les fichiers exécutables que l'on génère sont à placer dans /usr/bin dans /opt/bcm963xx_router/targets/fs.src et non dans /bin, car ces programmes ne concernent pas le fonctionnement du système directement. Et surtout des vérifications sont effectuées lors de la compilation sur la suppression des entêtes et autres données "inutiles" (strip) dans le programme sous forme de fichier binaire.
Maintenant, tout est prêt pour regénérer l'image de disque ROM (une nouvelle image est générée et l'ancienne n'est pas écrasée). Voir plus haut. Idem pour le transfert de l'image.

Une fois que l'image a été générée, on peut déjà vérifier que rien n'a été cassé en essayant de se connecter à internet. Si tout fonctionne, nous pouvons continuer et tester notre programme.
Il faut donc à nouveau se connecter sur la boite (telnet 192.168.1.1 root/clubadmin). Mais maintenant que l'invite en > apparaît, nous allons lancer un shell pour pouvoir exécuter notre programme. Il suffit de taper la commande suivante :

> sh

BusyBox v1.00 (2007.02.04-15:52+0000) Built-in shell (msh)
Enter "help" for a list of built-in commands.

#
Nous pouvons maintenant enfin lancer notre programme hors du commun avec la commande suivante :
# /usr/bin/helloworld
Hello, world!
#
Victoire, nous pouvons exécuter le code que nous voulons sur la boîte !!!

Remarques

Un client http (wget) est directement fourni sur la boîte, nous aurions donc pu simplement compiler le programme, le mettre sur un serveur web et le transférer avec wget a.out en le plaçant dans la partition /var accessible en écriture sur la boîte, puis le rendre exécutable (chmod 755) et le lancer directement. En revanche, le fait d'insérer notre programme dans /var limite sa taille fortement (en général, entre 50 et 150 ko sont disponibles dans /var), alors que la ROM de la club internet box peut contenir jusqu'à 4,2Mo de données. Mais surtout /var n'est pas l'endroit adequat pour l'exécution des programmes sous linux.

Voilà, j'espère que ce petit tutorial aura pu vous aider...

Permanent link
linux, internet, embedded systems, development, français

Comments