Forums d'entraide informatique - Astuces - Conseils

Des experts à votre écoute pour tous vos dysfonctionnements

Vous n'êtes pas identifié.


#1 23-10-2008 19:40:28

Admin
Administrateur
Date d'inscription: 30-07-2008
Messages: 683

Un système Debian sur un Flash de 16 Mo !

UN SYSTÈME DEBIAN SUR
COMPACTFLASH 16 MO

Pour faire de l'embarqué à peu de frais, la meilleure solution consiste à utiliser une architecture x86 qu'on aura, au préalable, adaptée, aussi bien côté matériel que logiciel. Cet article présente une méthode de construction reposant sur la réutilisation d'une distribution reconnue et très structurée : Debian.
Le présent article poursuit deux objectifs primaires. Premièrement, la construction d'un système embarqué de taille réduite sur carte CompactFlash 16 Mo et, deuxièmement, la compréhension de l'architecture d'un système GNU/Linux.
En effet, au-delà du simple résultat, la construction d'un système devant répondre à un cahier des charges strict est une occasion idéale d'étudier, étape par étape, les éléments qui composent un système GNU. L'utilisation de scripts et de techniques en oeuvre dans une distribution comme Debian GNU/Linux nous permettra également de mieux comprendre et apprécier cette distribution pour sa facilité de personnalisation/réutilisation.
1.MATÉRIEL
L'architecture de test ici utilisée est délibérément modeste. Il s'agit d'un Pentium 166 MMX utilisé avec une carte mère des plus classiques (pour son époque) et 128 Mo de mémoire. La fréquence du processeur aura été préalablement réduite à 110 Mhz afin de remplacer le couple radiateur/ventilateur par un simple radiateur de cuivre.
Côté périphériques, la carte mère a été joyeusement équipée de tout ce qui traînait dans mes tiroirs : 4 ports USB, 3 ports parallèles, 4 ports série, 2 ports firewire, un adaptateur graphique PCI et une interface Ethernet I ObaseT.
L'ensemble constitue quelque chose de très économique et surtout, bien en dessous des configurations x86 dédiées à l'embarqué que l'on trouve dans le commerce. Notez également que la plate-forme de départ pour les expérimentations était un 386/387 équipé de 4 Mo de mémoire. L'émulation 486 du noyau Linux était indispensable pour que l'ensemble soit fonctionnel. Busybox tel qu'empaqueté par Debian ne fonctionnait pas correctement sans émulation. Bien que viable, la configuration était insuffisante en termes de mémoire pour supporter les explications qui vont suivre. Sachez cependant qu'avec un peu d'obstination il est possible de « faire quelque chose qui marche » avec ce type de configuration.
L'élément le plus important de l'ensemble matériel réside dans l'utilisation de la carte CompactFlash. Il faut, en effet savoir que ce format de carte mémoire dispose d'un mode de compatibilité IDE. En d'autres termes, il est possible de connecter directement une carte CF sur un contrôleur IDE. On remarquera cependant que la carte doit être compatible TruelDE et pouvoir fonctionner en 5 volts. Les cartes CF ne supportant que 3.3 volts NE DOIVENT PAS ETRE UTILISEES de cette manière. Pour l'anecdote, c'est l'ouverture d'un adaptateur PCMCIA/CF (n'intégrant pas le moindre composant) qui fut à l'origine de l'expérimentation. Les cartes CF disposent également d'un mode de compatibilité PCMCIA permettant une connexion directe.
Il est possible de confectionner un adaptateur « maison » comme celui présenté en figure I. C'est une expérience intéressante au niveau émotionnel... En particulier lorsqu'on se rend compte que l'amas de fils et de soudures, confectionné d'après des bribes d'informations glanées sur leVVeb,fonctionne du premier coup et que, ni votre carte CF, ni le contrôleur

