Bonjour,
Pour mon projet tuteuré de DUT, j'ai besoin de démarrer un PC (n'importe quel processeur à partir du Pentium) sur un programme directement (c'est à dire sans Windows et de préférence sans Dos) pour gérer la surveillance des entrées sorties d'un automate programmable industriel par le biais d'une carte PCI.
L'automate est cablé, j'accède à la carte PCI et je lis et modifie l'état de mon automate sans problème grâce à des petits programmes de test que j'ai écrit (en démarrant le PC sans Dos et sans Windows, les programmes se comportent donc un peu comme un OS, sauf qu'ils ne permettent de rien faire d'autre).
Là où çà se corse, c'est quand je passe en Pmode, ce qui ce fait sans trop de difficultés. Le passage en pmode me permet de bénéficier du multi-tâche, me permettant ainsi de diviser le programme en plusieurs parties:
1. Scheduler de tâches, gestionnaire d'IRQ/ de mémoire, etc...
2. Les pilotes de bus
3. Les pilotes clavier/VGA/disquette/carte de communication à l'automate
4. Le programme en lui-même
Cette organisation me permet de modifier l'une des parties sans toucher aux autres, de plus, çà me permet de documenter séparément chaque partie (ce qui fait partie de mon cahier des charges).
Pour commencer en pmode, juste après le passage en pmode, j'initialise mes sélecteurs de segment, mon pointeur de pile de la manière suivante:
cli
masquage des ints au niveau des pics
Gate A20 à 1 par le contrôleur clavier
Gdt_ptr:
addresse de le GDT
longueur de la GDT: 0x18
GDT:
-descripteur 0x00: à 0 (cf doc Intel)
-descripteur 0x08: code lisible, exécutable, 'non conforming' (cf doc Intel), 32 bits, addresse de base: 0x0000 0000, addresse haute: 0xFFFF FFFF, ring 0, segment de 4Go
-descripteur 0x10: données lisibles, écriture autorisées, 'expand-up' (expansion vers le haut), 32 bits, addresse de base: 0x0000 0000, addresse haute: 0xFFFF FFFF, ring 0, segment de 4Go
Le modèle mémoire est donc de type flat.
Chargement du registre GDTR avec Gdt_ptr
Passage du bit 0 du registre CR0 à 1 (passage effectif en pmode)
short jump vers (sans code ni données entre la mise à 1 du bit 0 de CR0, cf doc Intel):
mov ax, 0x10
mov ds, ax
mov es, ax
mov fs, ax
mov ss, ax
mov sp, 0x10000
nouveau short jump vers (sans code entre le mov sp et le code suivant):
chargement du registre IDTR avec idt_ptr
démasque des ints au niveau des pics
sti
idt_ptr:
addresse de l'IDT
longueur de l'IDT: 256*32
IDT:
toutes les entrées sont initialisées en 'Interrupt Gate' avec l'adresse d'un IRQ Handler de test (il affiche un 'A' dans le coin supérieur gauche de l'écran puis iret) dans mon segment de code (pas de pb de ce côté à mon avis)
Ce n'est ici qu'un pseudo-code visant à expliquer au mieux le fonctionnement de mon code, et j'espère que c'est assez clair, sinon, dites le moi.
Voici le problème:
impossible de faire un far jump, impossible aussi de déclencher une interruption ni matérielle ni logicielle.
impossible aussi le lire quelque chose en faisant référence à cs de manière répétée (par exemple, impossible de faire: mov ax, word [cs:esi] - sous Fasm).
Sous VmWare, j'ai une erreur de pile, puis reset. Sur un vrai PC, reset direct (l'erreur de pile doit se faire aussi)
En fait, je pense que l'erreur de pile se produit, provoquant une exception, nécessitanbt le traitement par la biais de l'IRQ Handler, mais il est inaccessible car il provoque lui aussi une erreur de pile, ce qui provoque une triple fault et donc un reset hard du processeur et le redémarrage du Bios.
Je ne vois pas trop où est le soucis, si quelqu'un pouvait m'éclairer, ce serait vraiment génial (çà m'éviterait de me taper une sale note en projet tuteuré... pour çà, il faudrait que çà marche).
Merci d'avance (et désolé pour la taille de ce post !)