[SOS] Multi-Tasking - TSS

KAISER Edouard edouard.kaiser at gmail.com
Mer 28 Sep 00:52:25 CEST 2005


Décidemment moi qui pensait qu'éxécuter un segment de code avec un
DPL=3 serait un jeu d'enfant aprés avoir réussi a faire un changement
de contexte vers un segment de code de DPL=0, je me suis bien mis le
doigt dans l'oeil.

En fait le probleme vient de l'interruption software que j'ai mis en place.

Le userprogram qui s'execute dans un segment de DPL=3 effectue
volontairement une interruption logicielle pour tester un peu si c'est
donc possible de passer en mode noyau, executer cette interruption qui
affiche betement un message et repasser en mode user pour continuer
l'execution du programme en DPL=3.

Premièrement je me suis dis qu'il fallait passer le DPL du descripteur
correspondant dans l'IDT à 3, cela me semble logique sinon on va lever
une exception "General Protection".
Donc rien de bien compliquer finalement en ce qui concerne cette
entree dans l'IDT qui est caracterise par l'offset de ma fonction, le
selecteur de descripteur de segment de code du mode noyau (0x08) et le
fameux DPL=3, c'est une "Interrupt Gate".

Je me suis dis, ok le tour est jouée, ça devrait fonctionner.

Et bien non ! C'est pas si facile il semblerait :D

J'ai un resultat qui me semble completement dingue selon ma logique,
je vais vous expliquer :D

Voila le code de ma "software interruption" :

 _sys_call:
        push %ds
	push %es
	push %fs
	mov $0x10,%edx /* Selecteur du descripteur de donne du noyau dans la GDT */
	mov %dx,%ds
	mov %dx,%es
    call sys_call
	pop %fs         /* On replace les segments donnes du user mode */
	pop %es
	pop %ds
    iret

Comme vous le voyez elle se contente juste de sauvegarder quelques
registres, de donner le selecteur des donnees du mode noyau. Appeller
ma fonction C et retablir les registres de selecteur de donnees.
CS, EIP & EFLAGS sont remis en place par IRET.

Aprés plusieurs heures de session de debug sous Bochs ! Je ne
comprends toujours pas pourquoi lorsque l'OS rentre dans cette routine
ASM  "_sys_call" il y rentre avec un CS=0xB
Ce qui donne en binaire si je ne me trompe pas :
0x1011
Ce qui correspond donc au premier descripteur dans GDT (le code,
parfait !), mais avec un RPL=3 ??? (deux bits de poids faibles=1 dans
le selecteur).
Alors la je ne comprends pas, car mon descripteur d'Interrupte Gate
dans l'IDT a evidemment un DPL=3 mais c'est pour donner la possibilite
d'etre appellé par un segment code en DPL=3.
Le selecteur de segment de code dans cette entree de l'IDT est quand à
lui bien positionne sur 0x08, ce qui correspond au code Noyau dans la
GDT avec bien un RPL=00.

Le processeur n'est il pas sensé positionner CS avec justement le
selecteur contenu dans cette entrée de l'IDT ?

Donc forcement quand ma routine ASM essaye de modifier DS, ES et FS
bochs m'envoit peter avec :

load_seg_reg: RPL & CPL must be <= DPL

Je ne comprend meme pas comment je peux deja executer du code avec
CS=0xB dans ce segment qui a un DPL=0.
Car les instructions push de %ds, %es, %fs s'éxécutent car je retrouve
les selecteurs sur la pile en faisant "print-stack" sous Bochs.

Voila un peu tout ce que j'ai remarqué sans comprendre pourquoi je me
choppe 0x0B dans CS au lieu de 0x08.

Je me suis dis que j'ai peut etre raté une étape dans le "software
interrupt" mais que c'est tellement gros que ça m'a échapé.

Quelqun veut un tarball ? :D

Merci à ceux qui auront quelques pistes ;)
--
KAISER Edouard.
Wiki-Blog : http://kaiser.edouard.free.fr/
BesOS : http://besos.mtp.epsi.fr/


Plus d'informations sur la liste de diffusion Sos