IDE n'ont été détruits. Cependant, par expérience, je vous recommande l'acquisition d'un adaptateur manufacturé (figure 2).
En dehors des fonctionnalités en termes de connectivité et de compatibilité, une carte CompactFlash présente les mêmes caractéristiques que l'on retrouve dans tous les matériels de ce type
•    Rapidité. Contrairement à un disque « mécanique », une
carte mémoire n'a pas de période de qualibration des têtes à la mise sous tension.Vous gagnez un temps précieux au démarrage.
•    Faible consommation. Une carte CompactFlash consomme
quelques 0.5 watt en utilisation contre 2 à 4 watts pour un disque dur standard. Sur une période importante, ceci peut s'avérer non négligeable.
é Aucun bruit. Contrairement à un disque, une carte mémoire ne possède aucune partie mobile mécanisée susceptible de provoquer un bruit (rotation, ventilation, déplacement).
En adaptant le reste de la configuration, il vous est ainsi possible d'obtenir un système parfaitement silencieux car parfaitement statique.
•    Fiabilité. Cet avantage doit être mitigé. En effet, une carte mémoire est peu sensible aux chocs et aux différences importantes de températures, ce qui est une excellente chose. Cependant on considère généralement qu'un usage- intensif d'une mémoire Flash conduit, à moyen terme, à la destruction des unités de mémoire. Hors de question donc de swapper sur de la mémoire Flash.Au contraire, on Lichera de l'utiliser le moins possible. Il n'est pas nécessaire de contrôler la répartition des données:sur la carte. La logique interne de cette dernière s'occupe de placer les données de manière à ne pas « user » prématurément une zone plutôt qu'une autre. On notera cependant qu'il est fort possible que les cartes bas de gamme ou d'ancienne génération ne disposent pas de cette fonttionnalité.
En plus de cela, les cartes Compact Flash présentent un dernier intérêt non négligeable : leur faible coût. Ce type de format est encore utilisé pour quelques appareils photo numériques récents (Nikon et Canon), mais de plus en plus de modèles utilisent des cartes à un format plus petit etplus moderne (MMC, SD, Memory Stick ou xD).Ainsi, non seulement leur prix ne cesse de baisser mais on trouve des cartes de faible capacité (16 à 64 Mo) pour une misère sur Internet. Beaucoup d'utilisateurs ont reçu leur appareil photo numérique avec une carte de 16 Mo dont ils n'ont jamais eu l'usage, préférant acheter une carte complémentaire d'une capacité plus importante. Au vu des ventes de ce type d'appareil ces trois dernières années, on se demande si toutes ces cartes ne sont pas tout simplement en train de prendre la poussière dans des tiroirs ou, pire, dans une déchetterie.
2.PREMIÈRE ÉTAPE: LE NOYAU
La première étape consiste en la préparation du support et la création d'une partition sur la carte CF. Celle-ci occupera l'ensemble du support. L'idée aurait été tentante d'utiliser une carte de 32 Mo partitionnée en deux systèmes de fichier de 16 Mo chacun. Ainsi, il aurait été possible d'avoir un système de secours en cas de défaillance. La sécurité cependant aurait été très limitée et nous pouvons obtenir le même type de comportement avec deux cartes de 16 Mo.
Pour l'heure, nous allons commencer par créer une seule partition sur la carte placée dans un lecteur USB. Celle-ci nous apparaît comme un disque SCSI sous la désignation s d a.Voici
la partition telle que vue par fdi sk (commande p) :
Disk /dev/sda: 16 MB, 16056320 bytes
1 heads, 31 sectors/track, 1011 cylinders Units    cylinders of 31 * 512    15872 bytes
Device Boat Start    End Blocks Id System
/dev/sdal    2 1011    15655 83 Linux
On poursuit naturellement avec la création d'un systeme de fichier standard. Nous parlerons plus loin de l'utilisation d'autres systèmes de fichiers plus adaptés à la mémoire Flash
% mke2fs /dev/sdal
Type de système d'exploitation: Linux
nsion v1.0A Software, Inc.
ster    SanDisk SDCFB -16
lave    ... None
Master... None Slave    None
board present
CFDISKJE IDE/Compacel4sh adopte-
NO not
e 2004 PC Enenes Bon,
2E0M 2 94'0
OW:6
Figure 2
Dans tous les cas, une carte CF compatible TruelDE sera reconnue comme un disque dur par le BIOS du PC (figure 3). La construction du système se fera, très simplement, via l'utilisation d'un lecteur CF USB et les tests seront faits via Bochs.

