mardi 26 juin 2012

On va faire du custom (partie 1)

Introduction

La plupart des utilisateurs utiliseront leur carte avec une distribution Linux adaptée, telle que Debian squeeze ou Arch Linux pour ne citer qu'eux (disponible en téléchargement sur le site de raspberry pi). Elles offrent la possibilité d'avoir une suite complète de logiciel pour l'administration du système, la programmation, le multimédia et autres.
Ces distributions nécessitent d'avoir une carte SD avec une taille adaptée, environ 2 Go minimum.

Je vais partir du postulat que je n'ai ni le besoin, ni l'envie, d'utiliser ce genre de distribution. Pour cela, je vais me construire un environnement minimaliste pour ma carte.

Cet environnement sera constitué d' :
  • Une chaine de compilation croisée
  • Un bootloader
  • Un Noyau Linux
  • Un système de fichiers (avec tout ce qui va bien dedans, ex : busybox, etc ...)
Dans cette première partie, On va s’intéresser à la construction de notre système et la deuxième partie abordera la mise en route de notre système sur la carte.

 

Buildroot

    Je vais utiliser un outil, Buildroot, qui me permettra de construire mon environnement. Buildroot est la réunion de plusieurs outils permettant de construire un système embarqué complet. Il a la capacité de pouvoir constuire, séparément ou pas, les différents éléments essentiels (cité plus haut) d'un système embarqué.

    La version de buildroot utilisée est elle aussi custom et y inclut les caractéristiques de la raspberry pi.

    Récupération de Buildroot :
    # git clone git://github.com/nezticle/RaspberryPi-BuildRoot.git Buildroot

    Une fois les différents objets récupérés, voila à quoi ressemble notre dossier  :
    # ls -al
    drwxr-xr-x   7 sinseman44 sinseman44  4096 2012-06-06 18:57 board
    drwxr-xr-x  10 sinseman44 sinseman44  4096 2012-06-06 18:57 boot
    -rw-r--r--   1 sinseman44 sinseman44 60374 2012-06-06 18:57 CHANGES
    -rw-r--r--   1 sinseman44 sinseman44 11980 2012-06-06 18:57 Config.in
    drwxr-xr-x   2 sinseman44 sinseman44  4096 2012-06-06 18:57 configs
    -rw-r--r--   1 sinseman44 sinseman44 17987 2012-06-06 18:57 COPYING
    drwxr-xr-x   2 sinseman44 sinseman44 28672 2012-06-13 16:52 dl
    drwxr-xr-x   4 sinseman44 sinseman44  4096 2012-06-06 18:57 docs
    drwxr-xr-x  14 sinseman44 sinseman44  4096 2012-06-06 18:57 fs
    drwxr-xr-x   2 sinseman44 sinseman44  4096 2012-06-06 18:57 linux
    -rw-r--r--   1 sinseman44 sinseman44 24050 2012-06-06 18:57 Makefile
    drwxr-xr-x   2 sinseman44 sinseman44  4096 2012-06-07 22:15 output
    drwxr-xr-x 497 sinseman44 sinseman44 65536 2012-06-06 18:57 package
    -rw-r--r--   1 sinseman44 sinseman44  2128 2012-06-06 18:57 README.md
    drwxr-xr-x   7 sinseman44 sinseman44  4096 2012-06-06 18:57 support
    drwxr-xr-x   5 sinseman44 sinseman44  4096 2012-06-06 18:57 target
    drwxr-xr-x  10 sinseman44 sinseman44  4096 2012-06-06 18:57 toolchain

    Petite explication des différents fichiers/dossiers principaux de buildroot :
    • board : Scripts et fichiers de configuration spécifiques pour chaque carte (un dossier pour chaque système embarqué).
    • boot : Fichiers de configuration et de compilation des bootloaders sélectionnables.
    • dl : Dossier de téléchargement des packages sélectionnés.
    • configs : Fichiers de configuration de buildroot pour différents systèmes.
    • fs : Fichiers de configuration et de création du système de fichiers.
    • linux : Fichiers de configuration et de configuration du noyau linux.
    • output : Dossier de sortie de l'environnement (images systèmes).
    • package : Fichiers de configuration et de compilation des différents packages sélectionnables.
    • toolchain : Fichiers de configuration et de compilation des chaines de compilation croisée.
    Certains fichiers de configuration de mon environnement diffèrent de la version originale pour le bon fonctionnement de la carte. Je vous propose mon fichier de configuration buildroot à placer dans le dossier configs et mon fichier de configuration crosstool-ng et l'inittab à placer dans le dossier board/raspberrypi.

    On va commencer par configurer l'environnement pour la carte raspberry pi (cette commande est à taper que la première fois que vous installez buildroot), tapez la commande :
    # make raspberrypi_sinseman44_defconfig

    Il est possible de configurer et compiler notre environnement dans un dossier autre que celui de buildroot, pour cela, taper la commande :
    # mkdir -p /home/sinseman44/raspberrypi_output
    # make raspberrypi_sinseman44_defconfig O=/home/sinseman44/raspberrypi_output
    

    Si vous décidez d'utiliser cette commande, la compilation et le choix des paquets se fera à partir de ce dossier créé et non plus à partir du dossier de buildroot. Ex:
    # cd /home/sinseman44/raspberrypi_output
    # make menuconfig ou make
    

    Maintenant, on va choisir les outils à installer sur le système (Le fichier defconfig utilisé précédemment configure l'environnement et les paquets à installer sur le système, normalement, cette commande est à utiliser que si vous souhaitez modifier la configuration) , tapez la commande :
    # make menuconfig


    Ce menu principal offre la possibilité de configurer indépendamment, chaque élément pour notre système (chaîne de compilation croisée, Noyau Linux, bootloader, type de système de fichiers et packages).

    Les différents paquets, classés en catégories, sont accessibles dans le sous-menu Package Selection for the target.


    Après la configuration, on va compiler ....
    La commande magique est :
    # make
    
    [ ... BLABLABLA ... ]
    [INFO ]  Performing some trivial sanity checks
    [INFO ]  Build started 20120626.091634
    [INFO ]  Building environment variables
    [INFO ]  =================================================================
    [INFO ]  Retrieving needed toolchain components' tarballs
    [00:16] / 
    [ ... BLABLABLA ... ]
    

    A cet instant là, on peut se détendre, ça peut prendre un moment (quelques minutes, voir quelques dizaines de minutes en fonction de la machine hôte, ex: sur un Core 2 duo, je met entre 45 minutes et 1 heure de compilation).

    On devrait finir sur cette dernière action sans erreur.
    >>>   Generating root filesystem image rootfs.tar
    rm -f /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/build/_fakeroot.fs
    echo "chown -R 0:0 /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/target" >> /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/build/_fakeroot.fs
    cat target/generic/device_table.txt  > /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/build/_device_table.txt
    echo -e '\n \n \n \n \n \n \n /bin/busybox                       f 4755 0 0 - - - - -\n/usr/share/udhcpc/default.script f 755  0 0 - - - - -\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n' >> /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/build/_device_table.txt
    echo "/home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/host/usr/bin/makedevs -d /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/build/_device_table.txt /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/target" >> /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/build/_fakeroot.fs
    echo " tar -c""f /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/images/rootfs.tar -C /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/target ." >> /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/build/_fakeroot.fs
    chmod a+x /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/build/_fakeroot.fs
    /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/host/usr/bin/fakeroot -- /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/build/_fakeroot.fs
    rootdir=/home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/target
    table='/home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/build/_device_table.txt'
    gzip -9 -c /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/images/rootfs.tar > /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/images/rootfs.tar.gz
    
    #

    Pour finir, toutes les éléments de notre système vont se trouver dans le dossier output :
    # ls -al output
    drwxr-xr-x 104 sinseman44 sinseman44 20480 2012-06-25 20:50 build/
    drwxr-xr-x   4 sinseman44 sinseman44  4096 2012-06-22 13:05 host/
    drwxr-xr-x   2 sinseman44 sinseman44  4096 2012-06-22 22:08 images/
    lrwxrwxrwx   1 sinseman44 sinseman44   102 2012-06-25 21:44 staging -> /home/sinseman44/WORK/raspberry_pi/buildroot-2012.05/output/host/usr/arm-unknown-linux-gnueabi/sysroot/
    drwxr-xr-x   2 sinseman44 sinseman44  4096 2012-06-22 11:43 stamps/
    drwxr-xr-x  18 sinseman44 sinseman44  4096 2012-06-25 20:08 target/
    drwxr-xr-x   2 sinseman44 sinseman44  4096 2012-06-22 09:45 toolchain/ 

    Les dossiers importants sont :
    • build : dossier de compilation de tous nos paquets sélectionnés
    • host : chaîne de compilation croisée (arm-unknown-linux-gnueabi-gcc, ...)
    • images : les images compressées à transférer sur la carte SD (boot.tar.gz, rootfs.tar.gz)
    • target : l'image de notre système de fichiers (permet de construire l'archive) 
    • staging : dossier d'installation de toutes les librairies et des headers de développement (utile lors de dépendances entre paquets)

     

    Pour aller plus loin ...

     

    Crosstool-NG

    Buildroot utilise plusieurs outils pour générer les différents éléments de notre de système, notamment pour la chaine de compilation croisée. Il offre le choix d'utiliser une chaine de compilation croisée externe, une chaine construite par buildroot (itself) ou l'utilisation de l'outil Crosstool-NG.

    Il est possible de configurer la chaine de compilation croisée, et je vous propose mon fichier de configuration pour crosstool-NG. à placer dans le dossier board/raspberrypi.
    # make ctng-menuconfig
    # make


    Cette chaine, une fois construite, sera présente dans le dossier output/host.

     

    Busybox 

     

    Busybox est considéré comme le couteau suisse du système embarqué, il embarque dans un seul programme (gain de mémoire non négligeable), toutes les commandes de bases de linux (ls, mount, ps, ect ...). Il est, évidement, possible de configurer les commandes présentes sur notre système.

    Entrer la commande pour avoir l'interface de configuration de busybox :
    # make busybox-menuconfig

    puis la commande de compilation :
    # make

    Le binaire se trouvera dans le système de fichier, sous le nom busybox et de nombreux liens symboliques pointeront vers ce binaire pour accéder aux commandes. Vous pouvez le constater dans le dossier output/target/bin.

    # ls -al output/target/bin
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 addgroup -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 adduser -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 ash -> busybox
    -rwxr-xr-x  1 sinseman44 sinseman44 781092 2012-06-25 20:49 bash
    -rwsr-xr-x  1 sinseman44 sinseman44 634136 2012-06-25 20:49 busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 cat -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 catv -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 chattr -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 chgrp -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 chmod -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 chown -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 cp -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 cpio -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 date -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 dd -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 delgroup -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 deluser -> busybox
    lrwxrwxrwx  1 sinseman44 sinseman44      7 2012-06-25 20:08 df -> busybox
    [ ... ]
    On peut maintenant aborder la seconde partie du tutoriel ...


    Nota Bene :


    Suite à un retour d'un lecteur de ce blog, il s'avère que l'inittab modifié, ne se copie pas dans le système de fichiers, suite à une ligne commentée dans le script post-build.sh. Ce script est appelé à chaque construction du système de fichiers.
    Cette modification sert à avoir la console série.


    [...]
    # add a corrected, and lightweight inittab
    #cp board/raspberrypi/inittab $TARGETDIR/etc/inittab
    [...]
    

    et à remplacer par :

    [...]
    # add a corrected, and lightweight inittab
    cp board/raspberrypi/inittab $TARGETDIR/etc/inittab
    [...]
    

    ou copier directement l'inittab modifié directement dans BUILDROOT_PATH/output/target/etc et refaire un make

    # cp board/raspberrypi/inittab output/target/etc
    # make
    

    Aucun commentaire:

    Enregistrer un commentaire