Nous nous sommes concentrés jusqu'ici sur ce que les packages font. Je vais vous donner ici tout les indices que je peux pour fabriquer un système Linux de base à partir des sources. Si vous voulez monter un vrai système pour du vrai travail, lisez le Linux From Scratch HOWTO.
Il est possible d'obtenir une ligne de commande bash sans installer tout ce que je mentionne ici. Ce que je décris est un système de base, sans embûche, qui peut être monté facilement.
Nous installerons une distribution de Linux comme Red Hat sur une partition, et l'utiliserons pour construire un nouveau système Linux sur une autre partition. Je nommerai par la suite ``cible'' le système que nous construisons, et ``source'' le système que nous utilisons pour construire le système cible (à ne pas confondre avec code source que nous utiliserons aussi).
Vous allez donc avoir besoin d'une machine avec deux partitions libres dessus. Si vous le pouvez, utilisez une machine qui ne contienne rien d'important. Vous pouvez utiliser un système Linux déjà existant comme système source, mais je le déconseille. Si vous oubliez un des paramètres des commandes que nous allons saisir, vous pourriez accidentellement réinstaller des choses sur votre système source. Cela peut mener à des incompatibilités, et des conflits.
Les anciennes architectures PC, pour la plupart 486 et plus ancien, ont une
limitation ennuyeuse de leur Bios. Il ne peuvent lire les disques durs passé
les 512 premiers mégaoctets. Ce n'est pas vraiment un problème pour Linux, qui
gère lui-même les disques une fois lancé. Mais pour que Linux soit chargé
sur ces vieilles machines, le noyau doit résider quelque part en dessous de
512 mégaoctets. Si vous utilisez une de ces machines, vous devez créer une
partition distincte en dessous de 512 Mo, à monter sur /boot
pour
toute partition au dessus de la limite des 512 Mo.
La dernière fois que je l'ai fait, j'ai utilisé Red Hat 6.1 comme système source. J'ai installé le système de base plus
J'ai aussi installé X-window et Mozilla (NDT : Netscape) pour pouvoir lire les documentations facilement, mais ce n'est pas nécessaire. A la fin de mon travail, cela avait pris environ 350M d'espace disque (Cela semble un peu élevé, je me demande pourquoi).
Le système cible achevé prenait 650M, mais comprenait tout le code source et
les fichiers intermédiaires. Si l'espace est limité, je vous conseille de
faire un make clean
après la construction de chaque package. Cela
dit, c'est une source d'ennuis et d'hésitation.
Enfin, vous allez avoir besoin du code source du système que vous allez construire. Il y a les ``packages'' dont nous avons parlé dans ce document. On peut les obtenir depuis un CD, ou par l'Internet. Je donnerai les URL pour les sites américains et miroirs australiens.
agetty
et
login
.
Pour résumer, il vous faut :
Je pars du principe que vous pouvez installer le système source vous-même, sans aide de ma part. A partir de maintenant, je considère que c'est fait.
Les premiers pas de ce projet consistent à faire démarrer le noyau, et le
laisser `paniquer' (panic) car il ne peut trouver le programme init
.
Cela signifie que nous allons devoir installer un noyau, et installer Lilo.
Pour que Lilo fonctionne quand même correctement, nous avons besoin
d'installer les fichiers spéciaux dans le /dev
du système cible.
Lilo en a besoin pour effectuer les accès bas niveau au disque, nécessaire
pour écrire le secteur d'amorce. MAKEDEV est le script qui crée ces fichiers
spéciaux (Vous pourriez bien sûr les recopier depuis le système source, mais
ce serait tricher !). Mais d'abord, il nous faut un système de fichiers
pour les mettre dedans.
Notre nouveau système a besoin d'un système de fichiers pour vivre. Donc, il
nous faut tout d'abord créer ce système de fichiers en utilisant mke2fs
. Ensuite
il faut le monter quelque part. Je vous suggère /mnt/target
(comme
`cible'). Dans ce qui va suivre, je considère que votre système se trouve à cet
endroit. Vous pouvez gagner un peu de temps en ajoutant une entrée dans
/etc/fstab
de façon à ce que le montage de votre système
destination soit automatique lorsque votre système source démarre.
Lorsque nous démarrerons le système cible, ce qui se trouve dans
/mnt/target
se trouvera alors dans /
(à la racine).
Nous avons besoin d'une structure de sous-répertoires sur la cible. Jetez un
oeil au Standard de la Hiérarchie des Fichiers (File Hierarchy Standard,
voir section
Système de Fichiers).
pour trouver vous même ce qu'elle devrait être, ou faites simplement un cd
vers l'endroit où la cible est montée et tapez aveuglément :
mkdir bin boot dev etc home lib mnt root sbin tmp usr var cd var; mkdir lock log run spool cd ../usr; mkdir bin include lib local sbin share src cd share/; mkdir man; cd man mkdir man1 man2 man3 ... man9
Comme le FHS et la plupart des packages se contredisent en ce qui concerne l'endroit où les man pages doivent se trouver, nous avons besoin d'un lien symbolique :
cd ..; ln -s share/man man
Nous mettrons le code source dans le répertoire /usr/src
cible.
Aussi si votre système de fichiers cible est monté par exemple sur
/mnt/target
, et que vos archives sont dans /root
, il
faudra faire :
cd /mnt/target/usr/src tar -xzvf /root/MAKEDEV-2.5.tar.gz
Ne vous comportez pas en amateur fini et pensez à copier vos archives à l'endroit où vous allez les décompresser ;-)
En principe, lorsque vous installez un logiciel, vous l'installez sur le système en fonctionnement. En l'occurence, ce n'est pas notre intention, nous souhaitons l'installer comme si /mnt/target était le système de fichiers racine. Les différents packages ont différentes manières de vous le laisser faire. Pour MAKEDEV, vous devez faire
ROOT=/mnt/target make install
Vous devez rechercher ces options dans les fichiers README et INSTALL
ou faire un ./configure --help
.
Explorez le Makefile
de MAKEDEV pour voir l'usage qu'il fait de
la variable ROOT, que nous avons définie dans cette commande. Ensuite jetez
un oeil à la page de manuel en faisant un man ./MAKEDEV.man
pour voir comment il fonctionne. Vous découvrirez que la méthode utilisée
pour ces fichiers spéciaux consiste à faire un cd /mnt/target/dev
puis
un ./MAKEDEV generic
. Faites un ls
pour découvrir tous les
merveilleux fichiers spéciaux qu'il a créés pour vous !
Ensuite, nous devons fabriquer un noyau. Je considère que vous l'avez déjà
fait, aussi serai-je bref. Il est plus facile d'installer Lilo si le noyau
censé être monté est déjà là. Retournez dans le répertoire /usr/src
de la cible, et décompressez-y les sources du noyau linux. Entrez dans
l'arborescence des sources (cd linux
) et configurez le noyau, en
utilisant votre méthode préférée, comme par exemple make menuconfig
.
Vous vous faciliterez grandement la vie si vous configurez un noyau sans
module. Si vous configurez des modules, vous devrez éditer
Makefile
, trouver INSTALL_MOD_PATH
, et lui affecter la
valeur /mnt/target
.
Vous pouvez maintenant taper make dep
, make bzImage
,
et si vous avez configuré des modules : make modules
,
make modules_install
. Copiez le noyau arch/i386/boot/bzImage
et le plan système System.map
vers le répertoire de boot de la
cible /mnt/target/boot
, et nous seront prêts à installer Lilo.
Lilo est livré avec un très beau script nommé QuickInst
.
Décompressez les sources de Lilo dans le répertoire des sources du système
cible, lancez ce script par la commande
ROOT=/mnt/target ./QuickInst
. Il vous posera plusieurs questions
concernant la manière dont vous souhaitez que Lilo soit installé.
Souvenez-vous, comme nous avons affecté à la variable ROOT
la partition cible, vos noms de fichiers s'y rapportent. Donc, lorsqu'il
vous demandera le nom du noyau à lancer par défaut, répondez
/boot/bzImage
, pas /mnt/target/boot/bzImage
.
J'ai trouvé un bug mineur dans le script, qui lui fait dire :
./QuickInst: /boot/bzImage: no such file
Mais si vous vous contentez de l'ignorer, cela passe quand même.
Comment doit-on s'y prendre pour expliquer à QuickInst
où installer
le secteur de boot ? Quand nous redémarrons, nous voulons avoir le choix
de démarrer le système source ou le système cible, ou encore n'importe quel
autre système présent sur la machine. Et nous souhaitons que l'instance de
Lilo que nous mettons en place maintenant lance le noyau de notre nouveau
système. Comment est-ce que l'on réalise ces deux choses ? Ecartons-nous
un moment du sujet et étudions la façon dont Lilo démarre DOS sur un système
Linux en dual-boot. Le fichier lilo.conf
d'un tel système doit
sûrement ressembler à çà.
prompt timeout = 50 default = linux image = /boot/bzImage label = linux root = /dev/hda1 read-only other = /dev/hda2 label = dos
Si la machine est configurée de cette façon, alors le Master Boot Record
(MBR) est lu et chargé par le Bios, et lance le bootloader de Lilo, qui
affiche une invite de commande. Si vous tapez dos
dans cette
invite, Lilo chargera le secteur de boot depuis hda2, qui lancera DOS.
Ce que nous allons faire est exactement la même chose, mis à part que le
secteur d'amorce d'hda2 va être un autre secteur d'amorce Lilo - celui-là
même que QuickInst
va installer. Donc le Lilo de la distribution de
linux chargera le Lilo que nous avons construit, qui chargera le noyau que
nous avons bâti.
Vous verrez alors deux invites de commande Lilo au redémarrage.
Pour raccourcir une longue histoire, lorsque QuickInst
vous demande où placer le secteur de boot, indiquez-lui l'endroit où se
trouve votre système de fichiers cible, par exemple /dev/hda2
.
Maintenant modifiez le fichier lilo.conf
de votre système source,
de façon à ce qu'il ait une ligne ressemblant à:
other = /dev/hda2 label = target
Lancez Lilo, et nous devrions être capables de faire notre premier démarrage sur le système cible.
L'étape suivante consiste à installer init
, mais comme la plupart
des programmes qui tournent sous Linux, init
utilise des fonctions
issues de la bibliothèque C GNU, glibc. Aussi l'installerons-nous en
premier.
Glibc est un package très gros et très compliqué. Il faut 90 heures pour le bâtir sur mon vieux 386sx/16 avec 8M RAM. Mais cela ne prend que 33 minutes sur mon Celeron 433 avec 64M. Je pense que la quantité de mémoire est le principal critère dans notre cas. Si vous n'avez que 8Mo de RAM (ou - j'en tremble - encore moins !), préparez vous à une très longue compilation.
La documentation d'installation de glibc recommande une construction dans un répertoire distinct. Cela vous permet de recommencer facilement, en supprimant simplement ce répertoire. Cela vous permet aussi d'économiser 265Mo d'espace disque.
Décompressez l'archive glibc-2.1.3.tar.gz
(ou n'importe quelle
autre version) dans /mnt/target/usr/src
comme d'habitude. A
présent, nous devons décompresser les ``add-on'' dans le répertoire de
la glibc. Donc, faites un cd glibc-2.1.3
, puis
décompressez à cet endroit les archives glibc-crypt-2.1.3.tar.gz
et glibc-linuxthreads-2.1.3.tar.gz
.
Maintenant, nous pouvons créer le répertoire de construction, configurer,
bâtir et installer glibc. Voici les commandes que j'ai utilisées, mais relisez
vous-même la documentation et assurez-vous de faire ce qui est le plus
approprié dans votre environnement. Toutefois, avant de faire tout cela,
vous voudrez sans doute connaître l'espace disque qu'il vous reste par un
df
. Vous pouvez en faire un autre après avoir bâti et installé
glibc pour en déduire son volume.
cd .. mkdir glibc-build ../glibc-2.1.3/configure --enable-add-ons --prefix=/usr make make install_root=/mnt/target install
Remarquez que nous avons ici encore une autre façon de dire au package l'endroit où s'installer.
Bâtir et installer les binaires de SysVinit est assez direct. Je me contenterai d'être paresseux et de vous donner les commandes, en considérant que vous avez décompressé son code source, et que vous êtes entré dans son répertoire.
cd src make ROOT=/mnt/target make install
Il existe aussi beaucoup de scripts associés à init
. Il y a des
scripts d'exemple fournis dans le package de SysVinit, qui fonctionnent
bien. Mais vous devez les installer manuellement. Ils sont organisés dans
une hiérarchie sous debian/etc
dans l'arborescence du code source
de SysVinit. Vous pouvez recopier toute cette hiérarchie dans le répertoire
etc
du système cible, avec une commande du style
cd ../debian/etc; cp -r * /mnt/target/etc
.
Evidement, vous explorerez ces scripts avant de tous les recopier.
Tout est désormais en place pour permettre au noyau cible de lancer
init
au redémarrage. Le problème, cette fois, viendra des scripts
qui ne pourront être exécutés car bash
ne sera pas là pour les
interpréter. init
tentera également de lancer des getty
,
qui sont inexistants eux aussi. Rebootez maintenant, et assurez-vous que
tout le reste fonctionne correctement.
L'étape suivante consiste à mettre Bash en place, mais bash a besoin de ncurses, aussi devons-nous installer celui-ci en premier. Ncurses remplace termcap dans la manière de gérer les écrans texte, mais apporte également une compatibilité ascendante en prenant en charge les appels termcap. Dans l'objectif d'avoir un système moderne, simple et propre, je pense que le mieux est de désactiver l'ancienne méthode termcap. Vous pourriez par la suite rencontrer des problèmes avec des applications utilisant termcap, mais au moins vous connaîtrez les éléments qui l'utilisent. Si vous en avez besoin, vous pouvez recompiler ncurses avec prise en charge de termcap.
Les commandes que j'ai utilisées sont :
./configure --prefix=/usr --with-install-prefix=/mnt/target --with-shared --disable-termcap make make install
Il m'a fallu beaucoup de lecture, de réflexion, de tests, et d'erreurs pour que Bash s'installe là où je pensais qu'il devait aller. Les options de configuration que j'ai utilisées sont :
./configure --prefix=/mnt/target/usr/local --exec-prefix=/mnt/target --with-curses
Une fois que vous avez bâti et installé Bash, vous devez créer un lien
symbolique comme ceci : cd /mnt/target/bin; ln -s bash sh
.
Cela est dû au fait que les scripts débutent généralement par une ligne
comme celle-ci :
#!/bin/sh
Si vous n'avez ce lien symbolique, les scripts ne fonctionneront pas, car
ils chercheront /bin/sh
et non /bin/bash
.
Vous pouvez redémarrer à ce point si vous le souhaitez. Vous devriez
remarquer que les scripts peuvent maintenant s'exécuter, bien que vous ne
puissiez vous loguer, car il n'y pas encore de programmes getty
ou
login
.
Le package util-linux contient agetty
et login
. Nous avons
besoin des deux pour nous loguer et obtenir la ligne de commande de bash.
Après l'avoir installé, faites un lien symbolique depuis agetty
vers getty
de le répertoire /sbin
du système cible.
getty
est un des programmes censés se trouver sur tous les systèmes
de type Unix, donc faire un lien est une meilleure idée que de modifier
inittab
pour qu'il lance agetty
.
Il me reste un problème avec la compilation d'util-linux. Le package
contient également le programme more
, et je n'ai pas été capable de
persuader le processus make
de placer le lien more
sur la bibliothèque de ncurses 5 du système cible, plutôt que sur
ncurses 4 du système source. Je regarderai cela de plus près.
Vous aurez aussi besoin d'un fichier /etc/passwd
sur le système
cible. C'est l'endroit où le programme login
ira vérifier votre
accréditation. Comme il ne s'agit que d'un système gadget à ce niveau, vous
pouvez vous permettre des choses scandaleuses, comme ne définir que
l'utilisateur root, sans mot de passe ! Mettez le simplement dans le
fichier
/etc/passwd
du système cible.
root::0:0:root:/root:/bin/bash
Les champs sont séparés par des deux-points, correspondent, de gauche à droite, à l'user id (nom de login), au mot de passe (crypté), au numéro d'utilisateur, au numéro de groupe, au nom de l'utlisateur, à son répertoire personnel, et à son shell par défaut.
Le dernier package dont nous ayons besoin est sh-utils GNU.
Le seul programme nécessaire à ce niveau est stty
, qui est utilisé
dans /etc/init.d/rc
, lui-même utilisé pour changer de niveau
d'exécution et entrer dans le niveau initial. En fait, je possède et ai utilisé
un package qui ne contient que stty
mais je ne peux me souvenir d'où
il vient. Il vaut mieux utiliser le package GNU, car il contient d'autres
choses dont vous aurez besoin si vous voulez les ajouter au système pour le
rendre vraiment utilisable.
Eh bien ça y est. Vous devriez maintenant avoir un système qui doit démarrer
et vous donner l'invite de login. Saisissez-y ``root'', et vous devriez
avoir le shell. Vous ne pourrez pas faire grand chose avec, il n'y a même
pas de commande ls
pour voir votre travail. Tapez deux fois la
touche tab pour voir les commandes disponibles. C'est la chose la plus
intéressante que j'ai trouvée à faire avec.
Il semblerait que nous ayons là un système plutôt inutilisable. Mais en
réalité, nous ne sommes pas très loin de pouvoir commencer à
travailler avec. L'une des premières choses à faire est de rendre le
système de fichiers racine accessible et lecture et écriture. Il y a un script
issu du package, dans /etc/init.d/mountall.sh
qui s'occupe de cela,
et effectue un mount -a
pour monter automatiquement tout ce qui est
spécifié dans le fichier /etc/fstab
. Mettez un lien symbolique du
genre S05mountall
vers lui dans le répertoire etc/rc2.d
du
système cible.
Il se peut que ce script utilise des commandes que vous n'avez pas encore installées. Si c'est le cas, trouvez le package qui contient ces commandes et installez-le. Voyez la section Random Tips pour avoir des indications sur la marche à suivre pour trouver ces packages.
Regardez les autres scripts dans /etc/init.d
. La plupart
d'entre-eux doit être incluse dans tout système sérieux. Ajoutez-les un à un,
et assurez-vous que tout se lance en douceur avant d'en ajouter d'autres.
Lisez le Standard de la Hiérarchie des Fichiers (voir section
Système de Fichiers).
Il contient une liste de commandes qui devraient être dans /bin
et
/sbin
. Assurez-vous que toutes ces commandes sont installées sur votre système.
Mieux encore, trouvez la documentation Posix qui spécifie tout cela.
A partir de maintenant, il n'est plus question que d'ajouter de plus en
plus de packages, jusqu'à ce que tout ce que vous souhaitez avoir se trouve
sur votre système. Installez les outils de construction comme make
et gcc
le plus tôt possible. Une fois que cela est fait, vous
pouvez utiliser votre système cible pour se construire lui-même, ce qui est
bien moins compliqué.
Si vous avez une commande appelée thingy
sur un système Linux avec RPM, et souhaitez avoir des indications sur
l'endroit où trouver les sources, vous pouvez utiliser la commande :
rpm -qif `which thingy`
Et si vous avez un CD de sources Red Hat, vous pouvez installer le code source avec
rpm -i /mnt/cdrom/SRPMS/ce.qu.il.vient.de.dire-1.2.srpm
Ceci mettra l'archive, avec les patches Redhats éventuels dans
/usr/src/redhat/SOURCES
.