|
(2815 mots dans ce texte ) -
lu : 1895 Fois
 Introduction
On apprend beaucoup sur GNU/Linux en observant le demmarrage du système.
Cela peut paraître rébarbatif mais est essentiel pour la compréhention
Note : Il devient de plus en plus difficile de ne pas
créer un doc spécifique à une distribution au fur et à mesure que l'on avance
dans le système. Le boot est géré différement suivant les distributions et
notemment les scripts de demmarrage ne sont pas les même de l'une à l'autre.
Je vous renverrai donc à la documentation de votre système pour
que vous puissiez aller plus loin.
-1-Le démarrage du PC
Au démarrage, votre pc lance lance un programme. Ce programme s'appelle le
BIOS. Ce bios est situé sur une mémoire de la carte mère, une puce EPROM, il accède à la puce NVRAM, nom de code CMOS
pour charger les paramètres suplémentaires, ceux que vous pouvez modifier en
pressant à ce stade un touche précise du clavier, la touche suppr ou la
touche F2, cela dépend de la carte mère.
Les paramètres du BIOS inscrits dans le CMOS renseignent le bios sur le
processeur, son cadencement, les options diverses plus ou moins riches et
étendues suivant la carte (meilleure est la qualité de la carte mère, plus
ces parmètres sont fouillés, accentuant le contrôle de l'opérateur) et sur
les périfériques de boot, conditionnent
l'utilisation des chipsets, northbridge et southbridge (nom de code
de deux puces facilement identifiables, sur les cartes mères, par leur
taille, le northbridge est recouvert d'un radiateur parfois imposant, voire
d'un petit ventilateur) qui contiennent les différent contrôleurs hardware
des différents bus, pci, agp, usb, etc.
Le bios initialise le matériel, les disques, les lecteurs optiques, la ram et cherche un lanceur sur les secteurs de boot des disques durs (les mbr).
Le bios peut lancer directement le noyau sans l'aide d'un lanceur, si
celui-ci est copié sur une disquette. C'est le principe qu'utilisent certaines des
petites disquettes de boot que chaque distribution vous propose de faire lors
de l'installation.
Pour avoir accès aux données du bios inscrites sur la puce EEPROM (en lecture seulement, seul le bios lui-même, lorsqu'il est lancé au démarrage, peut modifier ces données), il existe une commande administrateur :
biosdecode
-2-Le lanceur du système d'exploitation
Sous GNU/Linux, ce lanceur est lilo ou grub. Le bios ne lit que le premier
secteur du disque dur, une zone qui ne fait que 512 octets et qui contient
aussi la table des partitions du disque dur. Cet espace est trop étroit pour
réellement contenir un programme complet, encore moins un noyau, aussi n'y
est-il copié qu'un premier stage du lanceur dont la fonction est de pointer vers le
programme réel qui se situe ailleurs sur le disque dur, dans le répertoire /boot, pour grub, dans /sbin pour lilo.
Une fois le lanceur chargé en mémoire vive, son rôle sera de trouver et de lancer le
noyau. C'est lui qui prendra en charge la suite des opérations, le lanceur a
fini son travail, il libère la mémoire qu'il occuppait précedemment. Le noyau est alors à son tour entièrement copié en mémoire vive.
On peut donner des instructions au noyau via les fichiers de config de lilo
ou grub, respectivement /etc/lilo.conf et /boot/grub/menu.lst, pour en savoir
plus :
man bootparam
Pour en savoir plus sur les chargeurs de démarrage, je vous renvoie aux manuels respectifs. Nous n'alons pas détailler ici le dépannage des chargeurs de demarrage.
-3-Le lancement du noyau
Le noyau
commence par initialiser le matériel avec ses propres drivers, monte la
racine puis lance le processus init. Les messages qui s'affichent au
démarrage vont très vite, si vous voulez retrouver les message du
noyau une fois le système lancé, utilisez la commande :
dmesg
Le chargement des modules
Les modules sont des programmes qui permettent de comuniquer avec les
contrôleurs des chipsets et ceux des périfériques.
Les modules peuvent être codés "en dur", c'est-à-dire dans le binaire
central du noyau : /boot/vmlinuz* ou en tant que module externe, dans le
repertoire /usr/bin/modules. Avant le montage de la racine, le noyau ne peut
accéder aux modules externes puisque ceux-ci se trouvent sur le disque dur.
Si tous les modules sont externes, la parade consiste à créer un image de ces
modules qui sera chargée en mémoire vive par le lanceur avec le noyau. Cette
image s'appelle initrd, doit être passée à grub en paramètre et placée dans le répertoire /boot.
Les modules complémentaires seront chargés plus tard par les scripts
d'init.
Les processus du noyau
Le noyau utilise jusque là librement la mémoire vive et ses propres processus, lorsque init est lancé, celui-ci prend en charge l'intégralité des processus, y compris ceux du noyau.
-4-Le processus init
Avant toute chose, jetez un coup d'oeil aux processus en cours d'execution
sur votre système :
pstree
init-+-acpid
|-5*[agetty]
|-2*[artsd]
|-atd
......
Vous avez sûrement remarqué le processus init, qui est à la racine de
l'arborescence donnée par pstree. Les processus portent un numéro unique, un PID (Processus Identificateur), attribuer dasn l'ordre d'apparition des processus, init porte le numéro (1), il est le premier procesus
lancé à la fin de la séquence d'initialisation du noyau.
init est aux processus ce que root est aux fichiers. c'est le père de tous
les processus. Son rôle est justement de contrôler ceux-ci. Il prend le relai
du noyau pour finir de lancer le système en lisant les scripts
d'initialisation. sous debian, ces scripts sont dans le répertoire
/etc/init.d , sous slackware, vous les trouverez dans le répertoire
/etc/rc.d, pour les autres distributions, je vous renvoie au /etc/inittab et
à la doc officielle de votre système.
À partir de ce moment-là, init prend en charge tous les processus, y compris ceux du noyau. On les retrouve dans l'arbre des processus, sous le nom kthread :
### [~] $ pstree -pun
init(1)-+-ksoftirqd/0(2)
|-events/0(3)
|-khelper(4)
|-kthread(5)-+-kblockd/0(8)
| |-kacpid(9)
| |-khubd(112)
| |-kseriod(114)
| |-pdflush(165)
| |-pdflush(166)
| |-kswapd0(167)
| |-aio/0(168)
| |-ata/0(824)
| |-ata_aux(825)
| |-scsi_eh_0(832)
| |-scsi_eh_1(833)
| |-reiserfs/0(912)
| |-khpsbpkt(1758)
| |-kpsmoused(2241)
| |-kjournald(4697)
| |-kjournald(4700)
| |-kjournald(4703)
| `-kjournald(4706)
-4-1-Le fichier /etc/inittab
On sait déjà que les fichiers de /etc/ sont les fichiers de configuration
du système. Le fichier inittab est le fichier de configuration d'init, init y
trouvera ce qu'il lui faut pour démarrer les processus suivants : les
différents scripts de démarrage, correspondant à chaque runlevel (nous reviendrons sur ces runlevel plus bas). Chacun de
ces scripts sera lancé tour à tour par init et lanceront de nouveaux
processus.
Voici comment décrypter ce fichier. Chaque entrée a la forme suivante :
id:runlevel:action:process
id : identenfie l'entrée
runlevel : le(s) niveau au(x)quel(s) s'applique l'entrée
action : décrit l'action a effectuer
process : le processus à executer
Le fichier définit par exemple le runlevel qui sera utilisé par défaut
après le boot, par exemple :
id:3:initdefault:
-4-2-Le fichier /sbin/initscript
fichier optionnel qui indique à init les limites et les masks à appliquer
aux processus qu'il va générer lui-même, c'est à dire leurs permissions, le temps de
cpu, la taille en mémoire vive ou en swap qu'ils peuvent atteindre, entre
autres, suivant leurs privilèges.
-4-3-Les runlevels
Les runlevels sont définis par le fichier inittab qui renvoie chaque
runlevel à un script correspondant. Les runlevel S, 0, 1 et 6 sont réservés,
les autres varient suivant les distributions. Ceci est un exemple tiré de
slackware :
- S initialisation du système
- 0 extinction de l'ordinateur
- 1 mode single-user
- 2
- 3 multi-user
- 4 X11 via GDM, KDM ou XDM
- 5
- 6 mode reboot
Le système démarre toujours en mode single user puis passe en mode multi-user. Là, soit il va lancer automatiquement un gestionnaire de connexion graphique, soit il vous laissera en mode terminal. À vous alors, de choisir de lancer ou non un environement de bureau.
Vous pouvez paramètrer la ligne correspondante de votre fichier
/etc/inittab pour changer le initdefault, le runlevel par défaut du
boot. Le mode single user n'est utilisé que pour le dépannage, il n'y a qu'un
seul utilisateur, le root. Les plus comunément utilisés étant quand même le
multi-user simple et le mode graphique. Il ne serait pas très avisé non plus de
mettre 6 comme runlevel par défaut (si vous ne comprennez pas pourquoi,
lancez [rm -R /] dans une console en root pour votre pénitence)
À chaque runlevel correspond un script que init va executer. L'arrêt du système, par exemple, n'est pas une opération si simple, jetez un coup d'oeil à votre scipt pour vous en convaincre.
Avec le mode multi-user, vous vous retrouvez devant le terminal tty1. Vous
pouvez tout de même lancer votre interface graphique avec le script
startx.
Le mode graphique (dans l'exemple, le level 4) lance directement un
gestionnaire de connection graphique, soit gdm, kdm ou xdm.
Dans le fichier d'initialisation correspondant (rc.4 dans mon cas), le
gestionnaire de connection peut être lancé avec le parmètre -nodaemon Si cet
argument n'est pas donné, kdm (ou gdm) sera lancé comme un daemon, détaché du
terminal qui l'a lancé, ce qui a pour effet de liberer le terminal tty1 des
messages du server X, notemment les messages d'erreur.
-5-Passer la main à l'utilisateur
Tout ceci est bel et beau mais à quel moment serons-nous enfin invité à
passer une ou deux commandes? Nous y venons justement...
-5-1-getty et agetty
getty ou agetty (l'un ou l'autre suivant votre système) va gérer la
création de terminaux, ouvrir et conditionner le port, écrire le prompt et
lancer le procesus login qui permet de se connecter au terminal. Après
l'écriture du promt, getty reste en attente d'une réponse de l'utilisateur.
Celui-ci doit rentrer un mon d'utilisateur et appuyer sur le touche entrée. À
ce moment-là, getty lit le nom d'utilisateur et invoque login en l'utilsant
comme argument.
Vous pouvez personnaliser le prompt avec le fichier /etc/issue
Au démarrage, init va lancer un certain nombre de processus getty suivant
le paramettrage donné par inittab. Vous y trouverez des lignes comme
celle-ci:
c1:1235:respawn:/sbin/agetty 338400 tty1 linux
Ici, agetty ouvre le port tty1. Généralement, il y a six à huit ports
ouverts par défault mais il peut y en avoir jusqu'à 63 et plus si vous en
créez de nouveaux mais l'interêt peut sembler limité tout de même.
Les terminaux tty sont les terminaux virtuels auxquels vous accedez par
ctrl+alt+Fn Ceux que vous utilisez via l'interface graphiques sont des pseudo
terminaux initialisés par xterm et correspondent aux périfériques pts ou pty.
À tout moment, vous pouvez savoir qur quel terminal vous êtes en utilisant la
commande :
tty
Dès que getty invoque login, le processus se termine.
-5-2-login
login lit simplement le nom passé en argument par getty, demande le mot de
passe, effectue les vérification d'usage dans le fichier /etc/shadow puis
lance bash dans le terminal. Puis il s'arrête.
Le PID du processus agetty va être donné à login puis à bash, exemple :
init(1)-+-.......
|-bash(2724,zafx)---startx(2819)---xinit(2835)-+-X(2836,root)
| `-.xinitrc(2865)---startkde(2866)+
|-agetty(2727)
|-agetty(2728)
|-agetty(2729)
.......
Dans ce petit extrait de la commande pstree -pun, nous voyons plusieurs choses. La paternité du procesus init est bien mise en évidence. La ligne concernant bash montre les procesus mis en branle pour lancer l'interface graphique depuis un terminal par la commande startx. Les lignes agetty correspondent à des terminaux virtuels inutilisés. Voyons ce qui se passe lorsqu'on va se loguer sur l'un de ces terminaux :
Je rentre la commande ctrl+alt+F4 pour me rendre sur le terminal 4 qui correspond au processus 2727, je rentre mon nom d'utilisateur sans rentrer mon mot de passe toutefois afin de chopper login en pleine action et voici ce que me donne maintenant pstree :
init(1)-+-.......
|-bash(2724,zafx)---startx(2819)---xinit(2835)-+-X(2836,root)
| `-.xinitrc(2865)---startkde(2866)+
|-login(2727)
|-agetty(2728)
|-agetty(2729)
.......
Le procesus 2727 est devenu login. Je finis la procedure de logue et voilà ce que me donne à présent pstree :
.....
|-bash(2724,zafx)---startx(2819)---xinit(2835)-+-X(2836,root)
| `-.xinitrc(2865)---startkde(2866)+....
|-bash(2727,zafx)
|-agetty(2728)
|-agetty(2729)
Le procesus 2727 ne s'apelle plus login mais bash. Si vous voulez faire cette manip chez vous, faites vite, login n'attend pas indéfiniment qu'on lui donne le password, il se déconnecte et le procesus change de PID.
Conclusion
Le système est maintenant lancé et nous savons ce qu'il se passe au
démarrage. Bien des choses ont cependant été laisées de côté, des tas de
processus, ainsi qu'autant, sinon plus de fichiers de configurations n'ont
pas été explorés, bien des détails ont été écartés de ces explications pour
éviter de partir dans tous les sens. J'éspère cependant que ce document peut
servir de base à une exploration approfondie du démarrage du système ou du
moins vous permettre de mieux comprendre ce qui se trame dans les antrailles
de votre ordinateur.
Retour à la sous-rubrique :
Autres publications de la sous-rubrique :
|