x86
Taille de bl oc=1024 ( 1 og.0) Taille de f ragment=1024 ( 1 og.0 ) 3920 i nodes , 15652 blocs
782 blocs (5.00%) réservé pour le super usager
Premier bloc de données.' 2 bloc de groupes
8192 blocs par groupe, 8192 fragments par groupe 1960 i nodes par groupe
Archive du superbl oc stockée sur les blocs:
8193
E...]
Une fois le système de fichier créé, nous pouvons nous attaquer au système dans l'ordre chronologique de son futur démarrage. Première étape donc, installer un bootlooder performant et souple qui s'occupera de charger notre noyau et de l'exécuter.
Pas de surprise ici, c'est tout naturellement GRUB qui sera utilisé. Nous montons donc le système de fichiers et installons le minimum vital pour GRUB :
% mount /dev/sdbl /mnt/CF16
% mkdir -p /mnt/CF16/boot/grub
% cp /lib/grub/i386-pc/stagel /mnt/CF16/boot/grub % cp /lib/grub/i386-pc/stage2 /mnt/CF16/boot/grub
% cat > /mnt/CF16/boot/grub/menu.lst
color white/black black/red
timeout 60
default 0
title DeniX embedded Linux 2.4 Pentium MMXUSB root (hd0,0)
kernel /boot/vmlinuz-2.4.32-MMXUSB root./devadal
Il faut ensuite installer GRUB sur la carte CF. Ceci se fera en deux étapes pour une raison évidente. Le système hôte, le PC sous Debian GNU/Linux disposant du lecteur CF USB, ne possède pas une configuration identique à celle de la cible, ici le Pentium 166.
De la même manière, dans la phase de construction/test, Bochs émulera une machine cible ne disposant que d'un seul disque : la carte CF. La première étape consiste donc à installer le secteur de boot (stagel) sur la carte CF avec des paramètres sans grande importance.
On lance ainsi g rub sur le système hôte en utilisant les paramètres correspondants à la configuration actuelle (sur une seule ligne) :
install
(hd1,2)/lib/grub/i386-pc/stagel (hd3)
(hd3,0)/boot/grub/stage2
(hd3,0)/boot/grub/menu.lst
Ici, ( na I , 2) est la partition racine du système hôte. Nous installons stagel sur hd3, le quatrième disque du système (la carte CF). On passe en paramètre l'endroit où réside st a ge2 et le fichier de configuration de GRUB. Nous utilisons ensuite immédiatement l'émulateur Bochs avec la configuration suivante :
meg s : 128
romi mage: fi 1 e=/us r/share/bochs/BIOS - bochs - 1 atest , address.8xf0000
v ga romi mage: fi 1 e=/usr/sha re/ vgabi os/ vgabi os .ci rrus.bi n di spl ay_l brary: x
keyboard_type: at
keyboard_mapping: enabled=1, map=/usr/share/ bochs/keymaps/x11-pc-fr.map
ata0-master: type=disk, path=/dev/sda, cylinders=1011, heads=1, spt=31
boot: c
1 og : bochsout .txt mouse : enabl ed.0 i ps: 5000000
Les lignes importantes sont mises en évidence. On précise respectivement le volume de mémoire disponible, le mappage du clavier (Français X I I) et la géométrie du disque telle que rapportée par f di s k. Lorsqu'on lance Bochs, GRUB « ne retrouve pas ses petits ». En effet, ( hd3) n'existe pas. On se retrouve alors sur la ligne de commande de GRUB d'où il nous est possible de réinstaller la configuration. Cette souplesse est l'une des raisons pour lesquelles GRUB est tellement apprécié. La commande utilisée est alors (sur une ligne) :
install
(hd0,0)/boot/grub/stagel (hd0)
(hd0,0)/boot/grub/stage2 (hd0,0)/boot/grub/menu.Ist
Dès le reset de la machine virtuelle Bochs, GRUB fonctionne correctement et affiche le menu que nous avons spécifié dans menu. 1 st (figure 4). Bien entendu, pour l'heure nous ne pouvons pas aller plus loin faute de noyau Linux. Nous allons corriger ce point.
La construction du noyau utilisera une méthode « classique » et indépendante de la distribution Debian. Il aurait été possible
de créer un paquet Debian via make-kpkg puis d'utiliser
son contenu pour peupler les répertoires / boot et /1 i b/ modul es. Cela ne présente pas de réel intérêt ici et nous obligerait à installer les sources du noyau via le système APT alors que le système hôte n'en a pas l'usage. De plus, toutes les versions des noyaux Linux ne sont pas disponibles sous forme de paquets.
La construction à proprement parler du noyau n'a rien d'exceptionnel.Après désarchivage des sources,on configurera simplement l'ensemble au strict minimum pour des raisons évidentes d'économie d'espace disque. Le reste est presque instinctif :
% make dep
make bzlmage % make modules % make INSTALL_MOD_PATe/tmp/damodules \
modules install
Remarquez l'utilisation de la variable IN STA L L MOD_PATH. Celle-ci permet d'installer l'arborescence des modules (1 i b/
modul es/ 2 . 4*) ailleurs que dans /us r, nous évitant ainsi de
« polluer » le système hôte. Ces directives correspondent à un noyau 2.4.x (2.4.32 pour être précis) et devront être adaptées pour un noyau de la série 2.6.

