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.
Avant de pouvoir compiler quoi que ce soit, pour obtenir notre distribution GNU/HURD il nous faut 2-3 petites choses :
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
Creer les fichiers interdependants que sont le compilateur, la libc et les entetes du 'noyau' (dans notre cas GNUmach+HURD)
A ce niveau nous aurons donc la GNUlibc d'installer pour notre systeme HURD
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).
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 !
Bienvenue dans le monde du HURD.
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"
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.
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 ..
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 !
Le repertoire $CROSS/$TARGET sera le repertoire de resultat de la cross-compilation. et donc cela sera notre systeme HURD !
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).
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.
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 ..
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.
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
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.
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
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 ..
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).
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
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 !
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
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 ..
TODO
On ecris dans le fichier /etc/hostname le nom de notre machine :
echo <my hostname> > ~/hurd/hurd-distro/etc/hostname
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
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
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
creer le fichier /etc/passwd avec la commande suivante :
cat > $HURD_DISTRO/etc/passwd << "EOF" root:x:0:0:root:/root:bin/bash EOF
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
TODO
On remplis ici la resolution des noms des machines connus
cat > $HURD_DISTRO/etc/hosts << "EOF" 127.0.0.1 localhost $hostname$ EOF
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 ..
A partir de la mieux vaux noter sur un papier ce qui va suivre tant que vous ne pouvez pas lire cette documentation :)
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
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 !
TODO
TODO