Page suivante Page précédente Table des matières

4. Construire un système racine

Pour créer un système racine, il faut sélectionner les fichiers nécessaires au système pour fonctionner. Dans cette section nous décrivons comment créer un système racine compressé. Une option moins courante est de créer un système non compressé sur une disquette que l'on monte directement ; cette alternative est décrite dans la section Système racine sans disque mémoire.

4.1 Aperçu

Un système racine doit contenir tout ce qui est nécessaire au bon fonctionnement d'un système Linux complet. Pour cela, le disque doit contenir un système Linux minimum :

Bien sûr, n'importe quel système devient utile dès que l'on peut faire tourner quelque chose dessus, et une disquette racine ne devient en général utilisable que lorsque vous pouvez faire quelque chose du genre :

Nous décrirons comment construire un système compressé, ainsi appelé car il est compressé sur disque et qu'une fois démarré, le noyau le décompresse dans un disque mémoire. Avec un système compressé vous pouvez faire tenir beaucoup de fichiers (à peu près six mégaoctets) sur une disquette standard de 1440K. Puisque le système de fichiers est bien plus gros que la disquette, il ne peut être construit directement sur la disquette. Il nous faut le construire ailleurs et le compresser avant de le copier sur la disquette.

4.2 Création du système de fichiers

Pour créer un tel système racine, il vous faut un autre périphérique capable de stocker tous les fichiers avant leur compression. Ce périphérique doit pouvoir contenir à peu près quatre mégaoctets. Plusieurs solutions s'offrent à vous :

Après avoir choisi une de ces options, préparez le PÉRIPHÉRIQUE avec :

        dd if=/dev/zero of=PÉRIPHÉRIQUE bs=1k count=3000

Cette commande initialise à zéro le périphérique. Cette étape est importante pour la compression ultérieure du système de fichiers, afin que toutes les portions inutilisées soient remplies de zéro pour une compression maximum.

Ensuite, créez le système de fichiers. Le noyau Linux sait charger automatiquement deux types de système de fichiers dans un disque mémoire : minix et ext2, avec une préférence pour ext2. Si vous le choisissez, vous voudrez peut-être utiliser l'option -i afin de créer plus d'i-noeuds que par défaut ; -i 2000 est une bonne valeur qui vous évitera de tomber à court d'i-noeuds. Vous pouvez sinon économiser des i-noeuds en supprimant pas mal de fichiers /dev/ inutiles. mke2fs crée par défaut 360 i-noeuds sur une disquette de 1,44 Mo. Je trouve 120 i-noeuds largement suffisants sur mon actuelle disquette racine de secours, mais si vous conservez tous les périphériques dans le répertoire /dev vous dépasserez facilement les 360. L'utilisation d'un système racine compressé permet de créer un système de fichiers plus grand, contenant donc plus d'i-noeuds par défaut, mais vous pourrez quand même vouloir réduire le nombre de fichiers ou augmenter le nombre d'i-noeuds.

Vous allez donc taper une commande du genre :

        mke2fs -m 0 -i 2000 PÉRIPHÉRIQUE

(Si vous utilisez un périphérique de boucle, le fichier que vous utilisez doit être indiqué à la place de ce PÉRIPHÉRIQUE. mke2fs vous demandera alors si vous voulez vraiment faire cela ; répondez oui.)

La commande mke2fs détectera automatiquement l'espace disponible et se configurera selon. Le paramètre -m 0 permet de ne pas réserver d'espace pour root, et laisse donc plus d'espace disponible sur le disque.

Ensuite, montez le périphérique :

        mount -t ext2 PÉRIPHÉRIQUE /mnt

(Vous devez créer un point de montage /mnt s'il n'existe pas encore.) Dans les sections suivantes, tous les répertoires destination sont supposés relatifs à /mnt.

4.3 Remplissage du système de fichiers

Voici un minimum raisonnable de répertoires à créer sur votre système racine :

(La structure de répertoires présentée ici concerne uniquement les disquettes racines. Les vrais systèmes Linux ont une politique plus complexe et disciplinée, appelée la Hiérarchie Standard de Système de Fichiers (Filesystem Hierarchy Standard), qui détermine où les fichiers doivent se trouver.)

Trois de ces répertoires resteront vides sur les systèmes racine, il suffit donc de les créer avec mkdir. Le répertoire /proc n'est qu'une base sous laquelle le système proc est placé. /mnt et /usr ne sont que des points de montage utilisés une fois que le système amorce/racine tourne. Encore une fois, il suffit de créer ces répertoires.

