Chinaunix首页 | 论坛 | 博客
  • 博客访问: 216728
  • 博文数量: 86
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 256
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-12 15:39
文章分类

全部博文(86)

文章存档

2016年(20)

2015年(65)

2014年(1)

我的朋友

分类: LINUX

2015-07-08 12:01:06

转自: http://blog.csdn.net/h_armony/article/details/9936283

中断在linux驱动中占有很重要的地位,所以也一定要好好分析一下。还是一样的套路,先讲一下基本的概念,然后分析源码再来加深理解。

中断门与其他三个门(调用门、陷阱门、任务门)一起是操作系统里的四扇门。它们之间的区别以后再补充,今天重点分析中断门。

那么什么是门呢?门其实就是一中描述符,直观来看这个描述符描述了由一个选择子和一个偏移所指定的线性地址,程序正是通过这个地址进行转移的。中断描述符放在中断描述符表里(IDT),也就是这个IDT将中断向量和中断服务程序联系起来,他们之间的关系如下图:

那中断向量怎么来得呢,其实每一种中断(异常)都会对应一个中断向量号,具体有哪些中断向量,可以看下面这张图:


向量号 助记符 描述 类型 出错码
0 #DE 除法错 Fault DIV和IDIV指令
1 #DB 调试异常 Fault/Trap 任何代码和数据的访问
2 非屏蔽中断 Interrupt 非屏蔽外部中断
3 #BP 调试断点 Trap 指令INT 3
4 #OF 溢出 Trap 指令INTO
5 #BR 越界 Fault 指令BOUND
6 #UD 无效(未定义)操作码 Fault 指令UD2或无效指令
7 #NM 设备不可用(无数学协处理器) Fault 浮点或WAIT/FWAIT指令
8 #DF 双重错误 Abort 有(0) 所有能产生异常或NMI或INTR
的指令
9   协处理器段越界(保留) Fault 浮点指令(386后不再处理此
异常)
10 #TS 无效TSS Fault 任务切换或访问TSS时
11 #NP 段不存在 Fault 加载段寄存器或访问系统段时
12 #SS 堆栈段错误 Fault 堆栈操作或加载SS时
13 #GP 常规保护错误 Fault 内存或其他保护检验
14 #PF 页错误 Fault 内存访问
15 Intel保留,未使用      
16 #MF x87FPU浮点错(数学错) Fault x87FPU浮点指令或WAIT/FWAIT指令
17 #AC 对齐检验 Fault 有(0) 内存中的数据访问(486开始支持)
18 #MC Machine Check Abort 错误码(若有的话)和源依赖于
具体模式(奔腾CPU开始支持)
19 #XF SIMD浮点异常 Fault SSE和SSE2浮点指令(奔腾三
开始支持)
20~31 Inter保留,未使用      
32~255 用户定义中断 Interrupt   外部中断或int n指令


上图中除了两个Interrupt(中断)外,其他还有三种Fault、Trap、Abort异常。我们这里讨论的中断主要是用户定义中断,这种中断产生的原因有两种:一是外部中断,就是由硬件产生的中断;另一种是由指令int n产生的中断。

通过指令int n产生中断的情形如第一张图所示,这有点像调用门的适用。

外部中断的情况则复杂一些,因为需要建立硬件中断和向量号之间的对应关系。外部中断的简单示意图如下:

