中断处理程序中的奇怪行为

时间:2013-05-05 04:16:52

标签: c kernel interrupt-handling osdev

我正在开发内核并在实现系统调用时遇到一个神秘的问题。我像这样编写0x80th中断处理程序:

sys_call_s:
    pushad
    call sys_call
    popad
    iret

“sys_call”是执行实际工作的C函数的名称。问题是:执行“int 0x80”的下一条指令时遇到三重错误。例如,我在执行下面程序的第三行时遇到了错误,最后bochs会自行重置。

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

更扼要的是,当我用“ret”替换“iret”指令时,程序运行正常,并以“jmp $”旋转。

有谁知道我为什么会遇到这个问题?

[edit]现在我认为这个问题是由堆栈指针的错误地址引起的。我为这个过程添加了一个页面,这个页面的物理地址是0x401000,线性地址是0x800000(8M)。我已将此进程的堆栈指针设置为0x800ff0,但每次在bochs中使用“print-stack”命令时,输出为:“物理地址不可用于线性0x00801000”。我该如何解决?

[edit]现在我发现在这个过程中我无法访问数据。例如,当我在“int 0x80”之前放置“mov [pid_father],eax”时,bochs重置自己。为什么会这样?

1 个答案:

答案 0 :(得分:1)

我认为您需要显示GDT和DS寄存器和分页表的内容。如果您在没有任何其余代码的情况下看到该行上的三重错误,那么这意味着访问[pid_father]是个问题。数据段无效,或页面无效或标记为只读,这会导致GPF或页面错误异常。 GPF或页面错误异常失败(可能是出于同样的原因,或者是另一个原因),这会导致双重故障异常,再次失败导致CPU出现三重故障并重置。

Bochs通常很好(从记忆中)打印出它出现故障的原因。您可能需要稍微向上滚动历史记录并查找引发的第一个异常。