GNU/HURD depuis un Linux - rev 20050829

Avant-propos

Juste histoire de voir comment marche la cross-compilation pour obtenir un nouveau systeme qui n'est pas linux.
NB. Pendant toute la compilation prendre du café, un bon CD (original ? ;-D ) ou un bon player audio et lancer de la bonne trance-goa ! hisoire de vous donnez la peche sinon on s'endort !

Notons que ala date de la doc, la cross-compilation fonctionne sur mon linux-gentoo a jour a cette date.

Ce qui est requis

Avant de pouvoir compiler quoi que ce soit, pour obtenir notre distribution GNU/HURD il nous faut 2-3 petites choses :

Des liens utiles (qui m'ont aide a rediger cette documentation)

Les etapes pour avoir notre GNU/HURD

Avant d'avoir quelque chose de fonctionnel (dans le genre stage1 de la gentoo), c'est a dire un systeme minimal, il faut faire les choses en 2 etapes

Etape1

Creer les fichiers interdependants que sont le compilateur, la libc et les entetes du 'noyau' (dans notre cas GNUmach+HURD)

  1. construire notre gcc (meme si on l'a deja!)
  2. contruire les 'cross' binutils (ce sont les cross-assembleurs et cross-linkeurs)
  3. essayer de contruire notre cross-compilateur
  4. installer les header du GNUmach (le micro kernel)
  5. construire le cross-compiler mig
  6. essayer d'installer la libc pour GNU/HURD
  7. finir d'installer le cross-compiler
  8. finir d'installer la libc pour GNU/HURD

A ce niveau nous aurons donc la GNUlibc d'installer pour notre systeme HURD

Etape2

A partir de la nous avons un cross-compileur qui peux cross-compiler n'importe quel programme ecris en C (gcc ne permet pas de cross-compiler du C++ (d'apres ce qui est ecris lors du configure de cross-gcc).

Etape3

A ce niveau notre systeme hurd peut booter et fonctionner, mais on ne peut pas faire grand chose avec :). Profiter en pour decouvrir les differents repertoires et fichiers et regarder la difference avec votre linux !

Etape4

Bienvenue dans le monde du HURD.

Recuperation des codes sources

Le mieux est de travailler dans un repertoire de votre $HOME, mais n'importe quel repertoire monter avec un access sufisant en tant qu'utilisateur peut faire l'affaire.

cd $HOME
mkdir hurd
cd hurd

Attention aux version que vous prenez, generalement pour l'etat des codes sources du hurd, il vaux mieux prendre :
gcc-3.3.6 / glibc-2.3.5 / binutils-2.15
qui est le triplet d'outils que j'ai utilise pour faire cette documentation

Note. si vous avez d'autre version qui marchent, faite le moi savoir je les rajouterai dans la liste ici !

Si vous n'avez pas cvs, j'ai mis a cote de ce fichier des snapshots de gnumach, hurd et mig provenant du cvs. ceux-ci marche avec le triplet d'outils ci-dessus.

Nous allons maintenant creer le repertoire resultat qui contiendra nos outils de cross-compilation

mkdir cross-tool

Pour etre plus a l'aise on va utiliser une variable temporaire $CROSS qui va rendre plus lisible les scripts qui vont suivre, ainsi que la variable $HURD_DIR pour etre tous ce qui va etre en rapport avec notre systeme.

export CROSS="$HOME/hurd/cross-tool"
export HURD_DIR="$HOME/hurd/distro"

A des fin d'optimisation et de format binaire il nous faut definir le format binaire des executables de notre system HURD. Pour des raison de visibilite nous allons mettre a jours 2 variables. l'une correspondant a notre systeme actuelle, l'autre etant le system hurd resultant

export MY_HOST="i686-pc-linux-gnu"
export MY_TARGET="i686-pc-gnu"

Vous remarquez la difference ? :-)

Maintenant Nous allons mettre a jours certaines variables servant a la compilation. Ces variables permettent d'optimiser les executables resultants et donc cela permettra a votre systeme HURD d'executer les instructions CPU plus adapter a votre processeur. Le mieux est de se referer a la documentation de gcc pour voir ce que l'on peut mettre.

export CFLAGS="-O2 -pipe -march=i686"

BUGS

Etape 1

gcc

Comme le dit la documentation de gcc (le README), pour creer le cross-compilateur il est mieux d'utiliser un gcc de meme version

