x86中断服务例程导致一般保护故障



我的通用isr存根定义为:

isr_common_stub:
pusha                    ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
mov ax, ds               ; Lower 16-bits of eax = ds.
push eax                 ; save the data segment descriptor
mov ax, 0x10  ; load the kernel data segment descriptor
mov ds, ax
mov es, ax
mov fs, ax
mov gs, ax
call isr_handler
;call saySomething
pop ebx        ; reload the original data segment descriptor
mov ds, bx
mov es, bx
mov fs, bx
mov gs, bx
;call saySomething
popa                     ; Pops edi,esi,ebp...
;add esp, 8     ; Cleans up the pushed error code and pushed ISR number
;sti
;call saySomething
;iret           ; pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP
ret ;Return to the caller. Iret and interrupt enabling is handled within caller.

此代码从每个中断调用如下:

%macro ISR_NOERRCODE 1
global isr%1
isr%1:
   cli                         ; Disable interrupts firstly.
   push byte 0                 ; Push a dummy error code.
   push byte %1                ; Push the interrupt number.
   jmp isr_common_stub         ; Go to our common handler code.
   sub esp, 2 ;Removes 2 bytes from stack
   ;sti ;Iret enables interrupts again
   iret ;Return from interrupt
%endmacro

此代码适当地调用外部处理方法,但从外部处理方法返回后会导致gpf中断。

此外,我还映射了我的gdt,以覆盖整个4G地址空间,其中包含0特权级别的数据和代码描述符(以及空描述符)。感谢您的帮助。

开始。。。

a) 在宏中,执行cli是愚蠢的。使用"中断门"(而不是"陷阱门"),CPU将自动为您禁用IRQ,而不会出现竞争条件的风险(例如,IRQ在中断处理程序启动后,但在它完成执行cli之前)。

b) 在宏中,jmp之后的代码从不执行,因此毫无意义。

c) 如果你把2个字节推到堆栈上,那么你就把堆栈对齐搞砸了,应该受到性能惩罚。推送2个双字可以避免这种情况。

d) CPU为某些异常提供32位错误代码;因此,您的伪错误代码也应该是32位的。

e) 您没有向ISR传递任何信息。大多数异常处理程序都需要知道异常发生时通用寄存器等的状态。

f) 您不能期望ret从中断返回,并且需要取消对iret的注释。

g) 丢弃所有段寄存器(DS、ES、FS、GS)可能是个坏主意。要么操作系统将它们视为常量,您没有理由在从ISR返回之前加载它们,要么必须保存它们,然后正确重新加载。

h) 不同的异常有不同的要求,所以使用"通用异常处理程序"是愚蠢的。最好为不同的异常提供不同的异常处理程序,这就是IDT所提供的(在这种情况下,在堆栈上推送"中断号"是没有意义的)。

j) IRQ不同于例外情况。对于IRQ,中断处理程序从不需要无意义的错误代码(或中断代码的状态)。请注意,在汇编存根中处理/隐藏PIC芯片的"伪IRQ"是很好的,这意味着检查PIC的"服务中寄存器",以区分真实IRQ7和伪IRQ7之间的差异,以及真实IRQ15和伪IRQ15之间的差异。对于伪造的IRQ15,你需要将EOI发送到主设备,而不是从设备,对于伪造的IRC7,你根本不能发送任何EOI。如果您使用IO APIC,那么没有合理的方法来禁用/屏蔽PIC芯片的虚假IRQ,因此您仍然需要两个PIC芯片的伪IRQ处理程序(除了APIC自己的虚假中断的处理程序)。

相关内容

  • 没有找到相关文章

最新更新