Je suis actuellement en train de développer un noyau et de rencontrer un problème mystérieux lors de l'implémentation de l'appel système. Je vous écris le gestionnaire d'interruption 0x80th comme ceci:comportement étrange dans le gestionnaire d'interruptions
sys_call_s:
pushad
call sys_call
popad
iret
« sys_call » est le nom de la fonction C qui font le vrai travail. Le problème est: J'ai une triple erreur lors de l'exécution de l'instruction suivante de "int 0x80". Par exemple, j'ai une erreur lors de l'exécution de la troisième ligne du programme ci-dessous et finalement les bochs vont se réinitialiser.
abc: mov eax,0 ; 0 means system call get_pid()
int 0x80
mov [pid_father],eax ; this is the instruction caused bochs to triple fault
mov eax,1 ; 1: fork()
int 0x80
jmp $
pid_father: dd 0
Encore plus strangly, quand je remplace l'instruction "IRET" avec "ret", le programme fonctionne très bien et se tourner à "jmp $".
Est-ce que quelqu'un a une idée de pourquoi j'ai eu ce problème?
[edit] Maintenant, je pense que ce problème est causé par la mauvaise adresse du pointeur de la pile. J'ai mappé une page pour ce processus, l'adresse physique de cette page est 0x401000, l'adresse linéaire est 0x800000 (8M). J'ai placé le pointeur de pile de ce processus à 0x800ff0, mais chaque fois que j'utilise la commande "d'impression-pile" dans des bochs la sortie est: "l'adresse physique n'est pas disponible pour linéaire 0x00801000". Comment puis-je le réparer?
[edit] Maintenant j'ai trouvé que je ne peux pas accéder aux données dans ce processus. par exemple quand je place "mov [pid_father], eax" avant "int 0x80", bochs se réinitialise. pourquoi c'est arrivé?
Merci pour vos conseils, Stewart. –
Le problème se localise dans la table de pages. Je n'ai pas défini l'indicateur inscriptible dans l'entrée de la table de pages correspondante. Donc, chaque fois que j'écris sur cette page, j'ai une erreur de protection. Lors de l'utilisation de l'instruction "ret" pour revenir du gestionnaire d'interruption, le sélecteur du segment de code est 0x10 qui est le sélecteur de code du noyau et le code de ce segment a droit à l'accès en lecture/écriture à n'importe quelle page. Ceci explique pourquoi le premier processus survient juste après avoir remplacé l'instruction "iret" par "ret". –
Vraiment? Je pensais que la protection de page outrepassait la protection du sélecteur, de sorte que si les tables de pages sont marquées en lecture seule, la page est en lecture seule quel que soit le segment de code en cours. BTW - vous n'avez pas mentionné que vous avez activé la pagination. Cela aurait été utile à mentionner. – Stewart