[SOS] Problème avec l'appel des handlers d'interruptions

Thomas Petazzoni thomas.petazzoni at enix.org
Mar 31 Oct 20:46:32 CET 2006


Salut,

[ Désolé de la réponse vraiment trop tardive. ]

Le Sat, 30 Sep 2006 12:33:39 +0200,
Nicolas Martyanoff <khaelin at gmail.com> a écrit :

> 00023337025e[CPU0 ] exception(): 3rd (13) exception with no
> resolution, shutdown status is 00h, resetting

C'est effectivement une triple fault. Ça veut dire que tu as une erreur
dans un gestionnaire d'interruption qui déclenche à nouveau une
interruption, qui déclenche à nouveau une interruption. Et donc boum.

J'ai récupéré et compilé ton code, mais dans Qemu, ça ne fait rien:
j'ai «Booting from floppy» qui s'affiche à l'infini dans la fenêtre de
Qemu. Ça fait ça aussi chez toi ? Ou alors peut-être as-tu changé ce
qu'il y a dans le tarball depuis que tu as envoyé ce mail ?

> Mais j'ai beau cherché, pas moyen de trouvé d'où ça peut venir.

Si tu me donnes une version des sources qui permettent de reproduire le
problème, je pourrais essayer de regarder.

> #define OSB_DISABLE_IRQ(flags) \
>    { OSB_SAVE_FLAGS(flags); asm("cli\n"); }
> 
> Utilise cli, or votre macro qui restaure les interruptions n'utilise
> pas sti pour les restaurer. j'ai essayé de faire ceci:

Le principe est que la macro sos_disable_IRQs() sauvegarde les
"flags" (le contenu du registre EFLAGS, qui contient notamment un
drapeau indiquant si les interruptions sont activées ou non) puis
désactive les interruptions. Ensuite, la macro sos_restore_IRQs()
repositionne le registre EFLAGS à sa valeur au moment du
sos_disable_IRQs(). Donc si au moment du sos_disable_IRQs() les
interruptions étaient activées, elles sont activées de nouveau. Et si
elles n'étaient pas activées au moment du sos_disable_IRQs(), alors
elles restent désactivées.

> #define OSB_RESTORE_IRQ(flags) \
>    { OSB_RESTORE_FLAGS(flags); asm("sti\n"); } 

Avec une telle macro, tu vas réactiver les interruptions même si elles
étaient désactivées lors du OSB_DISABLE_IRQ(). Ça peut être
dangereux ;-)

> Mais cela ne change rien. J'ai également essayé sans, et mêmes
> symptômes.

Ce n'est pas visible directement. Mais si tu as des interruptions
activées à un moment où tu t'attends à ce qu'elles soient désactivées,
tu auras des jolies surprises assez chiantes à débugger (race
conditions et autres subtilités passionnantes).

> - SoS traite séparément exceptions et IRQ, or le code est presque
> identique (un peu normal, les deux sont des interruptions). Pourquoi
> ne pas avoir factorisé cette gestion ? Je n'ai pas encore les idées
> claires concernant l'archi d'un OS, attendant d'avoir terminé les
> articles SOS pour recommencer en innovant, mais ça me parait un peu
> «cradingue» (n'y voyez pas une critique, juste une question :));

Si tu regardes bien le code de traitement des IRQs, il n'est pas
exactement identique: il gère un compteur sos_irq_nested_level_counter
et il s'occupe d'acquitter l'interruption auprès du PIC.

Ceci dit, c'est vrai que le code est assez similaire. On aurait pu le
factoriser, et faire des if() là où il faut. Le choix de la duplication
a sans doute été motivé par le fait que nous voulions bien distinguer
le traitement des différents type d'interruptions.

> - Le système wrappers/handlers pour les interruptions à l'avantage
> d'être propre, mais si j'ai bien compris, on perd le code erreur de
> certaines exceptions qui est dégagé par les routines assemblers, non ?

Non, le code d'erreur est conservé. Regarde le fichier
exception_wrappers.S, il est en deux parties. La première partie pour
les exceptions qui ne donnent pas de code d'erreur (on pushe 0 sur la
pile pour remplacer le code d'erreur). La deuxième partie pour les
exceptions qui donnent un code d'erreur (on ne pushe pas 0, on garde le
code d'erreur fourni par le processeur).

> En réalité, je ne comprend pas vraiment l'intérêt d'avoir des handlers
> configurables, il m'aurait paru plus simple de coder directement une
> fonction par interruption, ce qui aurait évité le code asm (qui
> utilise des macros gas, ce qui est moyen pour la portabilité (objectif
> personnel, avoir un OS, y coder un compilateur/assembleur/linker
> maison qui puisse recompiler l'OS en question, oui je sais je suis un
> malade :p) et aurait peut-être était plus propre. De plus, ça ne
> change que peu de chose, car il faudra de tte manière un handler pour
> à peu près toutes les interruptions.

Hum, le code assembleur me paraît difficile à éviter: il faut bien
sauvegarder/restaurer les registres. Et si tu fais ça en C, ton
compilateur va générer du code qui risque de toucher au registre avant
même de t'avoir donné la possibilité de sauvegarder leur valeur.

As-tu un exemple de code avec des gestionnaires d'interruption
intégralement en C ?

Bonne soirée,

Thomas
-- 
PETAZZONI Thomas - thomas.petazzoni at enix.org 
http://{thomas,sos,kos}.enix.org - Jabber: thomas.petazzoni at jabber.dk
http://{agenda,livret}dulibre.org - http://www.toulibre.org
Fingerprint : 0BE1 4CF3 CEA4 AC9D CC6E  1624 F653 CB30 98D3 F7A7
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 189 bytes
Desc: not available
Url : http://the-doors.enix.org/pipermail/sos/attachments/20061031/89d4ec9d/signature.pgp


Plus d'informations sur la liste de diffusion Sos