在系统初始化期间,trap_init()函数将对中断描述符表IDT进行第二次初始化(第一次只是建一张IDT表,让其指向ignore_intr函数),而在这次初始化期间,系统的0~19号中断(用于分NMI和异常的中断向量)均被设置好。与此同时,用于系统调用的0x80号向量也已被设置。

然而,对于外部中断的初始化 却没有在这个函数中进行。而是在函数init_IRQ中。

仔细想一想内核这样做,的确是使代码清晰又有条理。

1)trap_init -----> 内部中断异常和NMI(中断向量号:0~19)

2) init_IRQ   -----> 外部可屏蔽中断  (中断向量号:32~127,129~238)

在init_IRQ函数中,对IDT中断描述符表进行了第三次完善(把相应的外部中断对应的中断向量进行填充)

410 for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {

411 int vector = FIRST_EXTERNAL_VECTOR + i;

412 if (i >= NR_IRQS)

413 break;

414 if (vector != SYSCALL_VECTOR)

415 set_intr_gate(vector, interrupt[i]);

416 }

上述代码解释:

FIRST_EXTERNAL_VECTOR = 0x16;

设置中断向量号32---NR_IRQS相应的中断处理程序地址为数组interrupt[i]的内容。(除去128号中断向量,已经这个向量号已经被用于系统调用)。

我们看一下interrupt数组的定义:这段程序时用汇编写的。

540 .data

541 ENTRY(interrupt)

542 .text

543

544 vector=0

545 ENTRY(irq_entries_start)

546 RING0_INT_FRAME

547 .rept NR_IRQS

548 ALIGN

549 .if vector

550 CFI_ADJUST_CFA_OFFSET -4

551 .endif

552 1: pushl $~(vector)

553 CFI_ADJUST_CFA_OFFSET 4

554 jmp common_interrupt

555 .data

556 .long 1b

557 .text

558 vector=vector+1

559 .endr

上面的代码开起来很乱,我们整理一下,使其更加易读,但是又不失其本质。

.data

ENTRY(interrupt)

.long 1b //注意 如果把数据段放在这里那么1b要改为1f了,而且失去循环执行NR_IRQS次的功能。                     //我们只能人为的把他们想象成被循环执行了NR_IRQS次 :)

.text

vector=0

ENTRY(irq_entries_start)

.rept NR_IRQS

1: pushl $~(vector)

jmp common_interrupt

vector=vector+1

我们把数据段放在一起,代码段放在一起。注意这里的代码段是用来初始化数据段的。

我们看到:interrupt作为一个内存标签,其内容为代码段标号1所表示的地址。同时我们也注意到这个interrupt数组的所有项的内容都是一样的:全部为“标号1”的符号地址。

每次外部中断来临时,硬件自动根据PIC或者APIC送出来的中断类型码(中断向量号)去查找中断描述符表的相应项,然后得到interrupt[n]的内容,继而转去执行标号1地址的代码,而标号1的代码仅将中断号取反后压入栈中,后立马跳到common_interupt标号处去执行。至于为什么要把中断向量号取反后压栈,则是由于内核用正的相应号去表示系统调用号,用负号来表示中断号。

细心的你有可能发现了一个问题:上述代码片段只是向interrupt表示的内存地址处存入大量重复的4字节数据,却没有象C语言定义数组那样定义interrupt[NR_IRQS-1],那么set_intr_gate这样的函数是如何确切的指导interrupt是一个数组呢,而且数组的内容是函数指针?

例如:set_intr_gate(vector,interrupt[i]);是如何取interrupt[i]内容呢?

啰嗦了这么半天...

如下一个声明就搞定了。[])(void);//函数指针数组

566 common_interrupt:

567 SAVE_ALL

568 TRACE_IRQS_OFF

569 movl %esp,%eax

570 call do_IRQ

571 jmp ret_from_intr

572 CFI_ENDPROC

common_interrupt首先执行宏SAVE_ALL保存中断处理程序可能用到的寄存器(注意:cs eip ss esp由硬件自动保存)然后把栈顶指针传给eax寄存器后(eax寄存器内容将作为do_IRQ函数的参数)调用do_IRQ进行中断处理,返回后

执行ret_from_intr从中断返回。

