<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Linux Attitude&#187; Noyau</title>
	<atom:link href="http://linux-attitude.fr/tag/noyau/feed" rel="self" type="application/rss+xml" />
	<link>http://linux-attitude.fr</link>
	<description>Le libre est un état d&#039;esprit</description>
	<lastBuildDate>Mon, 06 Feb 2012 08:01:04 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>Alsa</title>
		<link>http://linux-attitude.fr/post/alsa?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=alsa</link>
		<comments>http://linux-attitude.fr/post/alsa#comments</comments>
		<pubDate>Thu, 21 Apr 2011 16:30:24 +0000</pubDate>
		<dc:creator>peck</dc:creator>
				<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Noyau]]></category>
		<category><![CDATA[planete-libre]]></category>
		<category><![CDATA[son]]></category>

		<guid isPermaLink="false">http://linux-attitude.fr/?p=1327</guid>
		<description><![CDATA[Niveau&#160;: &#160;&#160;&#160;&#160;&#160; Résumé&#160;: Aujourd'hui un truc obscur pour beaucoup d'entre nous&#160;: alsa. Pas la poudre blanche, mais le truc avec un mixer, enfin pas celui de la cuisine, mais celui de linux ... Pour simplifier disons que alsa est une API présentée par le noyau et qui permet d'accéder à travers une interface unique à [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Niveau</strong>&nbsp;: <span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="e">&nbsp;</span><br />
<strong>Résumé</strong>&nbsp;:</p>


<p>Aujourd'hui un truc obscur pour beaucoup d'entre nous&nbsp;: alsa. Pas la poudre blanche, mais le truc avec un mixer, enfin pas celui de la cuisine, mais celui de linux ...</p>


<p>Pour simplifier disons que alsa est une API présentée par le noyau et qui permet d'accéder à travers une interface unique à toutes les cartes son que vous pouvez avoir.</p>


<h3>Fichier de configuration</h3>

<p>Alsa étant relativement bien fait, ses utilisateurs (l'application qui émet du son, la gestion du volume ...) n'ont pas besoin de configuration particulière pour fonctionner. Mais il est possible de changer cette non configuration. Cela peut se faire soit de façon globale au système dans /etc/asound.conf soit spécifiquement à l'utilisateur dans ~/.asoundrc.</p>


<p>Que peut-on mettre dans ces fichiers&nbsp;?</p>


<p>Là ça devient vite obscur et peu documenté. Mais nous allons voir que c'est assez simple. Il s'agit d'une configuration hiérarchique. Vous avez le choix entre les 2 formats suivants pour écrire des valeurs (ou un mix des 2)&nbsp;:</p>
<pre>
# commentaire
val.eur.1 &quot;toto&quot;
val.eur.2 &quot;tata&quot;
val.ue &quot;help&quot;

val {
  eur {
   1 &quot;toto&quot;
   2 &quot;tata&quot;
  }
  ue &quot;help&quot;
}
</pre>


<h3>Éléments de configuration</h3>

<p>Mais que peut-on bien mettre dans ce fichier&nbsp;?</p>


<p>Ici les exemples sont nombreux, mais rarement expliqués.</p>


<p>Tout d'abord une liste détaillée se trouve ici&nbsp;: <a href="http://alsa.opensrc.org/Asoundrc.txt" hreflang="en">Asoundrc.txt</a></p>


<p>Reste à trouver ce que les attributs veulent dire. Ce qui va vous intéresser est essentiellement pcm qui permet de créer une nouvelle carte son (virtuelle). Les autres ne vous seront utiles que rarement et dépendront surtout du contenu de vos pcm.</p>


<p><span id="more-1327"></span></p>


<h3>Un pcm</h3>

<p>La première chose à déclarer dans un pcm est son type, vous avez le choix parmi les différents <a href="http://alsa.opensrc.org/ALSA_plugins" hreflang="en">plugins alsa</a>. Contemplez la densité de la documentation, heureusement vous en avez un peu plus ici&nbsp;: <a href="http://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html" hreflang="en">pcm_plugins.html</a></p>


<p>Notez la présence de ladspa pour changer le pitch du son. J'ai déjà présenté <a href="http://linux-attitude.fr/post/changer-la-vitesse-de-lecture-dun-film-sans-deformer-le-son">son usage avec vlc</a> pour accélérer un son sans en changer la hauteur.</p>


<p>Chaque type a ses paramètres spécifiques. Tous les plugins qui ne font que traiter le signal (comme ladspa ou softvol) ont un paramètre slave. Il faut bien comprendre de que cela signifie. Un slave est un autre plugin (oui c'est sans fin :-) qui va recevoir le son depuis le plugin que l'on configure. Donc le son transite de master vers slave lors de la lecture mais il transite de slave vers master lors de l'enregistrement.</p>


<h3>Exemple</h3>


<p>Maintenant prenons un exemple utile, ajouter une <strong>pré-amplification</strong> logicielle au système. Pratique lorsqu'on a un portable et qu'aucun ampli externe ne nous permet de monter le son alors que c'est l'enregistrement de youtube qui est très faible.</p>


<p>Comment faire&nbsp;? Très simple, ajoutons une carte virtuelle de type <a href="http://alsa.opensrc.org/Softvol et ici  http://www.alsa-project.org/alsa-doc/alsa-lib/pcm_plugins.html#pcm_plugins_softvol" hreflang="en">softvol</a></p>
<pre>
pcm.softcard {
      type softvol
      slave.pcm &quot;default&quot;
# on associe un contrôle nommé pre-amp au mixage de la première carte son
      control.name &quot;Pre-Amp&quot;
      control.card 0 
}
</pre>


<p>C'est bien, mais cela veut dire qu'il faut indiquer à nos logiciels d'utiliser la carte softcard pour profiter de cet avantage. Quelques changements vont nous permettre de changer ceci pour tout le monde.</p>
<pre>
# on change la configuration du pcm par défaut
pcm.!default {
      type plug
# et on pointe bêtement vers la notre
      slave.pcm &quot;softcard&quot;
}

pcm.softcard {
      type softvol
# on laisse dmix choisir la bonne carte physique
      slave.pcm &quot;dmix&quot;
      control.name &quot;Pre-Amp&quot;
      control.card 0
# on en profite pour donner des limites plus sympa pour l'augmentation et la rédution du volume
      min_dB -5.0
      max_dB 20.0
      resolution 5
}
</pre>


<p>Avant de voir le contrôle, il faut lancer un premier test pour forcer la lecture du fichier de conf par alsa (c'est comme ça ...)&nbsp;:</p>
<pre>
# test de bruit presque blanc
$ speaker-test
</pre>


<p>Et maintenant nous avons un nouveau contrôle dans alsamixer (ou votre mixer préféré) permettant de régler la pré-amplification.</p>


<p>A vous de tester les autres plugins ...</p>

<p></p><p>Si vous avez aimé, il y a aussi : </p><ol><li><a href='http://linux-attitude.fr/post/mpd-music-player-daemon' rel='bookmark' title='Permanent Link: MPD (Music Player Daemon)'>MPD (Music Player Daemon)</a></li>
</ol>
	Tags:<a href="http://linux-attitude.fr/tag/noyau" title="Noyau" rel="tag">Noyau</a>, <a href="http://linux-attitude.fr/tag/planete-libre" title="planete-libre" rel="tag">planete-libre</a>, <a href="http://linux-attitude.fr/tag/son" title="son" rel="tag">son</a><br />
]]></content:encoded>
			<wfw:commentRss>http://linux-attitude.fr/post/alsa/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Exécution capitale</title>
		<link>http://linux-attitude.fr/post/execution-capitale?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=execution-capitale</link>
		<comments>http://linux-attitude.fr/post/execution-capitale#comments</comments>
		<pubDate>Mon, 28 Mar 2011 16:52:02 +0000</pubDate>
		<dc:creator>peck</dc:creator>
				<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Commande]]></category>
		<category><![CDATA[Curiosité]]></category>
		<category><![CDATA[Noyau]]></category>
		<category><![CDATA[planete-libre]]></category>
		<category><![CDATA[Système]]></category>

		<guid isPermaLink="false">http://linux-attitude.fr/?p=1314</guid>
		<description><![CDATA[Niveau&#160;: &#160;&#160;&#160;&#160;&#160; Résumé&#160;: /proc/sys/fs/binfmt_misc/register Exécution Savez-vous qu'on peut rendre n'importe quel fichier exécutable sous linux&#160;? Bien sûr il suffit de faire un chmod +x, mais le noyau risque de vous envoyer balader si le fichier n'est pas réellement exécutable. Mais je parle ici de rendre exécutable n'importe quel fichier, un jar, un source en C, [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Niveau</strong>&nbsp;: <span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="e">&nbsp;</span><span class="e">&nbsp;</span><br />
<strong>Résumé</strong>&nbsp;: /proc/sys/fs/binfmt_misc/register</p>



<h3>Exécution</h3>


<p>Savez-vous qu'on peut rendre n'importe quel fichier exécutable sous linux&nbsp;? Bien sûr il suffit de faire un chmod +x, mais le noyau risque de vous envoyer balader si le fichier n'est pas réellement exécutable.</p>


<p>Mais je parle ici de rendre exécutable n'importe quel fichier, un jar, un source en C, un MP3 ...</p>


<p>Mais comment quoi que donc !?</p>


<p>Pour exécuter un fichier, le noyau lit les premiers octets du fichier et vérifie qu'ils correspondent à un format binaire (binfmt) connu.
Il existe un système pour ajouter des formats binaires à ceux déjà supportés dans le noyau (en gros les <a href="http://en.wikipedia.org/wiki/Executable_and_Linkable_Format" hreflang="en">elf</a> et les scripts). Il s'agit du format misc.</p>


<p>Pour savoir si ce format est supporté chez vous, ce qui est très probable, lancez la commande&nbsp;:</p>
<pre>
$ cat /proc/sys/fs/binfmt_misc/status
</pre>


<p>S'il n'est pas supporté, il faut charger le module et monter le répertoire&nbsp;:</p>
<pre>
$ modprobe binfmt_misc
$ mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc 
</pre>


<p><span id="more-1314"></span></p>


<h3>C capital</h3>


<p>Maintenant supposons vous vouliez rendre les fichiers .c exécutables. Vous pouvez soit utiliser un de mes <a href="http://linux-attitude.fr/post/usrbingcc-bis">anciens</a> <a href="http://linux-attitude.fr/post/ecrire-un-script-en-c">articles</a> ... soit créer un petit script qui sera appelé à chaque exécution d'un .c&nbsp;:</p>
<pre>
#!/bin/sh
# /usr/local/bin/ccexec
gcc -Wall -o /tmp/cscript.$$ &quot;$1&quot; &amp;&amp; shift &amp;&amp; /tmp/cscript.$$ &quot;$@&quot;
ret=$? ; rm -f /tmp/cscript.$$ ; exit $ret
</pre>


<p>Et de faire en sorte qu'il soit réellement appelé&nbsp;:</p>
<pre>
$ echo ':cfile:E::c::/usr/local/bin/ccexec:' &gt; /proc/sys/fs/binfmt_misc/register
</pre>


<p>Hop un test&nbsp;:</p>
<pre>
#include &lt;stdio.h&gt;
// test.c
int main() {
  printf(&quot;Coucou\n&quot;);
  return 0;
}
</pre>


<p>Et on lance&nbsp;:</p>
<pre>
$ chmod +x test.c
$ ./test.c
&gt; Coucou
</pre>


<p>Yeah !!!</p>


<h3>G tout compris</h3>

<p>Maintenant, passons à l'exécution d'un gzip. Plutôt que de reconnaître le fichier à son extension, ce qui est franchement faible comme méthode nous allons vraiment détecter le type de fichier.</p>


<p>Allons voir la spécification, un fichier gzip se reconnait à ses 2 premiers octets qui doivent valoir 0x1f et 0x8b&nbsp;:</p>
<pre>
$ echo ':gzip:M::\x1f\x8b::/bin/gunzip:' &gt; /proc/sys/fs/binfmt_misc/register
</pre>


<p>Même méthode et ça marche. Notez qu'il est possible d'utiliser n'importe quel champs de bits grâce à une masque et une position de départ, mais seulement dans les 128 premiers octets du fichier.</p>


<p>Enfin, certaines distributions vont vous installer des choses un peu plus utiles comme l'exécution des jar avec java ou celle d'exécutable windows avec wine.</p>


<p>Et pour une spécification plus détaillée de ce qu'il lest possible de mettre dans la ligne d'enregistrement, direction <a href="http://git.kernel.org/gitweb.cgi?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=Documentation/binfmt_misc.txt;hb=HEAD" hreflang="en">la documentation</a></p>


<p><strong>PS</strong>&nbsp;: pour supprimer l'entrée&nbsp;: echo -1 &gt; /proc/sys/fs/binfmt_misc/cfile</p>

<p></p><p>Si vous avez aimé, il y a aussi : </p><ol><li><a href='http://linux-attitude.fr/post/usrbingcc-bis' rel='bookmark' title='Permanent Link: #!/usr/bin/gcc (bis)'>#!/usr/bin/gcc (bis)</a></li>
<li><a href='http://linux-attitude.fr/post/changer-la-priorite-d-execution-des-processus' rel='bookmark' title='Permanent Link: Changer la priorité d&#8217;exécution des processus'>Changer la priorité d&#8217;exécution des processus</a></li>
<li><a href='http://linux-attitude.fr/post/trucs-et-astuces-5' rel='bookmark' title='Permanent Link: Trucs et astuces (5)'>Trucs et astuces (5)</a></li>
</ol>
	Tags:<a href="http://linux-attitude.fr/tag/commande" title="Commande" rel="tag">Commande</a>, <a href="http://linux-attitude.fr/tag/curiosite" title="Curiosité" rel="tag">Curiosité</a>, <a href="http://linux-attitude.fr/tag/noyau" title="Noyau" rel="tag">Noyau</a>, <a href="http://linux-attitude.fr/tag/planete-libre" title="planete-libre" rel="tag">planete-libre</a>, <a href="http://linux-attitude.fr/tag/systeme" title="Système" rel="tag">Système</a><br />
]]></content:encoded>
			<wfw:commentRss>http://linux-attitude.fr/post/execution-capitale/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Le retour de la vengeance de la bidouille</title>
		<link>http://linux-attitude.fr/post/le-retour-de-la-vengeance-de-la-bidouille?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=le-retour-de-la-vengeance-de-la-bidouille</link>
		<comments>http://linux-attitude.fr/post/le-retour-de-la-vengeance-de-la-bidouille#comments</comments>
		<pubDate>Wed, 05 Nov 2008 18:28:00 +0000</pubDate>
		<dc:creator>peck</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[C]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Noyau]]></category>
		<category><![CDATA[planet-libre]]></category>

		<guid isPermaLink="false">http://linux-attitude.fr/post/le-retour-de-la-vengeance-de-la-bidouille</guid>
		<description><![CDATA[Niveau&#160;: &#160;&#160;&#160;&#160;&#160; Résumé&#160;: grub&#160;; noyau&#160;; multiboot&#160;; mandelbrot Suite à de précédentes bidouilles, on veut faire mieux. Multiboot Donc grub peut booter plusieurs formats, l'un d'entre eux est le multiboot, un format de fichier bootable défini par les développeurs de grub espérant qu'il soit adopté par différentes distributions. Il souffre d'un certain nombre de faiblesses et [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Niveau</strong>&nbsp;: <span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="e">&nbsp;</span><br />
<strong>Résumé</strong>&nbsp;: grub&nbsp;; noyau&nbsp;; multiboot&nbsp;; mandelbrot</p>


<p>Suite à de précédentes <a href="http://linux-attitude.fr/post/Le-retour-de-la-bidouille">bidouilles</a>, on veut faire mieux.</p>


<h3>Multiboot</h3>

<p>Donc grub peut booter plusieurs formats, l'un d'entre eux est le multiboot, un format de fichier bootable défini par les développeurs de grub espérant qu'il soit adopté par différentes distributions. Il souffre d'un certain nombre de faiblesses et n'est pas encore vraiment un standard. D'autant que grub lui-même ne supporte pas encore complètement la <a href="http://www.gnu.org/software/grub/manual/multiboot/multiboot.html" hreflang="en">spécification</a> pourtant très courte. Si vous ne voulez pas lire toute la spécification, allez directement au chapitre 4 où on trouve un code d'exemple prêt à compiler pour vous lancer dans le développement.</p>


<p>Vous trouverez un autre exemple chez quelqu'un qui s'est amusé à coder un <a href="http://www.erikyyy.de/invaders/" hreflang="en">space invaders</a> bootable directement à partir de la spécification multiboot.</p>


<p>Alors c'est parti, reprenons notre projet précédent.
Faites attention, le processeur est dans un état particulier lorsqu'on vous laisse la main (lisez le chapitre 3.2), à vous de vous en accommoder.</p>



<h3>Mode graphique</h3>

<p>Tout d'abord on voudrait changer le mode graphique, et si possible pour mieux que la première fois. Pour cela, on va utiliser le standard <a href="http://en.wikipedia.org/wiki/VESA_BIOS_Extensions" hreflang="en">vesa 2.0</a> qui standardise des modes avec une plus grande définition et qui ajoute de nouvelles fonctions au bios pour manipuler la carte.</p>


<p>Choisissons le mode 0x118 (1024x768x24) avec 16 millions de couleurs. Plus besoin de gérer un palette puisqu'on écrit directement les couleurs RGB à utiliser pour le pixel. On aura tout de même une fonction de palette puisqu'on n'utilise qu'un petit nombre de couleurs placées sur une échelle.</p>


<p>Le problème c'est que vesa n'a pas prévu qu'on puisse appeler les fonctions de la carte en mode protégé sans passer au moins une fois par une interruption en mode réel. Multiboot est bien gentil, il a prévu le cas, malheureusement, grub n'implémente pas les fonctions qu'il devrait pour le faire pour nous. Un <a href="http://www.smk.co.za/software/vbe-grub/" hreflang="en">patch</a> est disponible pour ceux qui voudrait quand même cette fonctionnalité.</p>


<p><span id="more-23"></span></p>


<p>Il nous faudra donc faire nous-même ces interruptions. Pour survivre au mode réel nous devrons être sous le premier Mo de RAM, or grub nous place juste au dessus (en 0x100000). Notre premier bout de code aura donc pour but de nous déplacer en dessous. Pour cela on commence par prendre l'en-tête multiboot (beaucoup plus simple que pour les zImage) et on écrit le code pour se déplacer en 0x1000 (choix arbitraire)&nbsp;:</p>
<pre>
        /* on se copie ailleurs */
        mov     $KERNEL_SIZE,%ecx /* en octets */
        mov     $KERNEL_ORIG,%esi /* source juste après ce secteur */
        mov     $KERNEL_DEST,%edi /* destination sous les 1Mo */
        rep movsw

        /* et on va dans notre nouveau noyau */
        ljmp    $0x8,$KERNEL_DEST
</pre>


<p>Bien, maintenant, il faut passer du mode protégé au mode réel et inversement pour pouvoir faire des interruptions. Choisissons comme toujours de ne pas réinventer la roue et repiquons le code de grub qui dispose déjà de ces fonctions en assembleur. Elles s'appellent real_to_prot et prot_to_real. Pour ceux qui voudraient comprendre comment faire, c'est <a href="http://www.sudleyplace.com/pmtorm.html" hreflang="en">partout</a> sur le net. Comme le <a href="http://www.internals.com/articles/protmode/protmode.htm" hreflang="en">mode protégé</a> a besoin de descripteurs de segment, on n'oublie pas de les définir aussi (lire la fin du fichier asm.S) .</p>


<p>Du coup on peut utiliser 2 fonctions vesa bien utiles dans notre code, set_mode pour mettre en place notre mode graphique, et get_modeinfo pour savoir comment l'utiliser. En effet, on voudrait, comme avant pouvoir accéder directement à la mémoire vidéo pour y mettre nos pixels. La fonction get_modeinfo est là pour ça, elle utilise la fonction <a href="http://www.ctyme.com/intr/rb-0274.htm" hreflang="en">0x4F01</a> du bios. On lui passe une adresse dans laquelle elle va écrire une structure de données nous informant sur le mode choisi. On choisit l'adresse de cette structure au pif puisqu'on n'a pas de gestion de la mémoire et qu'on a toute la ram pour nous. On prend 8000:0000.</p>


<p>La structure renvoyée contient l'adresse du mapping de la mémoire vidéo en 28h, ainsi que ses dimensions. Cela nos permettrait de changer le mode dans notre code facilement (notez les conversions de type pour lire le bon nombre d'octets)&nbsp;:</p>
<pre>
        /* on récupère les infos sur le mode qui nous intéresse */
        get_modeinfo(0x118);
        /* conversion de l'adresse du format [segment:offset] au format à plat */
        data = (MODEINFO_SEG &lt;&lt; 4)+MODEINFO_OFF;
        /* on joue sur les converstions pour la lecture du bon nombre d'octets en ram */
        video = (unsigned char*) *(unsigned int*)(data + 0x28);
        width = (int) *(unsigned short*)(data + 0x12);
        height = (int) *(unsigned short*)(data + 0x14);
</pre>



<h3>Code</h3>


<p>On repart du code de l'article précédent. On y apporte quelques modifications techniques liées au changement de mode. Par exemple l'écriture d'un pixel se résume à l'écriture des 3 couleurs au bon endroit en ram&nbsp;:</p>
<pre>
        int pos = bpp*(x + y*width);
        /* et on ecrit directement en mémoire vidéo */
        video[pos] = r;
        video[pos+1] = g;
        video[pos+2] = b;
</pre>


<p>Pour ceux qui veulent aller plus loin dans la compréhension du mode protégé, ça aurait pu aussi être l'occasion de mettre en place un segment séparé pour écrire en mémoire vidéo avec la commande <a href="http://www.jamesmolloy.co.uk/tutorial_html/4.-The%20GDT%20and%20IDT.html" hreflang="en">lgdt</a>.</p>


<p>On peut imaginer y ajouter des tâches, par exemple une sorte de thread pour gérer le clavier. Mais la ça commence à devenir complexe et il vaudrait mieux lire des OS existants pour bien comprendre tout ça. Par exemple il existe <a href="http://www.minix3.org/" hreflang="en">minix</a> qui a été fait dans un but pédagogique.</p>


<h3>Compilation</h3>

<p>Une autre chose change, c'est la compilation. Puisque le format multiboot est plus simple, nous n'avons plus besoin du script setup.ld. Par contre, puisque notre binaire contient deux morceaux (souvenez vous de la copie sous les 1Mo en début d'article), on devra modifier notre compilation.</p>


<p>Ce qui se résume en 2 partie, une pour le code de copie fait pour tourner en 0x100000&nbsp;:</p>
<pre>
LDFLAGS1=&quot;-nostdlib -Wl,-N -Wl,-Ttext -Wl,100000 -m32&quot;
gcc $LDFLAGS1 -o boot.exec boot.o
objcopy -O binary boot.exec boot
</pre>


<p>Et une partie contenant tout le reste du code, qu'on va placer en 0x1000&nbsp;:</p>
<pre>
LDFLAGS2=&quot;-nostdlib -Wl,-N -Wl,-Ttext -Wl,1000 -m32&quot;
gcc $LDFLAGS2 -o kernel.exec start.o asm.o kernel.o debug.o
objcopy -O binary kernel.exec kernel
</pre>


<p>Et enfin une dernière copie qui va concaténer les 2 binaires&nbsp;:</p>
<pre>
# on force la taille pour éviter les problèmes avec le bootloader
dd if=/dev/zero of=mandel2 bs=256 count=32 2&gt;/dev/null 
# la premiere partie
dd if=boot bs=256 count=1 of=mandel2 conv=notrunc 2&gt;/dev/null
# la 2e partie a une position fixée dans le code de la première (boot.S + header.h)
dd if=kernel bs=256 seek=1 of=mandel2 conv=notrunc 2&gt;/dev/null
</pre>


<h3>Run</h3>


<p>Encore une fois, il suffit de préciser le fichier à grub pour qu'il le boote&nbsp;:</p>
<pre>
kernel         (hd0,0)/boot/mandel
</pre>


<p>Vous trouverez les sources en pièce jointe de cet article, et en complément une image disque contenant les 2 projets avec un grub installé qui fonctionne directement sur <a href="http://bellard.org/qemu/" hreflang="en">qemu</a>.</p>
<pre>
$ qemu image.dd
</pre>


<p>Bravo à vous&nbsp;!</p>


<p><img src="http://linux-attitude.fr/public/Schemas/mandel2.png" alt="mandel2.png" style="display:block; margin:0 auto;" title="mandel2.png, oct 2008" /></p>


<p><strong>PJ</strong>&nbsp;:</p>
<ul>
<li><a href="http://linux-attitude.fr/public/Code/mandel2/asm.S">asm.S</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel2/boot.S">boot.S</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel2/compile.sh">compile.sh</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel2/debug.c">debug.c</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel2/header.h">header.h</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel2/kernel.c">kernel.c</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel2/start.S">start.S</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel.dd">mandel.dd</a></li>
</ul>

<p></p><p>Si vous avez aimé, il y a aussi : </p><ol><li><a href='http://linux-attitude.fr/post/le-retour-de-la-bidouille' rel='bookmark' title='Permanent Link: Le retour de la bidouille'>Le retour de la bidouille</a></li>
<li><a href='http://linux-attitude.fr/post/en-vrac-25' rel='bookmark' title='Permanent Link: En vrac (25)'>En vrac (25)</a></li>
<li><a href='http://linux-attitude.fr/post/en-vrac-18' rel='bookmark' title='Permanent Link: En vrac (18)'>En vrac (18)</a></li>
</ol>
	Tags:<a href="http://linux-attitude.fr/tag/c" title="C" rel="tag">C</a>, <a href="http://linux-attitude.fr/tag/code" title="Code" rel="tag">Code</a>, <a href="http://linux-attitude.fr/tag/noyau" title="Noyau" rel="tag">Noyau</a>, <a href="http://linux-attitude.fr/tag/planet-libre" title="planet-libre" rel="tag">planet-libre</a><br />
]]></content:encoded>
			<wfw:commentRss>http://linux-attitude.fr/post/le-retour-de-la-vengeance-de-la-bidouille/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Le retour de la bidouille</title>
		<link>http://linux-attitude.fr/post/le-retour-de-la-bidouille?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=le-retour-de-la-bidouille</link>
		<comments>http://linux-attitude.fr/post/le-retour-de-la-bidouille#comments</comments>
		<pubDate>Mon, 03 Nov 2008 18:51:00 +0000</pubDate>
		<dc:creator>peck</dc:creator>
				<category><![CDATA[Développement]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Noyau]]></category>
		<category><![CDATA[planet-libre]]></category>

		<guid isPermaLink="false">http://linux-attitude.fr/post/le-retour-de-la-bidouille</guid>
		<description><![CDATA[Niveau&#160;: &#160;&#160;&#160;&#160;&#160; Résumé&#160;: grub&#160;; noyau&#160;; mandelbrot Vous souvenez-vous du bon vieux temps&#160;? Je vous parle du temps de l'autoexec.bat et des driver de quelques ko, le temps où on écrivait directement en mémoire vidéo, le temps de l'assembleur, du mode réel et des interruptions. Hé bien cette époque bien que révolue nous a laissé des [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Niveau</strong>&nbsp;: <span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="e">&nbsp;</span><br />
<strong>Résumé</strong>&nbsp;: grub&nbsp;; noyau&nbsp;; mandelbrot</p>


<p>Vous souvenez-vous du bon vieux temps&nbsp;? Je vous parle du temps de l'autoexec.bat et des driver de quelques ko, le temps où on écrivait directement en mémoire vidéo, le temps de l'assembleur, du mode réel et des interruptions.</p>


<p>Hé bien cette époque bien que révolue nous a laissé des traces. Il est toujours possible de coder sans noyau, de faire son propre noyau, de se passer de système d'exploitation ou de booter directement sur une application en quelques secondes.</p>


<h3>Boot loader</h3>


<p>Choisissons un bootloader, <a href="http://linux-attitude.fr/post/Chargeeeez">grub</a> par exemple, nous allons lui demander de lancer notre programme. Avec grub il existe plusieurs méthodes pour charger un os, entre autres&nbsp;:</p>

<ul>
<li><strong>Chainloader</strong> charge 512 octets, met le processeur en mode en mode réel, tel qu'il serait après le passage du bios. Pratique pour partir de zéro, mais 512 octet c'est un peu petit et nous n'avons pas vraiment envie de gérer le chargement de fichier sur le disque en plus.</li>
</ul>
<ul>
<li><strong>Linux</strong> charge un noyau au format zimage ou bzimage et lui passe le contrôle en mode réel 16 bits. Il est possible de charger des fichiers de plusieurs méga avec le format bzimage.</li>
</ul>
<ul>
<li><strong>Multiboot</strong> charge un noyau au format multiboot et lui passe le contrôle en mode protégé 32 bits après un certain nombre d'initialisations. On utilisera cette méthode une prochaine fois.</li>
</ul>


<h3>zImage</h3>


<p>On commence par une solution simple à mettre en place, un exécutable au format zImage. Le format est décrit dans la documentation des sources du noyau linux&nbsp;:  <a href="http://lxr.linux.no/linux+v2.6.26.6/Documentation/i386/boot.txt" hreflang="en">/usr/src/linux-2.X.XX/Documentation/i386/boot.txt</a>. C'est dans ce format que nous allons développer un binaire bootable directement.</p>


<p>Le bootloader (grub) lit l'en-tête du fichier zImage puis pose la première section (attention, taille limitée à quelques dizaines de ko) à l'adresse 0x90000, Ensuite, il lit le reste du fichier et le place en 0x1000 (pour une zImage, limitée à 512ko) ou en 0x100000 (pour une bzImage). Ensuite, dans le cas de linux, le noyau s'amuse à redéplacer tout ça selon un processus plus ou moins compliqué <a href="http://tldp.org/HOWTO/Linux-Init-HOWTO-2.html" hreflang="en">décrit ici</a> et <a href="http://www.tldp.org/HOWTO/Linux-i386-Boot-Code-HOWTO/index.html" hreflang="en">ici</a>. Attention, ne prenez pas ces documents pour argent comptant, ils sont un peu dépassés. En pratique nous n'irons pas si loin puisque nous resterons en mode réel et que 512ko nous seront largement suffisant (640Ko ça devrait suffire pour tout le monde !).</p>


<p>Nous allons donc faire simple et récupérer le code de boot de linux pour lancer notre petit projet. Le fichier qui contient le code de lancement ainsi que les en-têtes qui vont bien s'appelle <a href="http://lxr.linux.no/linux+v2.6.26.6/arch/x86/boot/header.S">header.S</a>.</p>


<p>Attention, il est écrit en assembleur GNU (gas), celui-ci diffère beaucoup de l'assembleur intel. Le point le plus important est que les arguments sont inversés (source puis destination).
<strong> header.S </strong>
Apportons quelques modifications au fichier pour qu'il corresponde à nos besoins&nbsp;:</p>


<p><span id="more-22"></span></p>

<ul>
<li>suppression des include</li>
<li>changement de la version de format pour se simplifier la vie</li>
</ul>
<pre>
-               .word   0x0209          # header version number (&gt;= 0x0105)
+               .word   0x0207          # header version number (&gt;= 0x0105)
</pre>

<ul>
<li>pas de payload (il faudra tout faire dans 4 secteurs (2Ko)</li>
</ul>
<pre>
-payload_offset:                .long input_data
-payload_length:                .long input_data_end-input_data
+payload_offset:                .long 0
+payload_length:                .long 0
</pre>

<ul>
<li>suppression des appels à puts pour éviter les dépendances inutiles</li>
</ul>
<pre>
-       calll   puts
</pre>

<ul>
<li>ajout des #define correspondant à nos besoins (surtout pour que ça compile)</li>
</ul>
<pre>
+#define DEF_SYSSEG       0x1000                                  
+#define DEF_SYSSIZE  0x200
+#define ASK_VGA          0xfffd          /* ask for it at bootup */
+#define STACK_SIZE      512     /* Minimum number of bytes for stack */
+#define CONFIG_PHYSICAL_ALIGN 0x200000
+#define COMMAND_LINE_SIZE 2048
</pre>


<p>Ce fichier se termine par un appel à la fonction cmain qu'on codera en C, bien plus sympa à écrire que l'assembleur.</p>



<h3>Fractint</h3>


<p>Comme nous voulons avoir des résultats rapidement, nous allons choisir un projet simple, dessiner l'<a href="http://fr.wikipedia.org/wiki/Ensemble_de_Mandelbrot" hreflang="fr">ensemble de Mandelbrot</a> en vga. Résumons l'algorithme en 3 étapes&nbsp;: initialiser le mode graphique, afficher la fractale et attendre.</p>


<p>On utilise gcc (du projet gnu pour ceux qui suivent ;-), mais son compilateur C ne génère que de l'assembleur 32 bits. Donc la ruse de sioux est de préfixer le code par la directive suivante pour que l'assembleur le transforme code compatible 16 bits (nécessaire puisque nous sommes en mode réel)&nbsp;:</p>
<pre>
asm(&quot;.code16gcc&quot;);
</pre>


<p>Pour le mode graphique, choisissons le mode vga 0x13 (320x200x8), il est facile à utiliser car chaque pixel est mappé sur une adresse en RAM et donc adressable directement en mode réel à l'adresse 0xA0000 (A000:0000 pour les habitués de l'assembleur Intel 16 bits).
Les vieux savent bien que la carte graphique se gère avec <a href="http://www.ctyme.com/intr/int-10.htm" hreflang="en">l'interruption 10h</a>, fonction 0 pour choisir le mode vidéo.</p>


<p>C'est l'occasion de regarder comment on incruste de l'assembleur dans du code C avec gcc&nbsp;:</p>
<pre>
/* Je vous fais la version longue */
/* Le code assembleur paramétré (d'où les %%) */        asm (&quot;pushl %%ebp; pushw %%ds; int $0x10; popw %%ds; popl %%ebp&quot;
/* L'affectation des valeurs de retour  */                      :
/* L'affectation des paramètres */                              : &quot;a&quot; (mode)
/* La liste des registres à sauvegarder */                      : &quot;ebx&quot;, &quot;ecx&quot;, &quot;edx&quot;, &quot;esi&quot;, &quot;edi&quot;);
</pre>

<p>On trouve en ligne les détails pour faire du <a href="http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html" hreflang="en">code assembleur en gcc</a>. Remarquez que si vous n'avez aucun '_:_' (pas de paramètre) les <strong>%%</strong> doivent être remplacés par des <strong>%</strong>.</p>


<p>Maintenant, la fonction pour modifier la palette de couleurs (8 bits, 256 couleurs, une palette) avec des valeurs RGB sur 6 bits&nbsp;:</p>
<pre>
/* la technique d'origine pour modifier la palette vga */
/* on modifie directement des registres de la carte graphique */
        asm( &quot;outb %%al,%%dx&quot; : : &quot;a&quot; (idx), &quot;d&quot; (0x03c8) );
        asm( &quot;outb %%al,%%dx&quot; : : &quot;a&quot; (r), &quot;d&quot; (0x03c9) );
        asm( &quot;outb %%al,%%dx&quot; : : &quot;a&quot; (g), &quot;d&quot; (0x03c9) );
        asm( &quot;outb %%al,%%dx&quot; : : &quot;a&quot; (b), &quot;d&quot; (0x03c9) );
</pre>


<p>Et la fonction pour modifier un pixel&nbsp;:</p>
<pre>
/* calcul de la position du pixel en mémoire vidéo */
        int pos = 320*y+x;
/* Technique à la mano car gas ne supporte pas l'adressage 16bits avec des segments
 * - on passe par ds qu'on doit sauvegarder
 * - la mémoire vidéo du mode vga 13h commence en A000:0000
 */
        asm (&quot;push %%ds; movw %%ax,%%ds; movb %%cl,(%%bx); pop %%ds&quot;
                : : &quot;a&quot; (0xA000), &quot;b&quot;(pos), &quot;c&quot; (color));
</pre>


<p>Le reste est un algorithme basique de calcul de Mandelbrot. Pour rappeler quelques souvenirs&nbsp;:</p>
<ul>
<li>c = (x,y)</li>
<li>p0 = (0,0)</li>
<li>p(n+1) = p(n)^2 + c</li>
<li>plus p diverge vite, plus on est loin de l'ensemble (-&gt; choix de la couleur)</li>
</ul>

<h3>Compilation</h3>


<p>Il faut maintenant compiler tout ça pour en faire un binaire au format zImage.</p>


<p>On compile avec gcc en faisant bien attention à ne pas inclure la libc (et à spécifier une architecture 32 bits pour les amd64)&nbsp;:</p>
<pre>
CFLAGS=&quot;-fno-builtin -nostdinc -O2 -I. -Wall -m32&quot;
gcc $CFLAGS -c header.S
gcc $CFLAGS -c kernel.c
</pre>


<p>Ensuite, il faut faire l'édition de lien (on fait toujours attention à la libc), nous avons besoin d'un script (setup.ld) pour maîtriser complètement le binaire sortant. Il est repiqué de linux, avec une instruction supplémentaire à la fin pour aligner la taille du binaire à celle précisée dans l'en-tête&nbsp;:</p>
<pre>
LDFLAGS=&quot;-nostdlib -Wl,-N&quot;
gcc $LDFLAGS -o mandel.exec -T setup.ld header.o kernel.o
</pre>


<p>Et on extrait le binaire final de notre binaire au format <a href="http://en.wikipedia.org/wiki/Executable_and_Linkable_Format" hreflang="en">elf</a>&nbsp;:</p>
<pre>
# extraction du binaire
objcopy -O binary mandel mandel.exec
</pre>


<h3>Grub, qemu</h3>


<p>Il nous faut maintenant tester notre œuvre. Plutôt que de devoir rebooter notre vraie machine, nous allons utiliser une machine virtuelle complète (qemu, vmware, virtualbox ...), dans laquelle on installe grub.</p>


<p>Et dans votre menu (ou dans le shell grub)&nbsp;:</p>
<pre>
kernel (hd0,0)/boot/mandel
</pre>


<p>C'est jôliii&nbsp;!
<img src="http://linux-attitude.fr/public/Schemas/mandel1.png" alt="mandel1.png" style="display:block; margin:0 auto;" title="mandel1.png, oct 2008" /></p>


<p>Pour ceux qui veulent tester, il y a en pièces jointes, les sources ainsi qu'une image disque toute prête pour <a href="http://bellard.org/qemu/" hreflang="en">qemu</a> contenant les sources, le binaire compilé, ainsi qu'un grub préinstallé avec un menu (et le contenu du prochain article avec, mais chut). Pour ceux qui n'ont pas tout suivi, essayez de lire les sources, ca peut être instructif.</p>
<pre>
$ qemu mandel.dd
</pre>


<p>Dans le prochain numéro, nous ferons la même chose en plus grand, plus beau et en mode protégé.</p>


<p><strong>PJ</strong>&nbsp;:</p>
<ul>
<li><a href="http://linux-attitude.fr/public/Code/mandel1/compile.sh">compile.sh</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel1/header.S">header.S</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel1/kernel.c">kernel.c</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel1/setup.ld">setup.ld</a></li>
<li><a href="http://linux-attitude.fr/public/Code/mandel.dd">mandel.dd</a></li>
</ul>

<p></p><p>Si vous avez aimé, il y a aussi : </p><ol><li><a href='http://linux-attitude.fr/post/le-retour-de-la-vengeance-de-la-bidouille' rel='bookmark' title='Permanent Link: Le retour de la vengeance de la bidouille'>Le retour de la vengeance de la bidouille</a></li>
<li><a href='http://linux-attitude.fr/post/vectorisation' rel='bookmark' title='Permanent Link: Vectorisation'>Vectorisation</a></li>
<li><a href='http://linux-attitude.fr/post/en-vrac-25' rel='bookmark' title='Permanent Link: En vrac (25)'>En vrac (25)</a></li>
</ol>
	Tags:<a href="http://linux-attitude.fr/tag/code" title="Code" rel="tag">Code</a>, <a href="http://linux-attitude.fr/tag/noyau" title="Noyau" rel="tag">Noyau</a>, <a href="http://linux-attitude.fr/tag/planet-libre" title="planet-libre" rel="tag">planet-libre</a><br />
]]></content:encoded>
			<wfw:commentRss>http://linux-attitude.fr/post/le-retour-de-la-bidouille/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Respections le protocole</title>
		<link>http://linux-attitude.fr/post/respections-le-protocole?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=respections-le-protocole</link>
		<comments>http://linux-attitude.fr/post/respections-le-protocole#comments</comments>
		<pubDate>Fri, 17 Oct 2008 20:00:00 +0000</pubDate>
		<dc:creator>peck</dc:creator>
				<category><![CDATA[Réseau]]></category>
		<category><![CDATA[Noyau]]></category>

		<guid isPermaLink="false">http://linux-attitude.fr/post/respections-le-protocole</guid>
		<description><![CDATA[Niveau&#160;: &#160;&#160;&#160;&#160;&#160; Résumé&#160;: Internet Protocol Pour ceux qui n'ont pas tout compris au dernier article réseau, voici quelques compléments sur le protocole IP. Celui qui vous permet d'envoyer n'importe quelle information à l'autre bout de la planète. Toute machine sur internet dispose d'une adresse IP (v4 pour l'instant). Écrite sous la forme w.x.y.z où chaque [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Niveau</strong>&nbsp;: <span class="s">&nbsp;</span><span class="e">&nbsp;</span><span class="e">&nbsp;</span><span class="e">&nbsp;</span><span class="e">&nbsp;</span><br />
<strong>Résumé</strong>&nbsp;: Internet Protocol</p>


<p>Pour ceux qui n'ont pas tout compris au dernier <a href="http://linux-attitude.fr/post/Des-lutins-dans-votre-noyau">article réseau</a>, voici quelques compléments sur le protocole IP. Celui qui vous permet d'envoyer n'importe quelle information à l'autre bout de la planète.</p>


<p>Toute machine sur internet dispose d'une adresse IP (v4 pour l'instant). Écrite sous la forme w.x.y.z où chaque lettre est un nombre compris entre 0 et 255 (donc un total de 32 bits). A chaque fois qu'une machine veut communiquer avec une autre elle remplit un paquet ip qu'elle envoie sur le réseau. Ce paquet soit contenir au moins les informations suivantes&nbsp;:</p>
<pre>
IP source
IP destination
protocole
Diverses choses
</pre>


<p>L'ip source, c'est tout simplement l'ip de la machine qui envoie le paquet et l'ip de destination peut être récupérée par le dns si le nom complet de la machine est connu.</p>


<p>Ce paquet doit être envoyé au bon routeur qui se débrouillera avec, et c'est là qu'intervient la configuration de la machine.</p>


<p>Supposons que nous soyons le noyau et essayons de traiter le paquet</p>
<pre>
#on regarde toutes les routes et on sélectionne celle qui nous intéresse
$ ip route show 
# on regarde l'ip source et la carte à partir de laquelle on va envoyer nos paquets
$ ip addr show
#ces deux opérations peuvent être résumées ainsi
$ ip route get w.x.y.z
</pre>


<p>La configuration de votre réseau se fait (au niveau du noyau) avec les commandes</p>
<pre>
# activation de la carte
$ ip link set dev toto up
# mise en place d'un adresse ip (et de son réseau)
$ ip addr add 10.0.1/24 dev toto
# mise en place d'un routage
$ ip route add default via 10.0.0.2
</pre>

<p>Heureusement, tout cela est fait automatiquement par votre distribution (à la lecture de /etc/nerwork/interfaces pour debian).</p>


<p>Vous aurez remarqué la notion de réseau, qui est apparu sous la forme 10.0.0.1/24. Cela veut dire que l'adresse 10.0.0.1 appartient au réseau constitué des ip de 10.0.0.0 à 10.0.0.255. Nous l'avons déduit grâce au maque /24 (qui s'écrit aussi 255.255.255.0), c'est-à-dire que les 24 premiers bits sont fixe.</p>


<p>On a beau avoir un cerveau brillant et pouvoir faire ceci de tête, le plus simple pour ne pas se tromper est d'utiliser un commande qui fait les calculs pour nous&nbsp;:</p>
<pre>
$ ipcalc 10.0.0.1/24
</pre>


<p>Vous remarquerez que dans un réseau il y a toujours 2 adresses qui ne peuvent pas être utilisées&nbsp;: la première, qui sert à désigner le réseau lui-même et la dernière qui sert de broadcast (envoi des paquets à tout le monde). Le plus petit réseau possible est donc un /30 avec 2 ip. Il est possible de faire plus petit, mais ce n'est plus vraiment un réseau au sens IP. On peut faire communiquer 2 IP dans un /31 moyennant quelques variations dans la configuration.</p>

<p></p><p>Si vous avez aimé, il y a aussi : </p><ol><li><a href='http://linux-attitude.fr/post/iproute2' rel='bookmark' title='Permanent Link: iproute2'>iproute2</a></li>
<li><a href='http://linux-attitude.fr/post/routage-ameliore' rel='bookmark' title='Permanent Link: Routage amélioré'>Routage amélioré</a></li>
<li><a href='http://linux-attitude.fr/post/des-lutins-dans-votre-noyau' rel='bookmark' title='Permanent Link: Des lutins dans votre noyau'>Des lutins dans votre noyau</a></li>
</ol>
	Tags:<a href="http://linux-attitude.fr/tag/noyau" title="Noyau" rel="tag">Noyau</a>, <a href="http://linux-attitude.fr/tag/reseau" title="Réseau" rel="tag">Réseau</a><br />
]]></content:encoded>
			<wfw:commentRss>http://linux-attitude.fr/post/respections-le-protocole/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Des lutins dans votre noyau</title>
		<link>http://linux-attitude.fr/post/des-lutins-dans-votre-noyau?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=des-lutins-dans-votre-noyau</link>
		<comments>http://linux-attitude.fr/post/des-lutins-dans-votre-noyau#comments</comments>
		<pubDate>Mon, 13 Oct 2008 22:33:00 +0000</pubDate>
		<dc:creator>peck</dc:creator>
				<category><![CDATA[Réseau]]></category>
		<category><![CDATA[Noyau]]></category>

		<guid isPermaLink="false">http://linux-attitude.fr/post/des-lutins-dans-votre-noyau</guid>
		<description><![CDATA[Niveau&#160;: &#160;&#160;&#160;&#160;&#160; Résumé&#160;: ip_forward&#160;; iptables -j MASQUERADE&#160;; iptables -j DROP&#160;; brctl&#160;; ip Routeur Un routeur, c'est une machine qui renvoie les paquets qui ne lui sont pas destinés vers d'autres machines qui les accepteront. Faisons-en un sous linux&#160;: $ echo 1 &#62; /proc/sys/net/ipv4/all/ip_forward Facile hein&#160;! Maintenant linux (le noyau) renverra tous les paquets qu'il reçoit [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Niveau</strong>&nbsp;: <span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="e">&nbsp;</span><span class="e">&nbsp;</span><span class="e">&nbsp;</span><br />
<strong>Résumé</strong>&nbsp;: ip_forward&nbsp;; iptables -j MASQUERADE&nbsp;; iptables -j DROP&nbsp;; brctl&nbsp;; ip</p>



<h3>Routeur</h3>

<p>Un routeur, c'est une machine qui renvoie les paquets qui ne lui sont pas destinés vers d'autres machines qui les accepteront. Faisons-en un sous linux&nbsp;:</p>
<pre>
$ echo 1 &gt; /proc/sys/net/ipv4/all/ip_forward
</pre>


<p>Facile hein&nbsp;! Maintenant linux (le noyau) renverra tous les paquets qu'il reçoit (au niveau ethernet) mais qui ne lui sont pas destinés (au niveau IP). Reste plus qu'à maintenir une table de routage (avec la commande "route", "ip route" ou avec un démon dédié comme quagga qui le gère dynamiquement).</p>


<h3>NAT</h3>


<p>Parfois la machine de départ utilise des IP qui n'ont pas le droit d'aller sur internet (c'est pratique pour communiquer en interne, mais c'est tout). Le routeur (la passerelle) doit donc traduire ces IP privées en IP publiques (en général il utilise la sienne). C'est le NAT. Les réseaux ip privées sont&nbsp;: 10.0.0.0/8 172.16.0.0/12 et 192.168.0.0/16</p>


<p>Pour activer le nat sur un linux, il faut déjà qu'il fasse routeur (voir ci dessus), puis on transforme les paquets avec netfilter (netfilter est le fltre du noyau, iptables est la commande pour le piloter)&nbsp;:</p>
<pre>
$ iptables -t nat -A POSTROUTING -s 10.0.0.0/24 -o eth0 -j MASQUERADE
</pre>


<h3>Firewall</h3>


<p>Un firewall va examiner la couche IP et la couche TCP pour filtrer ce qui se passe. Il peut tout faire, couper, changer le paquet ... Tout ceci se fait avec iptables sous linux. C'est un peu complexe, donc voici simplement un exemple qui coupe un utilisateur&nbsp;:</p>
<pre>
$ iptables -A FORWARD -s 10.0.0.12 -j DROP
</pre>


<h3>Pont</h3>

<p>Un pont (bridge) relie 2 (ou plus) réseaux ethernet comme le ferait un switch. Pour faire un bridge sous linux on utilise la commande brctl.</p>

<pre>
# on crée un nouveau bridge nommé bridge0
$ brctl addbr bridge0
# on ajoute les cartes réseau au bridge (le bridge prend l'adresse mac de la première carte ajoutée)
$ brctl addif bridge0 eth0
$ brctl addif bridge0 eth1
</pre>


<p>Et voila, à partir de ce moment, les paquets sont bien retransmis sur le réseau, si un paquet arrive sur une interface, il est retransmis sur l'autre s'il y a lieu.
Mais si on veut que l'ordinateur qui fait bridge soit aussi sur le réseau en question, il faut y ajouter quelques modifications&nbsp;:</p>
<pre>
# on désactive la pile ip sur les cartes du bridge
$ ip addr del 10.0.0.1/24 dev eth0
$ ip addr del 10.0.1.1/24 dev eth1
# et on l'active sur le bridge lui-même (représenté pare une carte réseau virtuelle)
$ ip addr add 10.0.0.1/24 dev bridge0
</pre>


<h3>Réseaux multiples</h3>

<p>La notion de réseau IP est décorrélé de la notion de réseau ethernet. Il est donc parfaitement possible d'avoir plusieurs réseaux IP sur le même réseau ethernet. Et cela se fait très simplement&nbsp;:</p>
<pre>
$ ip addr add 10.0.0.1/24 dev eth0
$ ip addr add 192.168.0.1/24 dev eth0
</pre>


<h3>Tunnel</h3>

<p>Un tunnel permet d'encapsuler un flux entre 2 machines dans un autre flux. Par exemple le tunnel ssh encapsule un flux tcp dans un flux ssh.</p>


<p>Faisons tunnel ip, avec le module gre du noyau&nbsp;:</p>
<pre>
# on crée un tunnel nommé tunnel0 
$ ip tunnel add tunnel0 mode gre remote 1.2.3.4
# ce tunnel est en fait une interface virtuelle qu'on configure
$ ip link set tunnel0 up
$ ip addr add 10.0.1.1 dev tunnel0
# un tunnel n'a que 2 bouts, on choisit de gérer le sous-réseau à la main
$ ip route add 10.0.1.2 dev tunnel0
</pre>


<p>N'oubliez pas qu'il faut faire la même chose à l'autre bout du tunnel (avec des ip inversée bien sûr) et vous avez maintenant une carte réseau sur chaque machine reliées par un câble virtuel.</p>

<p></p><p>Si vous avez aimé, il y a aussi : </p><ol><li><a href='http://linux-attitude.fr/post/des-lutins-partout' rel='bookmark' title='Permanent Link: Des lutins partout'>Des lutins partout</a></li>
<li><a href='http://linux-attitude.fr/post/iproute2' rel='bookmark' title='Permanent Link: iproute2'>iproute2</a></li>
<li><a href='http://linux-attitude.fr/post/aggregation-de-lien' rel='bookmark' title='Permanent Link: Aggrégation de lien'>Aggrégation de lien</a></li>
</ol>
	Tags:<a href="http://linux-attitude.fr/tag/noyau" title="Noyau" rel="tag">Noyau</a>, <a href="http://linux-attitude.fr/tag/reseau" title="Réseau" rel="tag">Réseau</a><br />
]]></content:encoded>
			<wfw:commentRss>http://linux-attitude.fr/post/des-lutins-dans-votre-noyau/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>La virtualisation pour tous</title>
		<link>http://linux-attitude.fr/post/la-virtualisation-pour-tous?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=la-virtualisation-pour-tous</link>
		<comments>http://linux-attitude.fr/post/la-virtualisation-pour-tous#comments</comments>
		<pubDate>Fri, 10 Oct 2008 22:57:00 +0000</pubDate>
		<dc:creator>peck</dc:creator>
				<category><![CDATA[Sysadmin]]></category>
		<category><![CDATA[Noyau]]></category>

		<guid isPermaLink="false">http://linux-attitude.fr/post/la-virtualisation-pour-tous</guid>
		<description><![CDATA[Niveau&#160;: &#160;&#160;&#160;&#160;&#160; Résumé&#160;: linux Imaginez que vous soyez un simple utilisateur (un compte dans une université par exemple), alors les joies de l'administration système vous sont interdites. Heureusement une bande de jeunes hippies a décidé de faire quelque chose contre nature, essayer de transformer le noyau en simple application qui tournerait dans l'espace utilisateur. Et [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Niveau</strong>&nbsp;: <span class="s">&nbsp;</span><span class="s">&nbsp;</span><span class="e">&nbsp;</span><span class="e">&nbsp;</span><span class="e">&nbsp;</span><br />
<strong>Résumé</strong>&nbsp;: linux</p>


<p>Imaginez que vous soyez un simple utilisateur (un compte dans une université par exemple), alors les joies de l'administration système vous sont interdites. Heureusement une bande de jeunes hippies a décidé de faire quelque chose contre nature, essayer de transformer le noyau en simple application qui tournerait dans l'espace utilisateur. Et ça a marché,  le noyau est maintenant un processus comme les autres.</p>


<p>On peut donc faire tourner linux sur un système existant, théoriquement un bsd ou un solaris peut même faire l'affaire, on a même trouvé des fous pour porter linux sous windows (cherchez colinux, vous trouverez).</p>


<h3>Le noyau</h3>

<p>Si vous êtes sous debian prenez le paquet user-mode-linux, et si vous êtes fans de la <a href="http://linux-attitude.fr/post/La-peche">compilation de noyau</a>&nbsp;:</p>
<pre>
$ make menuconfig ARCH=um
$ make ARCH=um
</pre>


<p>Et voila, il suffit de lancer linux&nbsp;:</p>
<pre>
$ linux
</pre>


<h3>Le système</h3>

<p>Bon, tout n'est pas si simple, il faudra bien que vous ayez un système de fichier pour ce linux. Si vous n'êtes pas root, vous devrez le préparer sur une autre machine. Il vous faut faire une image disque, soit à partir d'une installation existante, soit une nouvelle installation (par exemple avec <a href="http://linux-attitude.fr/post/Quand-Debian-imite-Austin">debootstrap</a>)&nbsp;:</p>
<pre>
# récupérer un disque existant
$ dd if=/dev/sda1 of=/data/image.dd

# créer un nouveau disque
$ dd if=/dev/zero of=/data/image.dd bs=1M count=512
$ mke2fs -j /data/image.dd
$ mount -o loop /data/image.dd /mnt
$ debootstrap etch /mnt
$ umount /mnt
</pre>


<p>Maintenant que nous avons notre image, c'est parti&nbsp;:</p>
<pre>
$ linux ubd0=/data/image.dd
</pre>


<p><span id="more-268"></span></p>


<h3>Les options</h3>


<p>Vos pouvez saupoudrer de quelques options, la liste est disponible avec la commande&nbsp;:</p>
<pre>
$ linux --help
</pre>


<p>Auxquelles ils faut ajouter les commandes habituelles qu'il est possible de passer au noyau à travers le bootloader. Les commandes intéressantes sont&nbsp;:</p>
<ul>
<li>mem=64M&nbsp;: pour allouer une certaine quantité de mémoire au noyau, c'est toujours une bonne idée de le préciser</li>
<li>hostfs=/home/user&nbsp;: pour autoriser l'accès au système de fichier de la machine hôte dans l'uml, il se monte avec la commande suivante&nbsp;:</li>
</ul>
<pre>
mount -t hostfs none /host
</pre>



<h3>Le réseau pour un utilisateur</h3>

<p>Ensuite vous voudrez sûrement le réseau, et là, beaucoup solutions pour beaucoup de problèmes différents. Commençons pas le cas où vous êtes simple utilisateur (pas root). Vous avez le choix entre utiliser la connexion de la machine hôte ou faire un tunnel vers une machine (où vous êtes root) qui vous laissera accès à une ip et un accès complet.</p>


<p>Prenons le premier cas, vous n'aurez le droit qu'à ce qui est autorisé à un simple utilisateur c'est-à-dire des connexions TCP et UDP (avec une sorte de nat), pas de ping (/bin/ping est suid). Si slirp n'est pas installé, vous devrez le compiler&nbsp;:</p>
<pre>
# réseau hôte avec slirp
$ linux ubd0=/data/image.dd eth0=slirp,,~/bin/slirp
# le réseau reste à configurer dans l'uml
</pre>


<p>Dans le cas d'un tunnel. Si vde n'est pas installé, vous devrez le compiler&nbsp;:</p>
<pre>
# Un switch virtuel
$ vde_switch -s /tmp/switch1
# on y connecte notre nouveau noyau
$ linux ubd0=/data/image.dd eth0=vde,/tmp/switch1
# le réseau reste à configurer dans l'uml

# Sur la machine distante où vous êtes root, l'autre bout du switch
$ vde_switch -tap
# et là nat (vous pouvez aussi faire un bridge si vous voulez)
$ iptables -t nat -A POSTROUTING -s 10.0.0.1/24 -o eth0 -j MASQUERADE

# Et on connecte les 2 switchs virtuels
# à faire dans le sens qui vous intéresse
$ dpipe vde_plug = ssh remote.machine.org vde_plug
</pre>


<p>Si vous voulez seulement faire des réseaux d'uml local, vous pouvez aussi les brancher entre eux sans accès à l'extérieur&nbsp;:</p>
<pre>
# Un switch virtuel connecte 3 linux
$ vde_switch -s /tmp/switch1
$ linux ubd0=/data/image1.dd eth0=vde,/tmp/switch1
$ linux ubd0=/data/image2.dd eth0=vde,/tmp/switch1
$ linux ubd0=/data/image3.dd eth0=vde,/tmp/switch1

# ou si vous ne voulez pas installer vde, uml_switch est fourni directement avec uml
$ uml_switch -s /tmp/switch1
$ linux ubd0=/data/image1.dd eth0=daemon,,,/tmp/switch1
$ linux ubd0=/data/image2.dd eth0=daemon,,,/tmp/switch1
$ linux ubd0=/data/image3.dd eth0=daemon,,,/tmp/switch1
</pre>


<h3>Le réseau pour root</h3>

<p>Si vous êtes root vous aurez plus de facilité. Vous avez le choix (en plus des 2 précédents) entre vous attribuer une ip interne et faire du nat ou vous brancher directement sur le réseau de l'hôte (bridge).</p>


<p>Dans tous les cas vous allez faire une interface virtuelle qui apparaîtra sur la machine hôte&nbsp;:</p>
<pre>
# 10.0.0.1 est l'ip de l'interface virtuelle côté hôte 
$ linux ubd0=/data/image.dd eth0=tuntap,,,10.0.0.1
# À vous de configurer l'interface dans l'uml (par exemple avec l'ip 10.0.0.2)
</pre>


<p>Je vous laisse faire le reste comme un grand.</p>


<h3>Plus</h3>

<ul>
<li>Un <a href="http://user-mode-linux.sourceforge.net/old/UserModeLinux-HOWTO.html" hreflang="en">howto</a> plus détaillé</li>
<li>man uml_mconsole vous aidera à manipuler l'uml pendant qu'il tourne</li>
<li>Le <a href="http://uml.jfdi.org/uml/Wiki.jsp" hreflang="en">wiki</a> peut vous aider</li>
</ul>

<p></p><p>Si vous avez aimé, il y a aussi : </p><ol><li><a href='http://linux-attitude.fr/post/la-flexibilite-pour-tous' rel='bookmark' title='Permanent Link: La flexibilité pour tous'>La flexibilité pour tous</a></li>
<li><a href='http://linux-attitude.fr/post/git-pour-tous' rel='bookmark' title='Permanent Link: Git pour tous'>Git pour tous</a></li>
<li><a href='http://linux-attitude.fr/post/git-a-tous-les-etages' rel='bookmark' title='Permanent Link: Git à tous les étages'>Git à tous les étages</a></li>
</ol>
	Tags:<a href="http://linux-attitude.fr/tag/noyau" title="Noyau" rel="tag">Noyau</a><br />
]]></content:encoded>
			<wfw:commentRss>http://linux-attitude.fr/post/la-virtualisation-pour-tous/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced (User agent is rejected)
Database Caching 22/93 queries in 0.117 seconds using apc
Object Caching 1830/1914 objects using apc
Content Delivery Network via N/A

Served from: linux-attitude.fr @ 2012-02-08 23:52:37 -->
