Catégorie : Distribution     Tags :      0 Commentaire

    Combien de fois vous êtes-vous retrouvé chez tonton Louis ou beau-père Michel, fiers de leur nouvelle bête de course équipée d'un accès DSL, tétanisé devant un écran bleu pastel arborant en guise de login un jeune en skateboard ou une pièce d'échiquier ? Ne vous êtes-vous pas maudit à ce moment, alors que vous alliez passer le week-end entier à cet endroit, de ne pas avoir pris dans vos bagages un live CD quelconque, un OS muni d'un shell digne de ce nom, ainsi que de tous les outils indispensables à un week-end de repos ? Et vous avez, dans votre poche, cette clé USB, pleine à craquer de mp3 – libres évidemment –, de photos de vacances et autres captures vidéo de la dernière Solutions Linux. Il restait pourtant dans cette clé 64 mégas octets inutilisés, 64 mégas dans lesquels vous auriez pu caser un UNIX minimal, un diamant qui serait muni d'un OpenSSH, d'un Irssi et d'un Links, que vous aurait présenté un Ion 3 à peine configuré.

    Voici ce que cet article vous propose : disposer à tout instant du couteau suisse de l'administrateur système UNIX, un NetBSD minimal, mais fonctionnel, qui se logera dans un coin de votre clé USB, sans pour autant la rendre inexploitable par d'autres systèmes. Le but de l'opération sera d'obtenir une clé amorçable, qui n'utilisera pas le système de fichiers de la clé, mais une image brute, générée à l'aide de l'outil dd(1), qu'un noyau affublé d'un RAMDISK ira mounter comme root filesystem.
    Pour construire notre OS minimal, nous utiliserons, sur une machine NetBSD 3.1, des outils présents dans le basesystem, mais également Grub, disponible dans pkgsrc (pkgsrc/sysutils/grub). Enfin, Qemu, installable depuis pkgsrc/emulators/qemu, nous servira à tester nos travaux. Cet article s'appuie sur un projet sur lequel j'ai travaillé en 2006 : the NetBSD LiveKey (http://imil.net/nlk/). J'utiliserai donc tout naturellement quelques scripts écrits pour l'occasion qui nous simplifieront grandement la tâche.

    NOTE
    Quelques notions des systèmes BSD, et particulièrement NetBSD, sont nécessaires pour la bonne compréhension de cet article. Si toutefois ces notions vous faisaient défaut, vous trouverez probablement de l'aide dans le fabuleux NetBSD Guide à cette adresse http:www.netbsd.org/guide/en/ ou en version française (mais un peu dépassée) à cette adresse : http:www.mclink.it/personal/MG2508/nbsdfra/netbsd.html.

    1. Création du noyau

    La première étape de notre périple va consister à créer un noyau muni d'un RAMDISK. Pour cela, nous allons compiler un noyau NetBSD de manière habituelle (voir http://netbsd.org/Documentation/kernel/#how_to_build_a_kernel), en nous assurant que les options suivantes sont bien activées/renseignées :

    # Nous allons utiliser UNION filesystem pour mounter
    # les partitions "réelles" sur le ramdisk
    file-system     UNION
    
    # vnd est le device permettant de mounter des images,
    # notre root filesystem sera une image
    pseudo-device   vnd             4
    # et pour stocker encore un peu plus de données,
    # nous utiliserons une image compressée
    options         VND_COMPRESSION
    
    # Les directives de création et d'espace nécessaire
    # au RAMDISK
    options         MEMORY_DISK_HOOKS
    options         MEMORY_DISK_IS_ROOT
    options         MEMORY_DISK_SERVER=0
    options         MEMORY_DISK_ROOT_SIZE=32768
    options         MEMORY_RBFLAGS=0

    Procédons donc à la compilation de ce noyau custom (on considère que le fichier de configuration utilisé est NBUSB) :

    # pwd
    /usr/src/sys/arch/i386/conf
    # config NBUSB
    # cd ../compile/NBUSB
    # make depend && make

    Si tout s'est bien déroulé, vous devriez maintenant disposer d'un noyau nommé netbsd à cet endroit de l'arborescence.
    Il nous faut maintenant affubler ce noyau anormalement gros d'un root filesystem minimal, qui constituera le pivot de notre mini-OS. Afin de simplifier l'opération, nous allons peupler ce RAMDISK de quelques outils compilés statiquement, que nous piocherons dans le répertoire /rescue de notre NetBSD souche. Pour peupler ce disque d'amorçage du système, nous devons réfléchir aux différentes étapes : 1. obligatoires dans une séquence de boot, 2. dont nous allons avoir besoin dans le cas spécifique qui nous occupe, à savoir, utiliser autre chose que le système de fichiers initial.
    Nous savons que le premier processus qui sera appelé est init(8), classiquement situé dans /sbin. Créons donc une fausse arborescence munie de cette ébauche d'OS :

    # mkdir -p /home/pinpin/nbusb/fakeroot/sbin
    # cp /rescue/init /home/pinpin/nbusb/fakeroot/sbin

    init(8), sur un système héritier de 4.0BSD, exécute le script /etc/rc, qui habituellement s'occupe de démarrer différents services à l'aide des divers /etc/rc.*. Nous allons utiliser rc(8) de manière beaucoup plus basique. En effet, cet /etc/rc sera exécuté dans le contexte d'un boot singulier, et c'est à lui que reviendra la charge d'effectuer le pivot entre le RAMDISK et l'image root contenant les moult outils qui motivent cette tâche. Voici un exemple de fichier fakeroot/etc/rc minimal et commenté :

     # debut de /etc/rc
    
    echo "Initialisation du système..."
    
    export PATH=/sbin:/bin:/usr/sbin:/usr/bin
    # on exporte la variable qui contient le point
    # de montage de la clé
    KEYMOUNTPOINT=/mnt
    # puis une variable contenant les données utiles
    KEYFILESPATH=${KEYMOUNTPOINT}/nbusb
    # enfin, le nom de l'image que nous créerons plus tard
    IMGNAME=nbusb.zimg
    
    sleep 2 # on attend la fin de l'affichage
    
    echo
    echo "--------------------------------------------"
    echo " . Stage 2: montage de l'image disque"
    echo "--------------------------------------------"
    echo
    echo "Nous allons monter le système de fichier VFAT."
    echo -n "Entrez le device sur lequel se trouve " \
            "l'image root (wd0a, wd0e, sd0e...): "
    read dev
    
    # 1ere passe, on monte la clé avec le système
    # de fichiers VFAT
    echo "Montage de /dev/${dev}"
    mount_msdos /dev/${dev} ${KEYMOUNTPOINT}
    
    # Nous avons maintenant la main sur le filesystem de la clé,
    # nous allons pouvoir créer le device virtuel vnd qui sera
    # associé au fichier image
    vnconfig -z vnd0 ${KEYFILESPATH}/${IMGNAME}
    # /!\ issu de man vnconfig :
    #
    #     -z      Assume that regular file is compressed
    #             disk image in cloop2 format, and
    #             configures it read-only.
    #                           ^^^^^^^^^
    
    # 2eme passe, nous pouvons maintenant monter / issu
    # du device vnd
    mount_ffs -o ro,union /dev/vnd0a / >/dev/null 2>&1
    
    # puis on monte le reste du filesystem en Memory
    # FileSystem (vnd compressé et en lecture seule)
    echo "montages mfs"
    mount_mfs -s 262144 swap /tmp
    mount_mfs -s 12000 swap /dev
    mount_mfs -s 262144 swap /var
    mount_mfs -s 131072 swap /etc
    mount_mfs -s 262144 swap /home
    mount_mfs -s 262144 swap /usr/pkg
    sleep 1
    
    echo "Création des devices..."
    cd /dev && sh MAKEDEV all
    
    echo
    echo "--------------------------------------------"
    echo " . Stage 3: multiutilisateur"
    echo "--------------------------------------------"
    echo
    
    # on appelle maintenant le "vrai" rc
    sh /etc/rc
    
    # fin de /etc/rc

    Ce rc fait appel à différents exécutables que nous devons donc copier sur notre clé : sh (sans lui, point de rc !) et sleep dans fakeroot/bin, puis mount_msdos, mount_ffs, mount_mfs et vnconfig dans fakeroot/sbin. Copiez également les bibliothèques desquelles dépendent ces outils, typiquement tout /lib, /usr/lib/libc.so* ainsi que /usr/lib/libutil.so.* et évidemment /libexec/ld.elf_so.
    Maintenant que nous disposons de la structure de fichiers initiale, il nous faut la greffer à notre noyau. Nous allons pour cela utiliser les outils makefs(8) et mdsetimage(8). Ces outils servent respectivement à générer une image à partir d'une structure de fichiers et à copier cette image dans le RAMDISK du noyau.
    Créons une image de 16 mégaoctets du filesystem basique créé plus haut. Nous choisissons évidemment FFS comme type de système de fichiers :

    # makefs -s 16m -t ffs md.img fakeroot

    Copions maintenant cette image dans notre RAMDISK :

    # mdsetimage netbsd md.img

    Afin de ne gaspiller aucun octet, compressons ce noyau :

    # gzip -9 netbsd && mv netbsd.gz netbsd

    Votre noyau est fin prêt.

    2. Création du root filesystem

    Muni de son système initial, notre noyau va dérouler, init(8) va invoquer rc qui va tenter de monter l'image nbusb.zimg. Ce fichier image n'est rien de plus qu'un disque virtuel créé à l'aide de dd(1), que nous allons peupler comme une simple partition.
    Créons donc un disque vide de 128 mégaoctets :

    # dd if=/dev/zero of=nbusb.img count=262144 bs=512

    Associons-le à un device virtuel de type vnd :

    # vnconfig -c -v /dev/vnd0 nbusb.img

    On génère, comme pour un véritable disque, un label :

     # cat > nbusb.disktab << EOF
      miniroot:\
      :ty=floppy:se#512:nt#1:rm#3600:ns#262144:nc#1:\
      :pa#262144:oa#0:ba#4096:fa#512:ta=4.2BSD:\
      :pb#262144:ob#0:\
      :pc#262144:oc#0:
      EOF

    On inscrit ce label :

    # disklabel -w -f nbusb.disktab /dev/vnd0 nbusb

    Puis, on construit le système de fichiers :

    # newfs -m 0 /dev/vnd0a

    Il est désormais possible de monter ce disque :

    # mount /dev/vnd0a /mnt

    Reste à peupler ce disque avec les packages de base de votre choix. Pour cette petite démonstration, nous nous contenterons des sets base et etc, que vous pourrez télécharger ici : ftp://ftp.netbsd.org/pub/NetBSD/NetBSD-3.1/i386/binary/sets/. Remplissons notre faux disque des packages fraîchement récupérés :

    # cd /mnt
    # tar zxvfp /home/pinpin/tmp/base.tgz
    # tar zxvfp /home/pinpin/tmp/etc.tgz

    Notre image dispose maintenant d'un système minimal, mais parfaitement fonctionnel. Reste à lui apporter quelques petites modifications afin de le rendre exploitable ; comme placer la variable rc_configured à YES dans etc/rc.conf, éventuellement ajouter un utilisateur ou en tout cas s'assurer qu'on pourra passer root. Pourquoi pas spécifier un nom d'hôte dans /etc/myname ou configurer quelques variables d'environnement dans l’/etc/profile.
    Notre disque créé et peuplé, il nous reste à le compresser afin qu'il occupe le moins de place possible sur notre clé. Ceci est réalisé à l'aide de la commande vndcompress(1) :
    On démonte notre disque virtuel :

    # umount /mnt

    On le désassocie du device vnd0 :

    # vnconfig -u vnd0

    Et on compresse l'image :

    # vndcompress nbusb.img nbimg.zimg

    Nous avons spécifié dans le fichier rc du RAMDISK que l'image se situera dans le répertoire nbusb/ sur la clé au format VFAT. C’est donc dans ce répertoire que nous allons copier notre image :

    # mount_msdos /dev/sd0e /mnt

    sd0e représente le device associé à la partition VFAT de notre clé :

    # mkdir /mnt/nbusb
    # cp netbsd /mnt/nbusb
    # cp nbusb.zimg /mnt/nbusb

    Reste à rendre notre clé amorçable grâce à Grub :

    # grub-install --root-directory=/mnt /dev/sd0

    Et créer un menu.lst idoine :

    # cat > /mnt/boot/grub/menu.lst << EOF
    title NetBSD LiveKey
    root (hd0,0)
    kernel --type=netbsd /nbusb/netbsd
    boot
    EOF

    C'est terminé !
    Vous pouvez maintenant tester votre NetBSD-light grâce, par exemple, à l'excellent Qemu en utilisant la syntaxe suivante :

    # qemu /dev/sda

    Si tout se passe bien, vous devriez admirer un magnifique menu Grub.

    /img-articles/lmhs/29/cc-art-netbsdpoche/fig-1.jpg

    ATTENTION
    Pour Qemu, le disque source sera exploité comme un disque IDE. Aussi, lorsque rc demandera quel device utiliser comme root filesystem, c'est bien wd0X (ou X=a, e...) qu'il faudra entrer, a contrario d'une vraie utilisation lors de laquelle le noyau NetBSD associera votre clé à un device de type sdXY.

    /img-articles/lmhs/29/cc-art-netbsdpoche/fig-2.jpg

    À la fin de la séquence de boot, vous devriez normalement vous trouver devant un TTY qui vous présente fièrement sa demande de login. Y'a plus qu'à.

    /img-articles/lmhs/29/cc-art-netbsdpoche/fig-3.jpg

    3. Au revoir président

    L'article se finit ici, mais vous avez certainement compris que c'est également ici que démarrent les insomnies, car il ne tient qu'à vous de créer autant de configurations de NetBSD " embarquées " que vous le souhaitez, de faire le ménage dans le basesystem, de retoucher, réécrire, repenser le rc basique !
    De plus, il reste dans notre image basique plusieurs dizaines de mégas inutilisés. Faites donc une petite sélection de packages (FTP : ftp.netbsd.org/pub/NetBSD/packages/3.0/i386/), puis à l'aide de pkg_add -p, installez-les dans votre environnement minimal. Attention, l'image compressée est en lecture seule. Il faudra travailler sur l'image décompressée puis regénérer le .zimg à l'aide de VNDcompress.
    Vous trouverez quelques ajouts, ainsi que des scripts automatisant les étapes que nous avons vues à l'adresse suivante : http://imil.net/nlk/. L’/etc/rc de ce projet utilise par exemple un autre répertoire sur la clé afin de pouvoir modifier des fichiers de configuration classiques sans devoir reconstruire la clé. Il est également capable d'installer au boot des packages qui se trouvent dans le répertoire livekey/ et il mounte /root en lecture écriture sur un répertoire situé sur la clé. Bien des améliorations sont imaginables, et il est sans aucun doute possible d'accélérer entre autres le processus de boot. Et comme d'habitude, commentaires et contributions sont les bienvenus :)

    Références

    Quelques liens connexes :

    • http://pkgsrc.se/sysutils/mklivecd
    • http://www.yazzy.org/docs/NetBSD/netbsd-livecd.txt
    • http://wiki.netbsd.se/index.php/How_to_build_your_own_NetBSD_LiveCD
    • http://www.wifibsd.org/
    Posté par Emile Heitor (iMil) | Signature : Emile « iMil » Heitor (GCU) | Article paru dans Creative Commons License

    Laissez une réponse

    Vous devez avoir ouvert une session pour écrire un commentaire.