c语言interrupt函数,中断处理函数数组interrupt[]初始化相关推荐

  1. 为什么C语言函数不能返回数组,却可以返回结构体?

    C语言函数为什么不能返回数组? 在C语言程序开发中,我们不可以编写下面这样的代码: char f(void)[8] { char ret; // ...fill... return ret; } in ...

  2. 为什么C语言函数不能返回数组,却可以返回结构体

    C语言函数为什么不能返回数组? 在C语言程序开发中,我们不可以编写下面这样的代码: char f(void[8]{ char ret;// ...fill... return ret; }int ma ...

  3. C语言结构体及函数传递数组參数演示样例

    C语言结构体及函数传递数组參数演示样例 注:makeSphere()函数返回Sphere结构体,main函数中.调用makeSphere()函数,传递的第一个參数为数组,传递的数组作为指针. post ...

  4. c语言不能在函数中求数组大小,C语言中数组长度不能用变量定义吗?

    翻翻过去那场雪 1.C语言中不支持.C++中支持变长数组(你可以自行度娘变长数组和alloca函数),但是因为其实在栈上分配,不被推荐使用.做为解决方案,你可以使用C式的malloc函数或者C++式的 ...

  5. C语言编程基础-10函数形参数组做形参文件操作

    函数形参 被调函数的形参在被调用时临时创建并使用实参对其赋值,故直接修改形参(特殊形式的形参如指针,数组除外)本身只会影响到被调函数内部; 形式参数是在函数调用发生时临时创建出来的,在函数调用结束时又 ...

  6. c语言函数将如何返数组,声明一个C函数返回一个数组

    有几点要指出. 首先,您不能像在这里那样分配数组对象: char A[WIDTH][HEIGHT]; A=rand_grid(WIDTH,HEIGHT); 数组类型的对象不可修改. 其次,C语言中的函 ...

  7. 详解C语言指针函数、函数指针、函数指针数组

    在C语言中,指针是一个很重要但是又很容易弄错的概念,也可以说指针就是C语言的灵魂,所以说学好指针对于完全掌握C语言是一个必须的过程.而在指针中,指针函数.函数指针.指针函数数组.函数指针数组.指向函数 ...

  8. C语言指针的那些事:第三篇(函数指针,指针函数,函数指针数组,指向函数指针数组的指针)

    文章目录 1. 函数指针 1)函数指针的例题 2. 指针函数 3. 函数指针数组 1)函数指针数组的用途 4. 指向函数指针数组的指针 5. 一些后话 1. 函数指针 函数指针就是指向函数的指针:本质 ...

  9. C语言自定义函数如何返回数组

    C语言自定义函数如何返回数组  C语言研究中心  CTO  9个月前 (01-28)  4759次浏览  5个评论 最近看到一些同学问题,有提到说:如何在一个函数中返回数组呢? 能否直接在自定义 函数 ...

最新文章

  1. Activity一共有以下四种launchMode
  2. 手把手带你用数据库中间件Mycat+SpringBoot完成分库分表
  3. 龙格库塔法matlab求解微分方程组,微分方程组的龙格库塔公式求解matlab版.pdf
  4. windows消息机制-4(MFC)
  5. 这周,我们作前端,实现统一的过滤搜索
  6. 串口打印怎么使用】_爱普生打印机怎么使用 爱普生打印机使用方法【详解】...
  7. 准备创业或刚创业的朋友必读
  8. Git-版本控制 (二)
  9. 第7章 PCA与梯度上升法 学习笔记中
  10. matlab 带通滤波结果不对,带通滤波 matlab
  11. 大数据决策支持的优势
  12. c语言程序设计伴随矩阵,c语言求方阵的行列式、伴随矩阵算法
  13. TMS320DM642调试出现#10247-D creating output section .capChaACrSpace without a SECTIONS 解决办法...
  14. 【PX4自动驾驶用户指南】距离传感器
  15. 一台计算机多个屏幕,一台电脑多个显示器,屏幕远程控制
  16. css3实现加载进度条的效果(二)
  17. Nginx获取真实用户IP
  18. window xp 自动登陆系统
  19. vector访问出界引起的,判断异常
  20. 张一鸣:Stay hungry, Stay young

热门文章

  1. java 类之间转换,java中类对象之间的类型转换
  2. MVC 之var与dynamic
  3. 送福利:ROKID 语音开发板免费送,开启你的物联网之旅
  4. Pyechart:30分钟学会pyecharts数据可视化
  5. vue+element 封装公共js代码
  6. Sqoop数据迁移工具的使用
  7. 模块 hashlib模块
  8. 学习教材《构建之法》遇到的问题及思路
  9. linux之x86裁剪移植---ffmpeg的H264解码显示(420、422)
  10. ubuntu更新python的指令_ubuntu下python模块的库更新(转载)