En phase d'expérimentation ou tout simplement pour avoir plusieurs noyaux différents sous la main en cas de besoin,vous pouvez installer plusieurs versions différentes sur la carte CE II faudra toutefois prendre garde à ne pas mélanger les modules de ces différentes versions (dans /1 i b/mod u 1 e/ 2 .4 .32 par exemple).
Le noyau est chargé par GRUB et le fichier pourra être nommé arbitrairement. Il n'en va pas de même pour /1 lb! modul es.Pour que le noyau aille chercher ses modules dans un répertoire spécifique,nous utiliserons la variable EXTRAVERSION présente dans le Ma kef i le des sources du noyau. En passant
en argument de ma ke, par exemple, E XT RAV E RS I ON= - MMX, le
noyau résultant ira chercher les modules automatiquement dans / u s r/ 1 i b/modul es/2 .4. 3 2 -MMX.On peut ainsi décliner une même version de noyau dans plusieurs configurations différentes sans créer le chaos dans le système. Au besoin, modifiez directement la variable dans les premières lignes du Ma kef i 1 e.
Une fois le noyau et les modules compilés, il ne nous reste plus qu'à copier tout cela sur la carte CF
% cp arch/i386/boot/bzImage \ / mnt/sda/boot/vmlinuz-2.4.32-MMXUSB % cp -r /tmp/damodules/lib /mnt/sda
Dès lors, un essai dans Bochs nous montre que GRUB charge correctement le noyau en mémoire et lui passe la main. Celui-ci démarre le système et finit par s'arrêter car il ne trouve pas in i t.
3.RENDRE LE SYSTÈME UTILISABLE
Le processus de démarrage d'un système GNU/Linux est très simple, du moins durant les premières secondes. Le noyau chargé et exécuté par le bootloader initialise un grand nombre d'éléments matériels et logiciels. Il prend ainsi en charge tout - - le matériel directement intégré à la configuration comme-rés contrôleurs IDE, les ports série, etc. Ceci fait, il montera le système de fichier spécifié via le paramètre roo-t= et tentera d'exécuter le premier programme utilisateu‘ r du système i ni t, le processus numéro I.
3.1 1NIT
Pour l'heure, / s bi nui ni t étant absent, rien ne marche. Deux solutions s'offrent à nous : soit utiliser la version Busybox d'i ni t, soit copier celle du système hôte. On simple J s - 1 nous apprend que le binaire ne fait que quelques 30 Ko. C'est suffisant pour nous décider. En effet, cet espace disque consommé vaut largement le principal inconvénient de l'init version Busybox : sa configuration n'est pas standard. Un simple coup d'oeil à la page de manuel et le choix est fait. Cette version ne supporte pas le principe des niveaux d'exécution (runlevel).
Nous commençons donc par copier notre cher init dans /usr/sbi n de notre carte CF. Bien entendu, tout binaire non compilé en statique possède des dépendances vis-à-vis de bibliothèques. C'est également le cas d'i ni t et cela sera très simplement vérifié avec la commande 1 dd :
% ldd /sbin/init
linux-gate.so.I => (Oxffffe0001
libsepol.so.1 => /lib/libsepol.so.I (Oxb7ea9080) libselinux.so.1 => /lib/libselinux.so.1 (Oxb7e960001 libc.so.6 => /lib/t1s/libc.so.6 (Oxb7d5d080) libdl.so.2 => /lib/t1s/libdl.so.2 (0xb7d59000) /libild-linux.so.2 (Oxref40081
Ne vous inquiétez pas, je ne vous ferais pas « le coup Idd » à chaque binaire. Non seulement, cela n'apportera rien à l'article mais, de plus, il existe une façon bien plus élégante de copier les bibliothèques du système hôte sur la cible que de lister celles-ci avec 1dd et de les copier manuellement. Un script Python nommé mk1 i bs - copy (voire mk1 i bs ou mkl ibs-smal 1), permet de détecter les dépendances, les trouver sur le système hôte et les copier dans un répertoire spécifié en argument. mk li bs - copy va plus loin qu'un simple 1dd et vous assure presque à 100% le fonctionnement du binaire sur le système cible. Ici, pour intégrer un init à notre système, nous utiliserons
mkdir /mnt/CF16/sbin
% cp /sbin/init /mnt/CF16/sbin/
% mklibs-copy -d /mnt/CF16/1ib /sbin/init
Le noyau ne se plaint plus de l'absence d' i ni t. C'est une grande réussite.A présent, il se plaint de ne pas pouvoir ouvrir une console. Nous avons avancé d'un pas de lutin. Nous n'avons pas configuré i ni t. Le binaire cherche sa configuration dans /etc/i ni ttab.Celle-ci sera plus complexe qu'avec Busybox, mais nous gagnerons finalement en souplesse en utilisant quelque chose de similaire à un SysVinit Debian.
Usr the t ana I keys te select uhich entry la htellyhted. Press enter ta bort the srlected OS. 'e' ta l'ait the commands before bontiny. or 'c for a conmoneline.
4.9',    (I. V.    I    ujap■ s    •toster,1
NOTE
GCC 4.0 est maintenant intégré dans presque toutes les distributions. Cependant, la compilation d'un noyau 2.4 avec cette version peut échouer. Pour contourner le problème et ne pas avoir à appliquer de patch sur les sources du noyau, la manière la plus simple est d'utiliser GCC en version 3.3. Il suffit alors de préciser en argument de ma ke le compilateur à utiliser avec HOSTCC=g cc -3.3 et CC=gcc - 3. 3.

Mais, avant toutes autres choses, nous devons créer les points d'entrée dans /dev (source du message à propos de la console). Nous ne pouvons pas utiliser le script MAKEDEV de Debian qui est, c'est un comble, bien trop performant. Non seulement celui-ci ne s'intéresse qu'au /dev du système hôte mais, de plus, il procède à quelques vérifications sur la version du noyau, la présence d'udev, etc.Autant de choses qui nous empêchent de simplement automatiser l'appel à mknod sur /mnt /CF 1 6/dev.
La solution est simple. Nous allons utiliser un MAKEDEV provenant d'ailleurs. Nous récupérons donc la version 1.7 mise à disposition du http://downloads.linuxfromscratch.orgi, décompressons le fichier, le rendons exécutable et l'appelons depuis /mnt/CF16/dev :
% mkdir /mnt/CF16/dev
% chmod 555 /mnt/CF16/dev % cd /mnt/CF16/dev
% /tmp/MAKEDEV-1.7 generic
Nous n'avons maintenant plus à nous préoccuper de /dev et pouvons passer à la suite. Nous commençons donc par créer le fichier de configuration principal d' i ni t (/etc/ini ttab):
id:2:initdefault:
si::sysinit:/etc/init.d/rcS 10:0:wait:/etc/init.d/rc 0 11:1:wait:/etc/init.d/rc 1 12:2:wait:/etc/init.d/rc 2 13:3:wait:/etc/init.d/rc 3 14:4:wait:/etc/init.d/rc 4 15:5:wait:/etc/init.d/rc 5 16:6:wait:/etc/init.d/rc 6
Dans l'ordre nous :
♦    spécifions le niveau d'exécution par défaut ;
♦    précisons le script systématiquement utilisé au moment du boot, le script d'initialisation du système ;
•    pour chaque niveau d'exécution, précisons un argument différent pour un script unique.
Le contenu du ficher /etc/i ni t. d/rcS est très simple :
tt! /bin/sh
exec /etc/init.d/rc S
Nous retrouvons le fameux script rc avec l'argument S en lieu et place d'une valeur numérique.Tout le fonctionnement de la configuration d'i ni t repose donc sur le script rc que nous allons, tout simplement, copier du système hôte. Nous avons donc, à ce stade :
% mkdir /mnt/CF16/etc/init.d
% mkdir /mnt/CF16/etc/default
% cp /etc/init.d/rc /mnt/CF16/etc/init.d
% cp /etc/default/rcS /mnt/CF16/etc/default % cat > /mnt/CF16/etc/init.d/rcS
#! /bin/sh
exec /etc/init.d/rc S
% chmod +x /mnt/CF16/etc/init.d/rcS
Puis, nous n'oublions pas de copier le shell Bash et l'utilitaire stty :
% mkdir /mnt/CF16/bin
% cp /bin/stty /mnt/CF16/bin
% cp /bin/bash /mnt/CF16/bin/sh
% mklibs-copy -d /mnt/CF16/lib \
/bin/stty /bin/bash
Résumons les faits. A ce stade, init utilisera son inittab pour exécuter le script rc avec l'argument ,) puis le même script avec l'argument 2. Ce script s'occupera de lancer d'autres scripts en cas de changement de niveau d'exécution. Pour déterminer quel script lancer et avec quel argument, il utilisera l'architecture suivante :
•    Le répertoire / etc/init.d contient tous les scripts.
•    Des répertoires correspondant aux niveaux d'exécution (/etc/rc0.d, /etc/rcl .d... /etc/rcS.d) contiennent des liens symboliques vers les scripts correspondants dans /etc/init.d.
•    Le nommage des liens symboliques détermine ce que le script rc doit en faire. Le premier caractère du nom définit l'action. Un « S » demandera le lancement du script dans /et c/init.d avec start en argument. Un « K » fera de même avec stop en argument. Le numéro spécifié entre la première lettre du nom et le nom du script détermine l'ordre d'exécution. Nous pourrons avoir par exemple, /etc/rc . 1 /S5 0toto correspondant à /etc/i ni t .d/toto start tel que lancé par rc.
Pour l'heure, rien n'est en état de fonctionner sur notre système cible. Il nous faut créer les scripts de démarrage du système.
3.2 LES PREMIERS SCRIPTS D'INIT
Nous allons faire simple. Les scripts suivants n'utilisent pas le squelette classique Debian consistant à tester le paramètre en argument. Ils pourront être facilement adaptés par la suite. Le principal but ici est d'arriver à obtenir rapidement un système évolutif et fonctionnel.
Pour que les scripts soient faciles à écrire, ils ne peuvent pas reposer uniquement sur le shell. Nous avons besoin d'un certain nombre de commandes qui nous seront fournies par Busybox. L'installation est, une fois encore, des plus simples. Après installation du paquet busybox sur le système hôte, nous procédons comme suit :
% cp /bin/busybox /mnt/CF16/bin
% mklibs-copy -d /mnt/CF16/lib /bin/busybox
L'étape suivante consiste à créer tous les liens symboliques pointant vers le binaire busybox. Pour cela, le plus simple est de récupérer la liste des fonctions dans un fichier avec busybox > /tinp/li ste et de formater l'ensemble de manière à obtenir la liste avec une commande par ligne.
On veillera à supprimer s h de la liste pour conserver notre Bash ainsi que bu sybox pour ne pas écraser le binaire. Une petite boucle suffit ensuite à créer tous les liens :
% /mnt/CF16/bin
% for i in 'cat /tmp/liste; do /bin/ln -s busybox Si; done


Cordialement

L'équipe Parisdepannage.fr

Hors ligne

 

Pied de page des forums


Copyright Parisdepannage.fr

 

De;coration en-pied 2008 Parisdepannage |Plan du site|Forums |Blog|Lexique De;coration en-pied


Fermer la fenètre