linux中断处理函数参数,第9章 设置ISR(中断处理函数)
中斷處理有三個階段
進入階段:棧保存(帶出錯碼的中斷、不帶出錯碼的中斷)
處理階段:中斷處理
退出階段:恢復棧
80×86中有特權級的概念,不同的特權級有不同的棧,所以中斷發生時要保存中斷前的棧地址。
查看intel使用手冊
interrupt.s源代碼文件(參考linux 0.11源代碼)
.global divide_error,debug_exception,nmi,breakpoint,overflow,bound,invalid_opcode
.global coprocessor_not_available,double_fault,coprocessor_segment_overrun,invalid_tss
.global segment_not_present,stack_exception,protection_exception,page_fault
.global intel_reserved,coprecessor_error,default_isr,timer
.include "kernel.inc"
divide_error:
pushl $do_divide_error
no_error_code:
xchgl %eax, (%esp) # &function-> %eax, 原%eax放到棧中
pushl %ebx
pushl %ecx
pushl %edx
pushl %edi
pushl %esi
pushl %ebp
push %ds
push %es
push %fs
pushl $0 # 填充錯誤碼,作為中斷處理函數的參數
lea 52(%esp), %edx #當前堆棧地址加上52后,放到edx中
pushl %edx #壓edx入棧,這樣中斷處理函數就能獲取到被壓入棧的寄存器的值
movl $DATA_SEL, %edx
mov %dx, %ds
mov %dx, %es
mov %dx, %fs
call *%eax #調用中斷處理函數
addl $8, %esp
pop %fs
pop %es
pop %ds
popl %ebp
popl %esi
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax
iret
invalid_tss:
pushl $do_invalid_tss
error_code:
xchgl %eax, 4(%esp) # error code -> %eax, 原eax放到棧中
xchgl %ebx, (%esp) # &function -> %ebx,原ebx放到棧中
pushl %ecx
pushl %edx
pushl %edi
pushl %esi
pushl %ebp
pushl %ds
pushl %es
pushl %fs
pushl %eax # 壓入錯誤碼,作為中斷處理函數的參數
lea 52(%esp), %eax # 當前堆棧地址加上52后,放到eax中
pushl %eax # 壓eax入棧,這樣中斷處理函數就能獲取到被壓入棧的寄存器的值
movl $DATA_SEL, %eax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
call *%ebx
addl $8, %esp
pop %fs
pop %es
pop %ds
popl %ebp
popl %esi
popl %edi
popl %edx
popl %ecx
popl %ebx
popl %eax
iret
debug_exception:
pushl $do_debug_exception
jmp no_error_code
nmi:
pushl $do_nmi
jmp no_error_code
breakpoint:
pushl $do_breakpoint
jmp no_error_code
overflow:
pushl $do_overflow
jmp no_error_code
bound:
pushl $do_bound
jmp no_error_code
invalid_opcode:
pushl $do_invalid_opcode
jmp no_error_code
coprocessor_not_available:
pushl $do_coprocessor_not_available
jmp no_error_code
coprocessor_segment_overrun:
pushl $do_coprocessor_segment_overrun
jmp no_error_code
intel_reserved:
pushl $do_intel_reserved
jmp no_error_code
coprecessor_error:
pushl $do_coprocessor_error
jmp no_error_code
timer:
pushl $do_timer
jmp no_error_code
double_fault:
pushl $do_double_fault
jmp error_code
invaild_tss:
pushl $do_invalid_tss
jmp error_code
segment_not_present:
pushl $do_segment_not_present
jmp error_code
stack_exception:
pushl $do_stack_exception
jmp error_code
protection_exception:
pushl $do_protection_exception
jmp error_code
page_fault:
pushl $do_page_fault
jmp error_code
default_isr:
pushl $do_default_isr
jmp no_error_code
interrupt.h源代碼文件
#ifndef _INTERRUPT_H_
#define _INTERRUPT_H_
//在中斷處理函數中,每個寄存器在棧中的下標
#define OLD_SS_REG 2
#define OLD_ESP_REG 1
#define OLD_EFLAGS_REG 0
#define OLD_CS_REG -1
#define OLD_EIP_REG -2
#define EAX_REG -3
#define EBX_REG -4
#define ECX_REG -5
#define EDX_REG -6
#define EDI_REG -7
#define ESI_REG -8
#define EBP_REG -9
#define DS_REG -10
#define ES_REG -11
#define FS_REG -12
extern void default_isr(void); //該函數定義在idt.c文件中
extern void divide_error(void);
extern void debug_exception(void);
extern void nmi(void);
extern void breakpoint(void);
extern void overflow(void);
extern void bound(void);
extern void invalid_opcode(void);
extern void coprocessor_not_available(void);
extern void double_fault(void);
extern void coprocessor_segment_overrun(void);
extern void invalid_tss(void);
extern void segment_not_present(void);
extern void stack_exception(void);
extern void protection_exception(void);
extern void page_fault(void);
extern void intel_reserved(void);
extern void coprecessor_error(void);
extern void timer(void);
extern void sys_call(void);
#endif
總結
以上是生活随笔為你收集整理的linux中断处理函数参数,第9章 设置ISR(中断处理函数)的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: linux asm 磁盘管理,asm磁盘
- 下一篇: linux lynx 源码,Linux