Les quatre autre répertoires sont décrits dans les sections suivantes.

/dev

Tous les systèmes Linux ont besoin d'un répertoire /dev contenant un fichier spécial par périphérique accessible au système. Le répertoire en lui-même est normal, et peut être créé avec mkdir de la manière habituelle. Les fichiers spéciaux de périphérique doivent par contre être créés différemment, à l'aide de la commande mknod.

Il y a un raccourci par contre : copiez le contenu de votre répertoire /dev existant, puis supprimez ceux dont vous n'avez pas besoin. Il suffit juste de copier les fichiers spéciaux avec l'option -R. Cela copie le répertoire sans tenter de copier le contenu des fichiers. Attention à bien utiliser un R en majuscule ! Si vous utilisez l'option en minuscule -r, vous allez vous retrouver en train de copier le contenu complet de votre disque dur -- ou au moins tout ce que pourra en contenir une disquette ! Prenez donc vos précautions, et utilisez la commande :

        cp -dpR /dev /mnt

en supposant que la disquette est montée sur /mnt. Les options dp demandent la copie des liens symboliques en tant que lien, plutôt que celle du fichier qui se trouve au bout de celui-ci, et la conservation des attributs originaux des fichiers, pour garder les bons propriétaires.

Si vous voulez le faire vous-mêmes, utilisez ls -l pour afficher les numéros majeurs et mineurs des périphériques qui vous intéressent, et créez-les sur la disquette en utilisant mknod.

Quelle que soit la manière retenue pour copier les périphériques, il faut vérifier que tous les périphériques dont vous aurez besoin sont bien présents sur la disquette de secours. Par exemple, ftape utilise les périphériques de bande, qu'il vous faudra donc tous copier si vous comptez utiliser votre lecteur de bande depuis le disque amorce.

A noter qu'un i-noeud est nécessaire pour chaque fichier de périphérique, et que les i-noeuds sont parfois une ressource rare, spécialement sur les systèmes de fichiers sur disquette. Il n'est donc pas idiot d'enlever tous les fichiers de périphérique dont vous n'avez pas besoin du répertoire /dev de la disquette. Bien des périphériques ne sont clairement pas nécessaires sur des systèmes spécifiques. Par exemple, si vous n'avez pas de disques SCSI vous pouvez tranquillement enlever tous les fichiers commençant par sd. De même, si vous ne comptez pas utiliser de port série vous pouvez supprimer tous les fichiers commençant par cua.

N'oubliez pas d'inclure les fichiers suivants dans le répertoire : console, kmem, mem, null, ram, tty1.

/etc

Ce répertoire doit contenir un certain nombre de fichiers de configuration. Sur la plupart des systèmes, on peut les répartir en trois groupes :

  1. Nécessaires à tout moment, par exemple rc, fstab, passwd ;
  2. Peut-être nécessaires, mais on n'en est pas sûr ;
  3. Du bazar oublié là.

Les fichiers non essentiels peuvent être identifiés avec la commande :

        ls -ltru

Les fichiers sont classés dans l'ordre inverse de dernière date d'accès, donc tout fichier qui n'est jamais lu peut être exclu d'une disquette racine.