通过对8259A的配置,可将IRQ0~IRQ7对应到中断向量20h~27h,同样地IRQ8~IRQ15可对应到中断向量28h~2Fh。具体初始化配置代码就不进行分析了。



  1. ; IDT  
  2. [SECTION .idt]                                                      ;sect.idt #show#-->  
  3. ALIGN   32  
  4. [BITS   32]  
  5. LABEL_IDT:  
  6. ; 门                        目标选择子,            偏移, DCount, 属性  
  7. %rep 32  
  8.         Gate    SelectorCode32, SpuriousHandler,      0, DA_386IGate  
  9. %endrep  
  10. .020h:      Gate    SelectorCode32,    ClockHandler,      0, DA_386IGate  
  11. %rep 95  
  12.         Gate    SelectorCode32, SpuriousHandler,      0, DA_386IGate  
  13. %endrep  
  14. .080h:      Gate    SelectorCode32,  UserIntHandler,      0, DA_386IGate  
  15.   
  16. IdtLen      equ $ - LABEL_IDT  
  17. IdtPtr      dw  IdtLen - 1  ; 段界限  
  18.         dd  0       ; 基地址  
  19. ; END of [SECTION .idt]   
  20.   
  21.   
  22. [SECTION .s16]  
  23. [BITS   16]  
  24. LABEL_BEGIN:  
  25.     ; 为加载 IDTR 作准备  
  26.     xor eax, eax  
  27.     mov ax, ds  
  28.     shl eax, 4  
  29.     add eax, LABEL_IDT      ; eax <- idt 基地址  
  30.     mov dword [IdtPtr + 2], eax ; [IdtPtr + 2] <- idt 基地址  
  31.   
  32.     ; 保存 IDTR  
  33.     sidt    [_SavedIDTR]  
  34.   
  35.     ; 保存中断屏蔽寄存器(IMREG)值  
  36.     in  al, 21h  
  37.     mov [_SavedIMREG], al  
  38.   
  39.     ; 加载 GDTR  
  40.     lgdt    [GdtPtr]  
  41.   
  42.     ; 关中断  
  43.     ;cli  
  44.   
  45.     ; 加载 IDTR  
  46.     lidt    [IdtPtr]  
  47.     ; 打开地址线A20  
  48.     in  al, 92h  
  49.     or  al, 00000010b  
  50.     out 92h, al  
  51.   
  52.     ; 准备切换到保护模式  
  53.     mov eax, cr0  
  54.     or  eax, 1  
  55.     mov cr0, eax  
  56.   
  57.     ; 真正进入保护模式  
  58.     jmp dword SelectorCode32:0  ; 执行这一句会把 SelectorCode32 装入 cs, 并跳转到 Code32Selector:0  处  
  59.   
  60. ; Init8259A ---------------------------------------------------------------------------------------------  
  61. Init8259A:  
  62.     mov al, 011h  
  63.     out 020h, al    ; 主8259, ICW1.  
  64.     call    io_delay  
  65.   
  66.     out 0A0h, al    ; 从8259, ICW1.  
  67.     call    io_delay  
  68.   
  69.     mov al, 020h    ; IRQ0 对应中断向量 0x20  
  70.     out 021h, al    ; 主8259, ICW2.  
  71.     call    io_delay  
  72.   
  73.     mov al, 028h    ; IRQ8 对应中断向量 0x28  
  74.     out 0A1h, al    ; 从8259, ICW2.  
  75.     call    io_delay  
  76.   
  77.     mov al, 004h    ; IR2 对应从8259  
  78.     out 021h, al    ; 主8259, ICW3.  
  79.     call    io_delay  
  80.   
  81.     mov al, 002h    ; 对应主8259的 IR2  
  82.     out 0A1h, al    ; 从8259, ICW3.  
  83.     call    io_delay  
  84.   
  85.     mov al, 001h  
  86.     out 021h, al    ; 主8259, ICW4.  
  87.     call    io_delay  
  88.   
  89.     out 0A1h, al    ; 从8259, ICW4.  
  90.     call    io_delay  
  91.   
  92.     ;mov    al, 11111111b   ; 屏蔽主8259所有中断  
  93.     mov al, 11111110b   ; 仅仅开启定时器中断                       
  94.     out 021h, al    ; 主8259, OCW1.  
  95.     call    io_delay  
  96.   
  97.     mov al, 11111111b   ; 屏蔽从8259所有中断  
  98.     out 0A1h, al    ; 从8259, OCW1.  
  99.     call    io_delay  
  100.   
  101.     ret                                                       
  102. ; Init8259A ---------------------------------------------------------------------------------------------  
  103.   
  104.   
  105. LABEL_SEG_CODE32:  
  106.     mov ax, SelectorData  
  107.     mov ds, ax          ; 数据段选择子  
  108.     mov es, ax  
  109.     mov ax, SelectorVideo  
  110.     mov gs, ax          ; 视频段选择子  
  111.   
  112.     mov ax, SelectorStack  
  113.     mov ss, ax          ; 堆栈段选择子  
  114.     mov esp, TopOfStack  
  115.   
  116.     call    Init8259A  
  117.   
  118.     int 080h                                                      
  119.     sti  
  120.     jmp $                                                     
  121.   
  122.   
  123. int handler ---------------------------------------------------------------                                                     
  124. _UserIntHandler:  
  125. UserIntHandler  equ _UserIntHandler - $$  
  126.     mov ah, 0Ch             ; 0000: 黑底    1100: 红字  
  127.     mov al, 'I'  
  128.     mov [gs:((80 * 0 + 70) * 2)], ax    ; 屏幕第 0 行, 第 70 列。  
  129.     iretd  
阅读(1042) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~