<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
  <title></title>
</head>
<body bgcolor="#ffffff" text="#000000">
Bonjour,<br>
<br>
C'est mon premier message sur cette liste, qui semble une niche
d'information.<br>
<br>
Merci pour SOS, qui me permet de comprendre certains principes des OS
32 bits, ce qui me permet d'am&eacute;liorer mes comp&eacute;tences en C et ASM x86.<br>
<br>
Mon but est de faire un OS graphique vers la fin (tr&egrave;s simple), ce qui
signifie que je vais d'abord me rendre &agrave; la gestion des threads
utilisateurs et j'essaierai d'impl&eacute;menter un simple contr&ocirc;leur du mode
v8086. Avec &ccedil;a, il me semble que je pourrai contr&ocirc;ler efficacement la
configuration du mode vid&eacute;o (obtention des param&egrave;tres, d&eacute;finition du
mode et acc&egrave;s &agrave; l'interface du mode prot&eacute;g&eacute; VBE) (le bootsecteur me
permet de faire &ccedil;a, mais ce n'est pas tr&egrave;s bon (aucun contr&ocirc;le de
validit&eacute;)).<br>
<br>
Pour l'instant, j'arrive au gestionnaire de pages physiques, dont je
semble avoir compris le fonctionnement, et j'ai le code suivant (que
j'ai mis en pi&egrave;ce jointe). Mais, cela g&eacute;n&egrave;re une boucle infinie sous
qemu, avec des valeurs totalement loufoques de "i" et "page_descr"
(fonction physmem_init() ).<br>
<br>
Apr&egrave;s quelques tests, je me rends compte de ceci (j'ai 32 Mb de RAM
sous qemu):<br>
start (le d&eacute;but de la m&eacute;moire g&eacute;r&eacute;e) est &agrave; 4096 (correct);<br>
end (la fin de la m&eacute;moire g&eacute;r&eacute;e) est &agrave; 33554432 (32 Mb exact) (correct);<br>
Nombre de pages (end-start)&gt;&gt;PAGE_SHIFT est &agrave; 8191 (encore
correct);<br>
l'adresse de "i" sur la pile est 2 164 144;<br>
DESCR_START (qui correspond &agrave; PALIGNS( &amp; __e_kernel )) est &agrave; 2 097
152 (plus bas que i??) ??<br>
<br>
Je ne comprends pas du tout ce qui se passe, pourquoi le symbole
__e_kernel est-il comme cela ? C'est la source de mes probl&egrave;mes (car
dans ce cas page_descr pointera &eacute;ventuellement vers i et l'&eacute;crasera, ce
qui cr&eacute;e une boucle infinie ...<br>
<br>
Je compile avec cygwin et le cross-compilateur que vous avez fourni
(binutils 2.16, gcc 3.4.4) sous Windows. Le makefile est l&eacute;g&egrave;rement
modifi&eacute; pour automatiquement utiliser l'image de grub fournie. Je mets
le zip en pi&egrave;ce jointe et, si &ccedil;a marche pas (aucune exp&eacute;rience en
mailing-lists), allez sur
<a class="moz-txt-link-freetext" href="http://serveur1.archive-host.com/membres/up/1521434322/MyOS.zip">http://serveur1.archive-host.com/membres/up/1521434322/MyOS.zip</a> .<br>
<br>
&gt;&gt;Merci de m'aider.<br>
<br>
<br>
P.S Voici certaines fonctions que je juge pratiques, sont-elles bien ?<br>
<br>
<blockquote>Soft_Ramsize: Calcul en C de la taille de la RAM. Utile
quand le boot sector et grub ne fonctionne pas. Cette fonction doit
&ecirc;tre appel&eacute;e avant la pagination (car elle cherche &agrave; &eacute;crire directement
en m&eacute;moire). La taille minimale pr&eacute;cis&eacute;e est &eacute;gale &agrave; 4 Mio - 4 o. Cette
fonction ne *devrait* pas effacer les donn&eacute;es en RAM (elle remet les
donn&eacute;es qu'elle &eacute;crase), mais je n'ai pas eu &agrave; voir si &ccedil;a le faisait
vraiment.<br>
C'est pour &eacute;viter d'&eacute;craser le noyau que je mets 4 Mo.<br>
L'algorithme utilis&eacute; est simple (c'est le m&ecirc;me principe qu'une
recherche binaire). "magic" vaut "01111111111111111111111111111111b"
(c'est un choix personnel). &Ccedil;a boucle tant que l'espace entre deux
tests est plus petit qu'un octet.<tt><br>
&nbsp;<br>
void soft_ramsize(unsigned long *ramsize){<br>
&nbsp;&nbsp;&nbsp; volatile unsigned long magic = 2147483647,tmp=0;<br>
&nbsp;&nbsp;&nbsp; /* minRAM = 4MB (don't blow up the kernel code), maxRAM = 4GB .
Remove 4 bytes because it's a long (magic do 4 bytes in memory). */<br>
&nbsp;&nbsp;&nbsp; unsigned long minRAM = 0x3FFFFC, maxRAM = 0xFFFFFFFC;<br>
&nbsp;&nbsp;&nbsp; register unsigned long ramsz = (maxRAM - minRAM) &gt;&gt; 1;<br>
&nbsp;&nbsp;&nbsp; volatile unsigned long *tptr;<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; do{<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tptr = (long*)(ramsz);<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tmp = *tptr;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *tptr = magic;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Higher! */<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; if (*tptr == magic){<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; *tptr = tmp;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tmp = ramsz;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; minRAM = ramsz;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ramsz += (maxRAM - minRAM) &gt;&gt; 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; /* Lower !*/<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; else{<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tmp = ramsz;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; maxRAM = ramsz;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; ramsz -= (maxRAM - minRAM) &gt;&gt; 1;<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; } while (ramsz != tmp); /* While there is another comparison */<br>
&nbsp;&nbsp;&nbsp; *ramsize = (ramsz + 4) &gt;&gt; 10;<br>
}<br>
  <br>
  </tt>Tvmem_putstring: affiche une cha&icirc;ne rapidement &agrave; l'&eacute;cran. Cette
fonction ne g&egrave;re pas encore le d&eacute;passement (quand on d&eacute;passe 24,79).
Elle est &eacute;crite afin d'utiliser les fonctionnalit&eacute;s du processeur
(lodsb et stosw). On utilise une instruction pour &eacute;crire deux octets
dans la RAM vid&eacute;o (stosw), ce qui acc&eacute;l&egrave;re le traitement. l'attribut
est dans ah et le caract&egrave;re dans al (les processeurs intel sont little
endian).<tt><br>
  <i>void tvmem_putstring(u8 row, u8 col, u8 a, const char* str){<br>
&nbsp;&nbsp;&nbsp; /*&nbsp;&nbsp;&nbsp; Explanations:<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; movb %0,%ah&nbsp;&nbsp;&nbsp; &gt; Sets the attribute into ah ONCE<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 1:<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; lodsb&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &gt; Loads an char into AL from memory at ESI<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; orb %al,%al&nbsp;&nbsp;&nbsp; &gt; Or'd ah and ah. This returns zero only if
AL is zero.<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jz 2f:&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &gt; If the or was zero, jump forward to 2: (end)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; stosw&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &gt; Write AX(AH and AL) into memory at EDI<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; jmp 1b&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &gt; Jump backward at 1: (write char)<br>
&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; 2:<br>
&nbsp;&nbsp;&nbsp; */<br>
&nbsp;&nbsp;&nbsp; asm volatile("movb %0,%%ah\n1:&nbsp; lodsb; orb %%al,%%al; jz 2f; stosw;
jmp 1b\n2:"<br>
&nbsp;&nbsp;&nbsp; :<br>
&nbsp;&nbsp;&nbsp; : "m" (a), "D" (VIDEO + ((row * COLUMNS + col) &lt;&lt; 1)), "S"
(str)<br>
&nbsp;&nbsp;&nbsp; : "memory", "ax"<br>
&nbsp;&nbsp;&nbsp; );<br>
}</i><br>
  <br>
  </tt>mov_blk: transf&egrave;re des double mots (des blocs de 32 bits) de src
&agrave; dest. Un des exemples de
<a class="moz-txt-link-freetext" href="http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html">http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html</a> . c'est
de l'ASM inline. cela permet de copier 4 octets &agrave; la fois et donc de
pouvoir acc&eacute;l&eacute;rer de 400% les traitements !<tt><br>
  <br>
  <i>#define mov_blk(src, dest, numwords) \<br>
asm __volatile__ ("cld\n\t"\<br>
"rep movsl"\<br>
:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \<br>
: "S" (src), "D" (dest), "c" (numwords)&nbsp; \<br>
)</i><br>
  <br>
  </tt>memcpy: version optimis&eacute;e qui utilise mov_blk pour faire la
majorit&eacute; du travail:<tt><br>
  <i>void * memcpy(void* dest, const void* src, size_t size){<br>
&nbsp;&nbsp;&nbsp; long dwsize = size &gt;&gt; 2;<br>
&nbsp;&nbsp;&nbsp; char i;<br>
&nbsp;&nbsp;&nbsp; char bsize = size &amp; 3;<br>
&nbsp;&nbsp;&nbsp; long rsize = size - bsize;<br>
&nbsp;&nbsp;&nbsp; char* dest_r = dest + rsize;<br>
&nbsp;&nbsp;&nbsp; char* src_r = (char*)(src + rsize);<br>
&nbsp;&nbsp;&nbsp; <br>
&nbsp;&nbsp;&nbsp; mov_blk((long*)dest,(long*)src, dwsize);<br>
  <br>
&nbsp;&nbsp;&nbsp; for ( i = 0; i&lt;rsize; i++ ) *dest_r++ = *src_r++;<br>
&nbsp;&nbsp;&nbsp; return dest;<br>
}</i><br>
  </tt></blockquote>
&nbsp; <br>
<br>
<br>
</body>
</html>