<!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éliorer mes compétences en C et ASM x86.<br>
<br>
Mon but est de faire un OS graphique vers la fin (très simple), ce qui
signifie que je vais d'abord me rendre à la gestion des threads
utilisateurs et j'essaierai d'implémenter un simple contrôleur du mode
v8086. Avec ça, il me semble que je pourrai contrôler efficacement la
configuration du mode vidéo (obtention des paramètres, définition du
mode et accès à l'interface du mode protégé VBE) (le bootsecteur me
permet de faire ça, mais ce n'est pas très bon (aucun contrôle de
validité)).<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èce jointe). Mais, cela génère une boucle infinie sous
qemu, avec des valeurs totalement loufoques de "i" et "page_descr"
(fonction physmem_init() ).<br>
<br>
Après quelques tests, je me rends compte de ceci (j'ai 32 Mb de RAM
sous qemu):<br>
start (le début de la mémoire gérée) est à 4096 (correct);<br>
end (la fin de la mémoire gérée) est à 33554432 (32 Mb exact) (correct);<br>
Nombre de pages (end-start)>>PAGE_SHIFT est à 8191 (encore
correct);<br>
l'adresse de "i" sur la pile est 2 164 144;<br>
DESCR_START (qui correspond à PALIGNS( & __e_kernel )) est à 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èmes (car
dans ce cas page_descr pointera éventuellement vers i et l'écrasera, ce
qui cré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égèrement
modifié pour automatiquement utiliser l'image de grub fournie. Je mets
le zip en pièce jointe et, si ça marche pas (aucune expé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>
>>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
être appelée avant la pagination (car elle cherche à écrire directement
en mémoire). La taille minimale précisée est égale à 4 Mio - 4 o. Cette
fonction ne *devrait* pas effacer les données en RAM (elle remet les
données qu'elle écrase), mais je n'ai pas eu à voir si ça le faisait
vraiment.<br>
C'est pour éviter d'écraser le noyau que je mets 4 Mo.<br>
L'algorithme utilisé est simple (c'est le même principe qu'une
recherche binaire). "magic" vaut "01111111111111111111111111111111b"
(c'est un choix personnel). Ça boucle tant que l'espace entre deux
tests est plus petit qu'un octet.<tt><br>
<br>
void soft_ramsize(unsigned long *ramsize){<br>
volatile unsigned long magic = 2147483647,tmp=0;<br>
/* 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>
unsigned long minRAM = 0x3FFFFC, maxRAM = 0xFFFFFFFC;<br>
register unsigned long ramsz = (maxRAM - minRAM) >> 1;<br>
volatile unsigned long *tptr;<br>
<br>
do{<br>
tptr = (long*)(ramsz);<br>
tmp = *tptr;<br>
*tptr = magic;<br>
/* Higher! */<br>
if (*tptr == magic){<br>
*tptr = tmp;<br>
tmp = ramsz;<br>
minRAM = ramsz;<br>
ramsz += (maxRAM - minRAM) >> 1;<br>
}<br>
/* Lower !*/<br>
else{<br>
tmp = ramsz;<br>
maxRAM = ramsz;<br>
ramsz -= (maxRAM - minRAM) >> 1;<br>
}<br>
<br>
} while (ramsz != tmp); /* While there is another comparison */<br>
*ramsize = (ramsz + 4) >> 10;<br>
}<br>
<br>
</tt>Tvmem_putstring: affiche une chaîne rapidement à l'écran. Cette
fonction ne gère pas encore le dépassement (quand on dépasse 24,79).
Elle est écrite afin d'utiliser les fonctionnalités du processeur
(lodsb et stosw). On utilise une instruction pour écrire deux octets
dans la RAM vidéo (stosw), ce qui accélère le traitement. l'attribut
est dans ah et le caractè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>
/* Explanations:<br>
movb %0,%ah > Sets the attribute into ah ONCE<br>
1:<br>
lodsb > Loads an char into AL from memory at ESI<br>
orb %al,%al > Or'd ah and ah. This returns zero only if
AL is zero.<br>
jz 2f: > If the or was zero, jump forward to 2: (end)<br>
stosw > Write AX(AH and AL) into memory at EDI<br>
jmp 1b > Jump backward at 1: (write char)<br>
2:<br>
*/<br>
asm volatile("movb %0,%%ah\n1: lodsb; orb %%al,%%al; jz 2f; stosw;
jmp 1b\n2:"<br>
:<br>
: "m" (a), "D" (VIDEO + ((row * COLUMNS + col) << 1)), "S"
(str)<br>
: "memory", "ax"<br>
);<br>
}</i><br>
<br>
</tt>mov_blk: transfère des double mots (des blocs de 32 bits) de src
à 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 à la fois et donc de
pouvoir accélé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>
: \<br>
: "S" (src), "D" (dest), "c" (numwords) \<br>
)</i><br>
<br>
</tt>memcpy: version optimisée qui utilise mov_blk pour faire la
majorité du travail:<tt><br>
<i>void * memcpy(void* dest, const void* src, size_t size){<br>
long dwsize = size >> 2;<br>
char i;<br>
char bsize = size & 3;<br>
long rsize = size - bsize;<br>
char* dest_r = dest + rsize;<br>
char* src_r = (char*)(src + rsize);<br>
<br>
mov_blk((long*)dest,(long*)src, dwsize);<br>
<br>
for ( i = 0; i<rsize; i++ ) *dest_r++ = *src_r++;<br>
return dest;<br>
}</i><br>
</tt></blockquote>
<br>
<br>
<br>
</body>
</html>