cd gcc.build
../gcc-x.x.x/configure --prefix=$CROSS --enable-languages=c make make install rm -rf * export PATH=$CROSS/bin:$PATH export LD_LIBRARY_PATH=$CROSS/lib cd..

La derniere ligne servant a prendre en compte ce nouveau compilateur plutot que celui de votre systeme linux actuelle.

cross-binutils

construisons maintenant les cross-linker et le cross assembleur

cd binutils.build
../binutils-X.X/configure --prefix=$CROSS --target=$MY_TARGET make make install rm -rf * cd ..

cross-gcc (#1)

essayons de compiler maintenant le cross-compilateur de gcc.

cd gcc.build
../gcc-X.X.X/configure --prefix=$CROSS --target=$MY_TARGET --with-gnu-as --with-gnu-ld --enable-languages=c make make -k make -k install cd ..

L'erreur de compilation viens d'un fichier header manquant. Ce fichier proviens de la glibc (qui n'est pas encore installe). Si une erreur autre que ca apparait alors soit vous avez fait une erreur dans la configuration, soit il y a une erreur dans gcc lui meme. changer de version de gcc peut parraitre judicieux dans ce cas (auquel cas il faut recommencer depuis le debut...). N'effacer pas le contenue de ce repertoire, on va encore en avoir besoin !

l'erreur doit ressembler a ca :

[...]
make[2]: *** [libgcc/./_muldi3.o] Error 1
make[2]: Leaving directory `/mnt/hurd/build/gcc.build/gcc'
make[1]: *** [libgcc.a] Error 2
[...]

Pas trop grave puisque cela affecte juste la compilation de la librairie statique libgcc.a. les binaires sont present !

Setup de la cross-compilation

Le repertoire $CROSS/$TARGET sera le repertoire de resultat de la cross-compilation. et donc cela sera notre systeme HURD !

GNUmach headers

Pour avoir ces headers manquant il nous faut d'abords installer quelques headers qui en dependent... les headers du GNUmach font partis de ceux la.

cd gnumach.build
CC=gcc ../gnumach/configure --build=$MY_HOST --host=$MY_TARGET make -k install-headers prefix=$CROSS/$MY_TARGET rm -rf * cd ..

Nous utilisons ici le gcc qui est actuellement fonctionnel (le cross-compileur n'etant pas encore totalement installer). D'ou l'utilisation de CC avec gcc (compilateur natif).

cross-mig

cd mig.build
../mig/configure --prefix=$CROSS --host=$MY_HOST --target=$MY_TARGET make make install rm -rf * cd ..

Il se peut qu'il faille re-creer le aclocal.m4 des sources, dans ce cas suivez les instructions et relancer make. Il ne devrait pas y avoir de soucis a ce niveau.

HURD headers

Nous installons maintenant les fichiers d'entetes de la partie hurd du 'noyau'. Ceci afin de pouvoir compiler en partie la GNUlibc. Celle-ci ayant besoin d'avoir des informations sur la partie noyau.

cd hurd.build
CC=gcc ../hurd/configure --build=$MY_HOST --host=$MY_TARGET --prefix= --disable-profile make install-headers no_deps=t prefix=$CROSS/$MY_TARGET rm -rf * cd ..

GNUlibc pour GNU/HURD (#1)

Passons enfin ala partie qui nous manque pour finir de pouvoir compiler le cross-compileur. La libc est le composant essentiel qui fait le lien entre l'utilisateur (le programmeur) et le system (dans notre cas hurd+gnumach).

cd glibc.build
## NOTE - added --without-tls since glibc TLS and gnumach seems got problems together (http://packages.debian.org/changelogs/pool/main/g/glibc/ , by searching hurd string)
../glibc-X.X.X/configure --without-cvs --prefix= --build=$MY_HOST --host=$MY_TARGET --disable-profile --with-headers=$CROSS/$MY_TARGET/include --without-tls make -k make -k install install_root=$CROSS/$MY_TARGET cd ..

La libc se compile mal car il manque le fichier manquand du cross-compiler. Apres avoir installer les elements compile ici, nous pouvons finir de construire le cross-compilateur.

cross-gcc (#2)

Nous pouvons maintenant finir de compiler le cross-compilateur, maintenant que nous avons les fichiers qu'il faut !

cd gcc.build
make touch $CROSS/$MY_TARGET/include/gnu/stubs.h make

Aie il y a encore une erreur, il manque encore un fichier :

ld: cannot find libcrt.a
collect2: ld returned 1 exit status
make[2]: *** [libgcc_s.so] Error 1
make[2]: Leaving directory `/mnt/hurd/build/gcc.build/gcc'
make[1]: *** [libgcc.a] Error 2

Ce fichier de la libc si vous regarder bien n'a pas ete installer precedement. hOr !, il y a une reference a ce fichier dans le fichier $CROSS/$TARGET/lib/libc.a. Il suffit d'editer ce fichier texte avec un editeur et d'enlever la reference a ce fichier (chez moi c'est libcrt.a).

On peux alors finir la compilation du cross-compiler correctement

make
make install

glibc pour GNU/HURD (#2)

cd glibc.build

A ce niveau si vous avez un probleme pour compiler la libc c'est que la version des binutils et/ou de gcc ne permet pas de compiler votre glibc (ce qui est facheux et est considerer comme un bug!) en cherchant bien l'erreur via google vous trouverez surement un petit patch pour resoudre le probleme de compilation. A moins de tous recommencer avec des versions differentes des outils de compilations.

make make install install_root=$CROSS/$MY_TARGET

Maintenant il faut editer le fichier $CROSS/$MY_TARGET/lib/libc.so et enlever la reference statique de recherche a /lib pour les fichiers qu'il y a dedans. Editer le fichier et enlever les '/lib/' tous simplement.

Il faut aussi rajouter un lien symbolique ld.so qui est utilise comme reference pour le loader par les serveurs hurd. Ce lien n'est pas fait lors de l'installation de la glibc.

cd $CROSS/$MY_TARGET/lib
ln -s ld-X.X.X.so ld.so

Le cross-compiler C est fini d'etre compiler. Les outils de compilations ainsi que la glibc sont construits pour le GNU/HURD !!!, Installons maintenant le micro-kernel gnumach ainsi que les serveurs du HURD.

Etape 2

copie des fichiers de bases de systeme

Les fichiers headers ainsi que les libraries sont les librairies qui vont etre directement utilisables par notre systeme. On en profite aussi pour faire le lien symbolique de /usr vers / (qui est une caracteristique du GNU/HURD), Ainsi que l'ajout de certains fichiers essentiels aux serveurs.

cd $HURD_DISTRO
cp -R $CROSS/$MY_TARGET/* . ### ### theses are $MY_HOST specifics ### rm -rf bin/ar bin/as bin/gcc bin/ld bin/nm bin/ranlib bin/strip lib/ldscripts/ ### ### hum ?!? really usefull ? (maybe for compatibility) ### ln -s . usr mkdir -p boot mkdir -p servers/socket mkdir -p share/misc mkdir -p var tmp root home touch servers/socket/1 touch servers/socket/2 ln -f servers/socket/1 servers/socket/local ln -f servers/socket/2 servers/socket/inet touch servers/exec

GNUmach micro-noyau

Les options ici du script configure peuvent etre differentes selon votre systeme. A vous de voir ce qu'il faut rajouter et/ou enlever...

cd gnumach.build
CC=$MY_TARGET-gcc ../gnumach/configure --build=$MY_HOST --host=$MY_TARGET --enable-floppy --enable-ide --enable-com make make install prefix=$HURD_DISTRO rm -rf * cd ..

HURD servers

Il se peut que vous ayez des problemes de compilatons sur le hurd. J'ai mis dans le repertoire differents patch trouver sur la mailling-list du hurd (hurd-bug) afin d'avoir une compilation correcte. Dans le cas ou la compilation de fait correctement c'est que le cvs a ete mis a jours avec ces patchs. Il faut donc que je mette a jours les fichiers sources du cvs :)

les patchs s'applique comme ceci :

cd hurd && patch -nP0 < ../le_patch_qui_conviens.patch

Apres cet intermede, continuons sur la construction..

cd hurd.build
CC=$MY_TARGET-gcc ../hurd/configure --build=$MY_HOST --host=$MY_TARGET --prefix= --disable-profile make make install prefix=$HURD_DISTRO cp ../hurd/release/SETUP $HURD_DISTRO/SETUP.sh rm -rf * cd ..

Un fichier important est a copier ala racine de notre distribution GNU/HURD, il est situe dans le repertoire 'release' des sources. c'est le fichier SETUP !. Ce script permet de configurer les 1ere choses a faire une fois la distribution en marche

Maintenant que nous avons correctement tous compiler il reste a voir ce qui va etre lancer au demarage. Une fois que GNUmach a reconnu les peripheriques qui dependent de la compilation qu'on a fait de lui. Il nous faut lancer les serveurs du hurd. Il existe 2 facons de le faire. Soit depuis grub soit depuis un fichier de configuration. Une fois les serveurs lancer le process 'init' peux etre lancer pour ne jamais finir (comme dans tout Unix qui se respecte).

avec un fichier de boot (obsolete, plus supporte, mais fonctionnelle)

Dans le fichier de configuration nous rajoutons :

#
# /boot/servers.boot file
#

#
# first launch the root filesystem (ext2fs for moment)
#
/hurd/ext2fs.static --bootflags=${boot-args} --host-priv-port=${host-port} --device-master-port=${device-port} --exec-server-task=${exec-task} -Tdevice ${root-device} $(task-create) $(task-resume)

#
# then launch the 'exec' server
#
/lib/ld.so.1 /hurd/exec $(exec-task=task-create)

#
# add the administrator defined linux swap area at startup
# (remove this after the creation of /dev entries)
#
# /dev/hd0s2 $(add-linux-paging-file)

die $(serverboot)

le fichier menu.lst du grub ressemblerai a ca :

title=GNU/HURD (my distro with serverboot file)
root (hd0,0)
kernel /boot/gnumach root=hd0s1 -s
module /boot/serverboot

depuis grub (si il est deja installer sur votre distribution)

Dans ce cas la pas besoin de fichier de lancement des serveurs hurd, car tous ce passe depuis grub... (/boot/grub/grub.conf)

title= GNU/HURD (my distro without serverboot file)
root (hd0,0)
kernel /boot/gnumach root=device:hd0s1 -s
module /hurd/ext2fs.static --multiboot-command-line=${kernel-command-line} --host-priv-port=${host-port} --device-master-port=${device-port} --exec-server-task=${exec-task} -T typed ${root} $(task-create) $(task-resume)
module /lib/ld.so /hurd/exec $(exec-task=task-create)

Attention a bien verifier que tous les fichiers sont present, sinon vous n'arriverez pas a booter correctement !

bash pour GNU/HURD (ca marche avec un 'tit patch)

cd bash.build
CC=$MY_TARGET-gcc ../bash-X.X/configure --build=$MY_HOST --host=$MY_TARGET --prefix= make make install prefix=$HURD_DISTRO rm -rf * cd ..

un petit patch est a appliquer car la compilation se fait mal sur un des fichier : il faut rajouter la macro en debut de fichier
#define SYMLOOP_MAX 8
dans le fichier lib/sh/pathphys.c . Cette valeur est trouver en faisant un 'grep -R SYMLOOP_MAX *' dans le repertoire 'hurd-distro/include'

Notons que nous touchons directement au specfiter du hurd qui ne definie normalement pas de limites pour quoi que ce soit. et ici nous en mettons une

cd $HURD_DISTRO/bin
ln -s bash sh

coreutils pour GNU/HURD

Ce package est un des elements essentiels a tous systeme GNU/unix. Il permet en effet d'avoir certains utilitaires indispensables comme le 'ls' ou le 'cd'. Il vaux mieux l'installer pour rendre le systeme utilisable pour l'utilisateur ;-) C'est le complement indispensable a tous shell.

cd coreutils.build
CC=$MY_TARGET-gcc ../coreutils-x.x.x/configure --build=$MY_HOST --host=$MY_TARGET --prefix= make make install prefix=$HURD_DISTRO rm -rf * cd ..

(un editeur de texte a compiler ici ?)

TODO

setup du hostname

On ecris dans le fichier /etc/hostname le nom de notre machine :

echo <my hostname> > ~/hurd/hurd-distro/etc/hostname

setup de la glibc

cat > $HURD_DISTRO/etc/nsswitch.conf << "EOF"
# Begin /etc/nsswitch.conf passwd: files group: files shadow: files hosts: files dns networks: files protocols: files services: files ethers: files rpc: files netgroup: nis # End /etc/nsswitch.conf EOF

setup de l'heure locale

Pas de quoi se prendre la tete de ce cote la un simple example a adapter a vos besoins

BUG ! hum ca a l'air de n''avoir pas installer les zoneinfo avec la glibc-2.3.5... a voir..

example :
cp /share/zoneinfo/US/Eastern /etc/localtime

setup des partitions

Maintenant il faut creer le fichier '/etc/fstab' c'est lui qui contient ce qui doit etre activer au demarage :

cat > $HURD_DISTRO/etc/fstab << "EOF"
# <file system> <mount point>   <type>  <options>  <dump>  <pass>
/dev/hd0s1      /               ext2    rw         0       1
/dev/hd0s2      /home           ext2    rw         0       2
/dev/hd0s3      none            swap    sw         0       0

EOF

setup des mots de pass

creer le fichier /etc/passwd avec la commande suivante :

cat > $HURD_DISTRO/etc/passwd << "EOF"
root:x:0:0:root:/root:bin/bash
EOF

setup du fichier group

creer le fichier /etc/group avec la commande suivante :

cat > $HURD_DISTRO/etc/group << "EOF"
root::0:root
bin::1:root,bin,daemon
daemon::2:root,bin,daemon
sys::3:root,bin,adm
adm::4:root,adm,daemon
tty::5:
disk::6:root,adm
lp::7:lp
mem::8:
kmem::9:
wheel::10:root
floppy::11:root
mail::12:mail
news::13:news
uucp::14:uucp
man::15:man
cron::16:cron
console::17:
audio::18:
cdrom::19:
dialout::20:root
ftp::21:
sshd::22:
at::25:at
tape::26:root
video::27:root
squid::31:squid
gdm::32:gdm
xfs::33:xfs
games::35:
named::40:named
mysql:x:60:
postgres::70:
cdrw::80:
nut::84:
usb::85:
vpopmail:x:89:
users::100:games
nofiles:x:200:
qmail:x:201:
postfix:x:207:
postdrop:x:208:
smmsp:x:209:smmsp
slocate::245:
portage::250:portage
utmp:x:406:
nogroup::65533:
nobody::65534:

EOF

setup du clavier

TODO

setup du fichiers hosts

On remplis ici la resolution des noms des machines connus

cat > $HURD_DISTRO/etc/hosts << "EOF"
127.0.0.1 localhost $hostname$

EOF

grub pour GNU/HURD (pour booter notre distro)

Comprendre le vocabulaire de GRUB

Pour bien comprendre GRUB, le plus important est de se familiariser avec la manière qu'a GRUB de désigner les disques durs et les partitions. Votre partition Linux /dev/hda1 s'appelle (hd0,0)dans GRUB. Notez les parenthèses nécessaires autour de hd0,0.

GRUB compte les disques durs à partir de zéro plutôt que "a" et les partitions à partir de zéro au lieu de un. Remarquez aussi que GRUB ne compte que les disques durs et ignore les périphériques tels que les lecteurs ou graveurs de CD-ROM. Les mêmes principes s'appliquent aux disques SCSI. Ces derniers reçoivent en général des numéros supérieurs à ceux des disques IDE, sauf quand le BIOS est configuré pour démarrer sur les disques SCSI.)

En supposant que vous ayez un disque dur /dev/hda, un lecteur de CDROM /dev/hdb, un graveur de CDROM /dev/hdc, un second disque dur /dev/hdd et aucun disque SCSI, /dev/hdd7s'écrit (hd1,6) dans GRUB. Cela peut sembler compliqué, et ça l'est, mais, comme vous le verrez, GRUB offre un système d'aide à la saisie bien pratique si vous avez de nombreux disques durs avec beaucoup de partitions.

Après cette courte introduction, il est temps d'installer GRUB.

cd grub.build
CC=$MY_TARGET ../grub-X.X/configure --build=$MY_HOST --host=$MY_TARGET --prefix=$HURD_DISTRO make make install rm -rf * cd ..

jusqu'au boot..

A partir de la mieux vaux noter sur un papier ce qui va suivre tant que vous ne pouvez pas lire cette documentation :)

setup du hurd en mode resteint

La premiere chose a faire est de lancer le script SETUP qui se trouve dans le repertoire 'release' des sources du hurd que nous avons copier precedement ala racine de notre distribution, il faut juste lancer la commande :

/bin/sh /SETUP

setup des fichiers peripheriques pour les partitions des disques durs

#sh-0.3> cd /dev
#sh-0.3> ./MAKEDEV hd0s1 hd0s2 hd0s3

Decouverte de hurd...

Vous pouvez rebooter votre machine et enlever l'option '-s' au lancement du micro-noyau dans grub. Vous etes en mode multi-utilisateur et vous pouvez maintenant utiliser et configurer votre systeme comme il vous plait !

Etape 3

TODO

Etape 4

TODO