[SOS] Multi-Tasking - TSS

KAISER Edouard edouard.kaiser at gmail.com
Mer 14 Sep 13:46:22 CEST 2005


Salut à tous !
J'avance petit à petit dans la mise en place  d'un OS basé sur un
modèle multi segment et je m'aventure donc dans le changement de
contexte, sujet épineux qui peut faire mal aux neuronnes :D
Alors je résume !
Chaque processus possède sa propre LDT qui contient 4 segments :
- NULL (je pense que c'est pas obligé pour une LDT...)
- Code User
- Data User
- Stack User

Un processus est aussi caracterise par un TSS dont le descripteur doit
se trouver forcement dans la GDT (impossible dans LDT).
Une LDT doit avoir un descripteur dans la GDT pour la décrire donc...
De ce fait un processus dans la GDT correspond à un descripteur pour
sa LDT et un autre pour son TSS.

La GDT est definie comme ceci :
- NULL
- Code Noyau
- Data Noyau
- Kernel NOyau
- LDT proc0
- TSS proc0
- LDT proc1
- TSS proc1
etc....

J'ai utilise le système d'SOS pour inserer des binaires ELF dans mon
binaire du Kernel.
J'ai donc repris vos fonctions pour retrouver ce binaire dans mon Noyau.

Maintenant voila le probleme :
Je souhaite passer la main a un thread (en mode noyau pour l'instant...).
Plusieurs choses à faire ;
- Cree 2 nouvelles entrees dans la GDT (LDT & TSS)
- Definir la LDT (4 descripteurs de segment)

Une fois que tout les descripteurs sont mis en place, je fais pointer
le register TR vers l'entree du descripteur de TSS dans la GDT et le
registre LDTR vers l'entree du descripteur de LDT dans la GDT.
Aucune erreur de la part de bochs, les registers sont ok et se
chargent parfaitement.
Grace au mode debug j'ai pu verifier que mes nouvelles entrees dans la
GDT etaient bien considere comme descripteur de LDT & TSS.
Jusque la il ne se passe rien de different, pour effectuer une action
de "task_switching" il faut passer par un call ou jmp.

Et c'est la que je bloque... Voila mon code pour changer de contexte :
__asm__
       ("movw $0x14,%ax \n \
         movw %ax, %ds \n \
         movw %ax, %es \n \
         movw %ax, %fs \n \
         movw %ax, %gs \n \
         movw $0x1C,%ax \n \
         movw %ax, %ss \n \
         movl $0xFFFFFF,%esp \n \
         nop \n \
	 nop \n \
         ljmp $0x30,$0x18");

Je donne au register de selecteur de segment de donnee 0x14 qui
correspond au segment de donnee dans la LDT.
Pout SS il s'agit de 0x1C qui est le descripteur de segment de pile.
Maintenant il ne reste plus qu'a modifier CS & EIP. Et ça je n'y arrive pas.
ljmp $0x30 signifie que je souhaite passer au processus caracterise
par la TSS ou son entree est 0x30 dans la GDT. L'entree existe ! Et
bochs me le confirme !
Ensuite le $0x18 dans le jump est juste l'offset dans le segment de
code... (header ELF à sauter).
Voila ce que me renvoit Bochs :

Event type: PANIC
Device: [CPU  ]
Message: task_switch: CS NULL

CS NULL ?
Je pensais que c etait la valeur du champ CS dans mon TSS, mais non
mon TSS est bien initialisé et contient la valeur qu'il faut. Pourtant
lorsque je fais : info tss sous debug de bochs tout les champs sont à
zéro alors qu'ils ne devraient pas !
Alors que le register TR qui contient le selecteur vers le TSS
contient la bonne valeur, et pointe donc de ce fait vers le TSS
souhaite qui devrait contenir des valeurs et qui les contient en
memoire réellement ! Alors je ne comprend pas trop pour bochs me
renvoit un tss null quand je fais info tss...
De plus on peut faire info gdt 4 sous bochs pour avoir les
informations de la 4ème entrée de la GDT, mais pour la LDT il indique
que c'est pas implémenté, ça aide vraiment pas ça :(
Merci a ceux qui auront des petites idées !
Je veux bien vous donner du code, mais y en a pas mal et je doute que
vous aurais la foi de le regarder et l'assimiler ! :D
A bientot !
-- 
KAISER Edouard.
Wiki-Blog : http://kaiser.edouard.free.fr/
BesOS : http://besos.mtp.epsi.fr/


Plus d'informations sur la liste de diffusion Sos