Salut
Bon, je commence à y voir un peu plus clair en regardant avec détail le fichier script /linuxrc du ramdisk du liveCD, et également en lisant la page de manuel d'initrd.
Cependant, il y a quelques points que je ne comprends pas. Je commence par initrd ( http://pwet.fr/man/linux/fichiers_speciaux/initrd ) :
Citation :
DÉMARRAGE DU SYSTÈME
Quand il démarre en utilisant initrd, le système procède comme suit:
1. Le chargeur place une copie du noyau en mémoire, ainsi que le contenu de /dev/initrd.
2. Au démarrage du noyau, celui-ci décompresse et recopie le contenu du périphérique /dev/initrd sur le disque virtuel /dev/ram0 puis libère la mémoire utilisée par /dev/initrd.
3. Le noyau monte en lecture-écriture le périphérique /dev/ram0 comme racine initiale du système de fichiers.
4. Si la racine désirée pour le système de fichiers est également celle que l'on vient de monter (par ex. /dev/ram0), le noyau passe directement à la dernière étape du démarrage.
5. Si un fichier exécutable /linuxrc est présent sur le système de fichiers racine initial, ce fichier est exécuté avec l'uid 0. (Le fichier /linuxrc doit avoir la permission d'exécution. Ce peut être n'importe quel exécutable, y compris un shell-script.)
6. Si /linuxrc n'est pas exécuté ou lorsqu'il se termine, la racine normale du système de fichiers est montée. (Si /linuxrc se termine en ayant monté d'autres systèmes de fichiers sur la racine initiale, alors le comportement du noyau est INDÉTERMINÉ. Voir le paragraphe NOTES pour le comportement effectif.)
7. Si la racine normale dispose d'un répertoire /initrd, le périphérique /dev/ram0 est déplacé depuis / vers /initrd. Sinon, si le répertoire /initrd n'existe pas, le périphérique /dev/ram0 est démonté. (Lors du déplacement de / vers /initrd, /dev/ram0 n'est pas démonté, aussi des processus peuvent continuer à s'exécuter depuis ce périphérique. Si le répertoire /initrd n'existe pas sur le système de fichiers normal, et si des processus continuent à s'exécuter depuis /dev/ram0 lorsque /linuxrc se termine, le comportement du noyau est INDÉTERMINÉ. Voir le paragraphe NOTES pour le comportement effectif.)
8. La séquence de démarrage habituelle (invocation de /sbin/init) est alors effectuée depuis le système de fichiers normal.
|
Je ne comprends pas bien le point 6. Qu'entendent-ils par "si /linuxrc se termine en ayant monté d'autres systèmes de fichiers sur la racine initiale, alors ..."
Cela signifie : si on a fait des mounts supplémentaires ( genre dans /mnt/toto ou autre ), ou bien si on a remplacé la racine ( qui est à ce moment là /dev/ram0 qui est en fait le initrd.gz ) par autre chose ( genre, dans ce cas là, le unionfs que je souhaite faire ) ?
J'ai globalement compris le reste du détail de la séquence de démarrage, et je pense que c'est exactement avec ce mécanisme que je vais pouvoir faire ce que je souhaite faire, d'ailleurs si je regarde en détail le /linuxrc du live CD de mandriva , cela confirmerait mon hypothèse.
Je passe à la suite.
Apparemment, le paragraphe suivant de la page man explique qu'on peut effectivement se servir d'initrd pour changer la racine du système de fichier. Serait-ce l'explication à mon interrogation précédente ? A savoir, on ne peut pas changer la racine ( voir 6. ) SAUF si on applique ce qui est expliqué dans ce paragraphe ?
je cite :
Citation :
Le système de fichiers utilisé comme racine par défaut est celui qui est compilé dans le noyau (ou configuré avec rdev), ou celui qui est spécifié par une option du chargeur. Pour accéder à un système de fichiers monté par NFS, il faut utiliser les options de démarrage nfs_root_name et nfs_root_addrs pour la configuration NFS. Pour plus d'information sur les racines de systèmes de fichiers montées par NFS, consultez le fichier nfsroot.txt, dans la documentation du noyau. Pour plus d'informations sur la configuration de la racine du système de fichiers, voyez également les documentations de LILO et LOADLIN.
On peut aussi faire effectuer la modification de la racine normale par l'exécutable /linuxrc. Pour ce faire, le système /proc doit être monté. Ensuite, /linuxrc modifie le périphérique racine en écrivant directement dans les fichiers /proc/sys/kernel/real-root-dev, /proc/sys/kernel/nfs-root-name, et /proc/sys/kernel/nfs-root-addrs. Pour un périphérique physique monté à la racine, le changement s'effectue en écrivant le numéro de périphérique du nouveau système de fichiers dans /proc/sys/kernel/real-root-dev. Pour un système monté par NFS, la modification se fait en écrivant la configuration NFS dans les fichiers /proc/sys/kernel/nfs-root-name et /proc/sys/kernel/nfs-root-addrs puis en inscrivant 0xff (c.-à-d. le numéro de pseudo-périphérique NFS) dans le fichier /proc/sys/kernel/real-root-dev. Par exemple, la ligne de commande suivant basculerait le périphérique racine normale sur /dev/hdb1:
echo 0x365 >/proc/sys/kernel/real-root-dev
La ligne suivante modifierait le périphérique normal en un répertoire NFS /var/nfsroot sur un serveur local ayant l'adresse IP 193.8.232.7, ceci sur un système nommé idefix, se trouvant à l'adresse 193.8.232.7:
echo /var/nfsroot >/proc/sys/kernel/nfs-root-name
echo 193.8.232.2:193.8.232.7::255.255.255.0:idefix \
>/proc/sys/kernel/nfs-root-addrs
echo 255 >/proc/sys/kernel/real-root-dev
|
Dans cette explication, cela parle beaucoup de NFS, je ne suis pas dans ce cas. Je souhaite monter la racine sur un unionfs d'un squashfs en ro d'un coté, et un tmpfs en rw de l'autre ( comme un liveCD en fait). Et ce squashfs serait stocké sur une CF , dans laquelle il y aurait également le noyau et l'initrd ( quasiment comme un liveCD - bis ).
Si j'ai bien compris, c'est la ligne : echo 0x365 >/proc/sys/kernel/real-root-dev qui me permettrait d'avoir le droit de changer la racine avec linuxrc.
Passons maintenant au détail du fichier /linuxrc de l'initrd du liveCD mandriva 2010.
Code :
- #!/bin/nash
- nash-mount -t proc /proc /proc
- nash-mount -t sysfs /sys /sys
- /bin/plymouthd
- plymouth --show-splash
- probe-modules ide_core
- probe-modules ide_cd_mod
- probe-modules scsi_mod
- probe-modules sr_mod
- probe-modules nls_iso8859_1
- probe-modules nls_iso8859_2
- probe-modules nls_iso8859_3
- probe-modules nls_iso8859_4
- probe-modules nls_iso8859_5
- probe-modules nls_iso8859_6
- probe-modules nls_iso8859_7
- probe-modules nls_iso8859_9
- probe-modules nls_iso8859_13
- probe-modules nls_iso8859_14
- probe-modules nls_iso8859_15
- probe-modules nls_utf8
- probe-modules isofs
- probe-modules fat
- probe-modules vfat
- probe-modules crc_t10dif
- probe-modules sd_mod
- probe-modules usbcore
- probe-modules usb_storage
- probe-modules uhci_hcd
- probe-modules ohci_hcd
- probe-modules ehci_hcd
- probe-modules loop max_loop=64
- probe-modules squashfs
- probe-modules unionfs
- probe-modules --cdrom
- sh -c 'if grep -q initrd_debug /proc/cmdline; then plymouth --quit; exec sh </dev/console >/dev/console 2>/dev/console; fi'
- for i in seq 1 5; do showlabels --removable | grep LABEL=One-2010S-KDE4; if [ $? -eq 0 ]; then break; fi; sleep 1; done
- showlabels --removable
- nash-mount -o ro -t iso9660 LABEL=One-2010S-KDE4 /live/media
- /bin/losetup /dev/loop0 /live/media/loopbacks/distrib-lzma.sqfs
- nash-mount -o ro -t squashfs /dev/loop0 /live/distrib
- mount -t tmpfs -o mode=755 /live/memory /live/memory
- sh -c 'mount -o dirs=/live/memory=rw:/live/distrib=ro -t unionfs unionfs /live/union'
- plymouth --newroot=/live/union
- echo 0x0100 > /proc/sys/kernel/real-root-dev
- umount /sys
- sh -c 'umount /proc/bus/usb 2>/dev/null'
- umount /proc
- pivot_root /live/union /live/union/initrd
- sh -c 'rmdir /initrd/live/union'
- sh -c 'cd /initrd/live; for i in `ls -1`; do [ -d $i ] || continue; mkdir -p /live/$i; mount -n --move $i /live/$i; rmdir $i; done'
- rmdir /initrd/live
- nash-mount -o mode=0755 -t tmpfs /dev /dev
- sh -c 'rm -rf /dev/loop'
- sh -c 'mv /initrd/dev/* /dev/'
|
nash-mount doit être un utilitaire équivalent à mount ( pourquoi ils utilisent celui-là, mystère ...) ,et plymouth à l'air d'être un gestionnaire de splashscreen.
Première chose effectuée ( je passe les inits diverses ) : montage du CDROM dans /live/media (ligne 39)
Code :
- nash-mount -o ro -t iso9660 LABEL=One-2010S-KDE4 /live/media
|
ensuite montage du squashfs en 2 étapes ( car nash-mount ne doit pas savoir gérer les périphériques loop ) dans /live/distrib (ligne 40 et 41)
Code :
- /bin/losetup /dev/loop0 /live/media/loopbacks/distrib-lzma.sqfs
- nash-mount -o ro -t squashfs /dev/loop0 /live/distrib
|
ensuite montage du tmpfs dans /live/memory ( ligne 42 )
Bizarre, ici ils utilisent mount et non nash-mount
Code :
- mount -t tmpfs -o mode=755 /live/memory /live/memory
|
Ensuite , création du unionfs entre /live/memory et /live/distrib, resultat dans /live/union ( ligne 43 )
Code :
- sh -c 'mount -o dirs=/live/memory=rw:/live/distrib=ro -t unionfs unionfs /live/union'
|
Ensuite, commande qui je ne sais pas à quoi elle sert ( ligne 44 )
Code :
- plymouth --newroot=/live/union
|
Ensuite, la ligne dont je parlais précédemment à propos de l'initrd ( ligne 45 )
Code :
- echo 0x0100 > /proc/sys/kernel/real-root-dev
|
Que représente 0x0100 ? Pourquoi ce choix ? Comment choisir le numéro que je dois mettre dans mon cas ( décrit plus haut )
Ensuite proc et sys sont démonté ( certainement parce qu'ils seront remontés plus tard par un des scripts appelés par /sbin/init ) , ligne 46 à 48
Code :
- umount /sys
- sh -c 'umount /proc/bus/usb 2>/dev/null'
- umount /proc
|
Pourquoi démonter également /proc/bus/usb alors que je ne l'ai pas monté ?
Puis, une commande qui d'après la page man , permet de changer la racine. C'est exactement ce que je veux. Je suis juste étonné qu'on n'en parle pas dans la page man de initrd ( ligne 49 )
Code :
- pivot_root /live/union /live/union/initrd
|
D'après la page man de pivot_root , cette commande permet de changer la racine, la nouvelle étant le premier paramètre, et l'ancienne est bougée dans le 2eme paramètre.
Donc si je détaille bien cet appel :
avant l'appel : / est /dev/ram0 ( le contenu de mon initrd.gz )
après l'appel : / devient /live/union ( donc ( l'union de squashfs et tmpfs ) , et /dev/ram0 bouge dans le sous répertoire /live/union/initrd ... ET comme /live/union devient / , alors le contenu de /dev/ram0 se trouve en réalité dans /initrd
/initrd contient donc la totalité de mon ramdisk + /initrd/live/union ( qui est maintenant vide ) + /initrd/live/memory ( qui est mon tmpfs ) + /initrd/live/distrib ( qui est mon squashfs ).
les lignes 50-51-52 nettoie ce répertoire /initrd/live en enlevant tous les répertoires, et en déplacant les montages directement dans /live
ensuite ligne 53-54-55
Code :
- nash-mount -o mode=0755 -t tmpfs /dev /dev
- sh -c 'rm -rf /dev/loop'
- sh -c 'mv /initrd/dev/* /dev/'
|
Je ne comprends pas le besoin de faire ces appels. Si je comprends bien, le but est de déplacer tous les fichiers de périphériques du ramdisk vers un tmpfs créé. Mais il y a également un répertoire /dev provenant du squashfs, qui se retrouve donc au même endroit. Que se passe-t-il ? Le montage ligne 53 écrase le /dev du squashfs ? Ou alors il y a fusion ?
Fin du script.
Si je reprends le détail de initrd, ensuite s'exécute normalement /sbin/init et la séquence de démarrage va partir du unionfs entre squashfs et tmpfs.
Sauf que si je reprends le point 6 qui me posait problème :
- ne sommes-nous pas dans le cas : "Si /linuxrc se termine en ayant monté d'autres systèmes de fichiers sur la racine initiale, alors le comportement du noyau est INDÉTERMINÉ."
- sinon , quelle opération a permis de dire que nous ne sommes pas dans un cas indeterminé ? ( ex : le echo 0x0100 > /proc/sys/kernel/real-root-dev ) ?
En espérant que pour ceux qui m'ont lu jusque là, qu'ils auront encore le courage de me donner des réponses à mes nombreuses interrogations
( bien entendu, lorsque j'aurai réussi à faire fonctionner comme je le souhaite, je donnerai tout le détail, ça pourra servir de tutoriel à d'autres qui seront confrontés aux mêmes besoins).