Sur mes disquettes racine, je n'ai que 15 fichiers de configuration. Mon travail se réduit alors à gérer trois groupes de fichiers :

  1. Ceux que je dois configurer pour un système d'amorce et racine :
    1. rc.d/* : scripts de démarrage du système et de changement de niveau d'exécution ;
    2. fstab : liste des systèmes de fichiers à monter ;
    3. inittab : paramètres pour le processus init, le premier à être lancé au démarrage.
  2. Ceux que je dois nettoyer pour un système d'amorce et racine :
    1. passwd : liste des utilisateurs, des répertoires utilisateurs, etc ;
    2. group : groupes d'utilisateurs ;
    3. shadow : mots de passe cachés des utilisateurs. Il se peut que vous n'ayez pas ce fichier ;
    4. termcap : la base de données de fonctionnalités des terminaux.
    Si la sécurité est importante, passwd et shadow doivent être nettoyés pour ne pas copier de mots de passe d'utilisateurs hors du système et pour qu'en cas de démarrage sur disquette, les logins indésirables soient rejetés. Assurez-vous que passwd contienne au moins root. Si vous comptez donner accès à d'autres utilisateurs, vérifiez l'existence de leurs répertoires utilisateurs et de leurs shells. termcap, la base de données de terminaux, fait en général plusieurs centaines de kilo-octets. Vous devrez faire du ménage dans la version de votre disquette d'amorce/racine pour ne conserver que le ou les terminaux que vous utilisez, ce qui se réduit en général à l'entrée linux-console.
  3. Le reste. Ils fonctionnent très bien tels quel, je ne les modifie donc pas.

Parmi tout cela, je n'ai en réalité que deux fichiers à configurer, et ils ne doivent contenir qu'étonnamment peu de choses.

Votre inittab doit être modifié pour que la ligne sysinit lance rc ou quelque autre script basique d'amorce. De plus, si vous ne souhaitez pas que les utilisateurs se loguent sur les ports série, commentez toutes les entrées getty qui référencent des périphériques ttys ou ttyS à la fin de la ligne. Laissez les ports tty pour pouvoir vous loguer sur la console.

Un fichier inittab minimal contient cela :

        id:2:initdefault
        si::sysinit:/etc/rc
        1:2345:respawn:/sbin/getty 9600 tty1
        2:23:respawn:/sbin/getty 9600 tty2

Le fichier inittab décrit ce que va lancer le système dans divers états, dont le démarrage, le passage en mode multi-utilisateurs, etc. Attention aux noms de fichiers référencés dans inittab ; si init ne peut trouver le programme, le disque d'amorce s'arrêtera, et vous n'aurez peut-être même pas de message d'erreur.

Notez que certains programmes ne peuvent être déplacés en raison d'autres programmes qui référencent en dur leur position. Par exemple sur mon système, /etc/shutdown référence en dur /etc/reboot. Si je déplace reboot vers /bin/reboot, et que je lance une commande shutdown, elle va échouer en ne trouvant pas le fichier reboot.

Pour le reste, copiez juste tous les fichiers texte de votre répertoire /etc, ainsi que tous les exécutables présents dans /etc dont vous n'êtes pas sûr de pouvoir vous passer. Basez-vous sur l'exemple de la section Exemple de contenu des répertoires d'un disque racine. Il vous suffira probablement de copier ces fichiers, mais les systèmes pouvant être très différents, il n'est pas certain que le même ensemble de fichiers sur votre système soit équivalent aux fichiers listés. La seule méthode sure est de partir d'inittab et d'en déduire ce qui est nécessaire.

La plupart des systèmes utilisent maintenant un répertoire /etc/rc.d/ contenant des scripts shell pour les différents niveaux d'exécution. Il faut au minimum avoir un script rc unique, mais il peut être plus simple de carrément copier inittab et le répertoire /etc/rc.d depuis votre système puis de nettoyer les scripts shell dans le répertoire rc.d pour enlever tous les traitements inutiles pour un système sur disquette.

/bin et /sbin

Le répertoire /bin est un endroit pratique pour tous les utilitaires nécessaires aux opérations de base, tels que ls, mv, cat et dd. Voir l'appendice Exemple de contenu des répertoires d'un disque racine pour un exemple d'ensemble de fichiers pouvant aller dans les répertoires /bin et /sbin. Il ne contient aucun des utilitaires nécessaires à la récupération d'une sauvegarde, tels que cpio, tar et gzip. C'est parce que je place ceux-ci sur une disquette utilitaire séparée, pour conserver de la place sur la disquette d'amorce et racine. Une fois la disquette d'amorce/racine démarrée, elle est copiée sur le disque mémoire, laissant ainsi le lecteur de disquette libre pour en monter une autre, la disquette utilitaire. En général je la monte sur /usr.

La création d'une disquette utilitaire est décrite ci-dessous dans la section Construire un disque utilitaire. Il est probablement souhaitable d'y maintenir une copie des mêmes versions d'utilitaires de sauvegarde que ceux utilisés pour écrire les sauvegardes, histoire de ne pas perdre de temps en essayant d'installer des versions qui ne peuvent pas lire vos bandes de sauvegarde.

Vérifiez que vous mettez les programmes suivants : init, getty ou un équivalent, login, mount, un shell capable de faire tourner votre script rc, un lien de sh vers le shell en question.

/lib

Vous mettez dans /lib les bibliothèques partagées et chargeurs nécessaires. Si les bibliothèques nécessaires ne sont pas trouvées dans /lib, le système ne pourra pas démarrer. Avec de la chance, un message vous expliquera pourquoi.

Pratiquement tous les programmes ont au moins besoin de la bibliothèque libc, libc.so.N, N étant le numéro de version courant. Vérifiez votre répertoire /lib, libc.so.N est en général un lien symbolique vers un fichier avec un numéro de version complet :

% ls -l /lib/libc.so*
-rwxr-xr-x   1 root     root      4016683 Apr 16 18:48 libc-2.1.1.so*
lrwxrwxrwx   1 root     root           13 Apr 10 12:25 libc.so.6 -> libc-2.1.1.so*

Dans le cas présent, il vous faut libc-2.1.1.so. Pour trouver les autres bibliothèques nécessaires, il faut lancer la commande ldd sur tous les exécutables que vous prévoyez de mettre sur la disquette. Par exemple :

        % ldd /sbin/mke2fs
        libext2fs.so.2 => /lib/libext2fs.so.2 (0x40014000)
        libcom_err.so.2 => /lib/libcom_err.so.2 (0x40026000)
        libuuid.so.1 => /lib/libuuid.so.1 (0x40028000)
        libc.so.6 => /lib/libc.so.6 (0x4002c000)
        /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)

Tous les fichiers à droite sont nécessaires. Le fichier peut en réalité être un lien symbolique.

Notez que certaines bibliothèques sont assez grosses et ne tiendront pas facilement sur votre système racine. Par exemple, la libc.so citée précédemment fait environ 4 mégas. Vous devrez probablement nettoyer les bibliothèques en les copiant sur votre système racine. Reportez-vous à la section Réduire la taille du système racine pour plus d'informations.

Il faut également inclure dans /lib un chargeur pour les bibliothèques. Il s'agira soit de ld.so (pour les bibliothèques a.out), soit de ld-linux.so (pour les bibliothèques ELF). Les versions récentes de ldd vous indiquent de quel chargeur vous avez besoin, comme dans l'exemple ci-dessus, mais de plus anciennes versions ne le font pas forcément. Si vous ne savez pas duquel vous avez besoin, utilisez la commande file sur la bibliothèque. Par exemple :

        % file/lib/libc.so.4.7.2 /lib/libc.so.5.4.33 /lib/libc-2.1.1.so
        /lib/libc.so.4.7.2: Linux/i386 demand-paged executable (QMAGIC), stripped
        /lib/libc.so.5.4.33: ELF 32-bit LSB shared object, Intel 80386, version 1, stripped
        /lib/libc-2.1.1.so: ELF 32-bit LSB shared object, Intel 80386, version 1, not stripped

Le mot QMAGIC indique que 4.7.2 est pour les bibliothèques a.out, et ELF que 5.4.33 et 2.1.1 sont pour les ELF.

Copiez le ou les chargeurs dont vous avez besoin sur le système racine que vous êtes en train de construire. Les bibliothèques et chargeurs doivent être testés attentivement avec les exécutables inclus. Si le noyau ne peut charger une bibliothèque nécessaire, il s'arrêtera en général net, sans message d'erreur.

4.4 Utilisation de PAM et NSS

Votre système peut utiliser des bibliothèques chargées dynamiquement mais invisible à ldd.

PAM (Pluggable Authentication Modules)

Si votre système utilise PAM (Pluggable Authentication Modules, soit Modules Externes d'Authentification), tenez-en compte dans la construction de votre disque d'amorce, sans quoi vous ne pourrez pas vous loguer. En quelques mots, PAM est une méthode modulaire sophistiquée pour authentifier les utilisateurs et contrôler leur accès aux services. Pour déterminer simplement si votre système utilise PAM, cherchez dans le répertoire /etc de votre disque dur un fichier pam.conf ou un répertoire pam.d ; si l'un des deux existe, vous devez prévoir un minimum de support pour PAM. (Vous pouvez aussi lancer ldd sur votre exécutable login ; si la sortie contient libpam.so, vous avez besoin de PAM.)

Heureusement, la sécurité est rarement un problème avec les disques d'amorce étant donné que quiconque avec un accès physique à la machine peut en général faire tout ce qu'il veut dessus. Vous pouvez donc complètement désactiver PAM en créant un fichier /etc/pam.conf simple sur votre système racine contenant :


OTHER   auth       optional     /lib/security/pam_permit.so
OTHER   account    optional     /lib/security/pam_permit.so
OTHER   password   optional     /lib/security/pam_permit.so
OTHER   session    optional     /lib/security/pam_permit.so

Copiez également le fichier /lib/security/pam_permit.so sur votre système racine. Cette bibliothèque ne fait qu'environ 8 Ko et ne coûte donc pas grand chose.

Notez bien que cette configuration donne à tous un accès complet aux fichiers et services de votre machine. Si vous avez des impératifs de sécurité sur votre disque d'amorce pour une raison ou une autre, vous devrez copier une partie, voire l'ensemble de la configuration PAM de votre disque dur vers le système racine. Lisez bien attentivement la documentation de PAM, et copiez toutes les bibliothèques nécessaires depuis /lib/security vers votre système racine.

Vous devez aussi inclure /lib/libpam.so sur le disque racine. Mais vous le saviez déjà puisque vous avez lancé ldd sur /bin/login qui vous a montré la dépendance.

NSS (Name Service Switch)

Si vous utilisez glibc (appelée aussi libc6), vous devez tenir compte des services de noms sans quoi vous ne pourrez pas vous loguer. Le fichier /etc/nsswitch.conf contrôle les recherches dans les bases de données pour divers services. Si vous ne comptez pas accéder à des services du réseau (tels que des recherches DNS ou NIS), un simple fichier nsswitch.conf comme suit suffit :


        passwd:     files
        shadow:     files
        group:      files
        hosts:      files
        services:   files
        networks:   files
        protocols:  files
        rpc:        files
        ethers:     files
        netmasks:   files
        bootparams: files
        automount:  files
        aliases:    files
        netgroup:   files
        publickey:  files

Ce fichier spécifie que tous les services ne sont fournis que par des fichiers locaux à la machine. Vous devez aussi inclure le fichier /lib/libnss_files.so.1 qui est chargé dynamiquement pour gérer les recherches dans les fichiers.

Si vous comptez accéder au réseau depuis votre disque d'amorce, vous pouvez créer un fichier nsswitch.conf plus complet. Voir la page de manuel de nsswitch pour plus de détails. N'oubliez pas d'inclure un fichier /lib/libnss_service.so.1 pour chaque service que vous ajoutez.

4.5 Modules

Si votre noyau est modulaire, vous devez savoir quels modules vous voudrez charger depuis votre disque d'amorce une fois le système démarré. Il vous faudra inclure les modules ftape et zftape si vos sauvegardes sont sur bandes, les modules pour périphériques SCSI si vous en avez, et éventuellement ceux pour le support PPP ou SLIP si vous souhaitez accéder au réseau en cas d'urgence.

Ces modules doivent être placés dans /lib/modules. Vous devez aussi inclure insmod, rmmod et lsmod. Si vous souhaitez charger les modules automatiquement, prenez modprobe, depmod et swapout. Et si vous utilisez kerneld, prenez le avec son fichier de configuration /etc/conf.modules.

Néanmoins, le principal avantage à utiliser les modules est que vous pouvez déplacer les modules non essentiels sur un disque utilitaire et ne les charger que lorsque nécessaire, ce qui prend alors moins de place sur le disque racine. Si vous devez gérer beaucoup de périphériques, il vaut mieux procéder de cette manière plutôt que de construire un seul gros noyau contenant tous les gestionnaires.

Attention, pour démarrer avec un système de fichiers ext2 compressé, vous devez avoir inclus le support pour disque mémoire et ext2. Ils ne peuvent être installés par modules.

4.6 Quelques ultimes détails

Certains programmes, tels que login, se plaignent si le fichier /var/run/utmp et le répertoire /var/log n'existent pas. Donc :

        mkdir -p /mnt/var/{log,run}
        touch /mnt/var/run/utmp

Enfin, après avoir installé toutes les bibliothèques dont vous avez besoin, lancez ldconfig pour refabriquer /etc/ld.so.cache sur le système racine. Le cache indique au loader où trouver les bibliothèques. Pour refabriquer ld.so.cache, lancez les commandes suivantes :

        chdir /mnt; chroot /mnt /sbin/ldconfig

La commande chroot est nécessaire car ldconfig reconstruit toujours le cache pour le système racine courant.

4.7 C'est dans la poche

Une fois le système racine construit, démontez-le, copiez-le dans un fichier et compressez-le :

        umount /mnt
        dd if=PÉRIPHÉRIQUE bs=1k | gzip -v9 > rootfs.gz

Une fois cette étape effectuée, vous obtenez un fichier rootfs.gz contenant votre système racine compressé. Vérifiez sa taille pour être sûr qu'il tient sur une disquette. Si ça n'est pas le cas vous devrez y retourner pour supprimer certains fichiers. La section Réduire la taille du système racine vous donnera des astuces pour y arriver.


Page suivante Page précédente Table des matières