当前位置: 首页 > news >正文

Linux0.12的中断处理过程源码分析

在linux0.12中和中断处理文件有asm.s和traps.c。asm.s用于实现大部分硬件异常所引起的中断服务过程的汇编程序部分,而traps.c程序实现asm.s中段处理过程中调用的c函数部分。中断服务由内核提供,因此中断处理过会使用进程的内核态栈。

关于IDB的定义和初始化相关代码如下,首先是在启动代码boot/head.S中定义了一个idt表并将其全部设置了一个默认的中断处理函数:

.align 3
_idt:	.fill 256,8,0		# idt is uninitializedsetup_idt:
/** %eax:* 位31-16: 0x0008 (段选择子)* 位15-0:  ignore_int地址的低16位* %edx:* 位31-16: 0x8E00 (中断门属性)* 位15-0:  ignore_int地址的高16位
*/lea ignore_int,%edxmovl $0x00080000,%eaxmovw %dx,%axmovw $0x8E00,%dxlea _idt,%edi          # edi指向IDT的基地址mov $256,%ecx          # 256个中断门
rp_sidt:movl %eax,(%edi)movl %edx,4(%edi)addl $8,%edi           # 移动到下一个中断门描述符dec %ecx               # 循环计数器减1jne rp_sidtlidt idt_descr         # 加载IDT描述符ret

然后在kernel/traps.c中重新设置了部分中断的处理函数

void trap_init(void)
{int i;set_trap_gate(0,&divide_error);set_trap_gate(1,&debug);set_trap_gate(2,&nmi);set_system_gate(3,&int3);	/* int3-5 can be called from all */set_system_gate(4,&overflow);set_system_gate(5,&bounds);set_trap_gate(6,&invalid_op);set_trap_gate(7,&device_not_available);set_trap_gate(8,&double_fault);set_trap_gate(9,&coprocessor_segment_overrun);set_trap_gate(10,&invalid_TSS);set_trap_gate(11,&segment_not_present);set_trap_gate(12,&stack_segment);set_trap_gate(13,&general_protection);set_trap_gate(14,&page_fault);set_trap_gate(15,&reserved);set_trap_gate(16,&coprocessor_error);set_trap_gate(17,&alignment_check);for (i=18;i<48;i++)set_trap_gate(i,&reserved);set_trap_gate(45,&irq13);/* 配置8259A可编程中断控制器,启用特定中断 */outb_p(inb_p(0x21)&0xfb,0x21);outb(inb_p(0xA1)&0xdf,0xA1);set_trap_gate(39,&parallel_interrupt);
}

中断处理函数的定义是在汇编代码kernel\asm.s中,当中断被触发后,CPU会自动的在IDT表里面根据中断号找到对应的中断处理函数。以除0异常举例,CPU将会跳转到_divide_error开始执行(关于_do_divide_error的定义是在kernel\trps.c中)

_divide_error:pushl $_do_divide_error # 将do_divide_error的地址压入栈中
no_error_code:xchgl %eax,(%esp)       # 将函数地址从栈移到eax# 保存所有通用寄存器和段寄存器,为调用C函数做准备pushl %ebxpushl %ecxpushl %edxpushl %edipushl %esipushl %ebppush %dspush %espush %fspushl $0		         # 将0压入栈中,占位符lea 44(%esp),%edx        # edx指向异常发生时的栈指针位置pushl %edx               # 将edx入栈,作为第一个参数传递给C函数# 切换到内核数据段,异常处理需要访问内核数据movl $0x10,%edxmov %dx,%dsmov %dx,%esmov %dx,%fscall *%eax               # 间接调用eax中的函数地址addl $8,%esp             # 将栈指针向上移动8字节,这8字节是pushl $0和pushl %edx# 恢复段寄存器和通用寄存器pop %fspop %espop %dspopl %ebppopl %esipopl %edipopl %edxpopl %ecxpopl %ebxpopl %eaxiret                      # 中断返回
http://www.dtcms.com/a/394543.html

相关文章:

  • 进程控制(Linux)
  • 【C++】——string类的使用(详细讲解)
  • 借助 Amazon ECS 全新的内置蓝绿部署功能,加速安全的软件发布进程
  • 【脑电分析系列】第24篇:运动想象BCI系统构建:CSP+LDA/SVM与深度学习方法的对比研究
  • 【论文速递】2025年第22周(May-25-31)(Robotics/Embodied AI/LLM)
  • MySQL 5.7 多实例部署完整指南(基于二进制包)
  • Git的使用——Git命令、密钥/私钥、文件推送/提交、分支增删改查、文件回滚、.gitignore文件忽略
  • [已更新]2025华为杯D题数学建模研赛D题研究生数学建模思路代码文章成品:低空湍流监测及最优航路规划
  • [C++类的默认成员函数——lesson5.构造函数析构函数]
  • 第二十七章 ESP32S3 INFRARED_TRANSMISSION 实验
  • ✅ Python车牌识别计费系统 PyQt5界面 YOLOv5+CRNN 深度学习 MySQL可视化 车牌检测(建议收藏)
  • 盛水最多的容器_优选算法(C++)双指针
  • QT-串口,完结!
  • Git常用命令合集
  • Qt(模态对话框的切换)
  • QT-模型视图结构
  • C语言 C语句
  • 《理解Reactor网络编程模型》
  • Mirror Maze 镜面反射
  • 一个案例弄懂nfs
  • 在飞牛NAS使用Lucky做动态解析到域名?
  • 多实例 MySQL 部署
  • 使用批处理脚本快速切换 Claude API 实现多平台环境配置
  • SkyDiffusion:用 BEV 视角打开街景→航拍图像合成新范式
  • 免费下载适用于 Windows PC 的 Pixologic Zbrush 2026
  • 10.eNSP下载及安装教程(2025年9月21日)
  • Qt 实战 之 打包部署
  • QT-文件
  • 2001-2022年全国地级市高铁开通数据
  • TenstoRT加速YOLOv11——C++端加速