[Linux内核完全剖析]第五章Linux内核体系结构5.4-5.6总结 x86中断和时间控制

x86中断子系统
x86微机系统中采用了8259A可编程中断控制器,每个8259A可以管理8个中断源,通过多片级联方式,可以构成最多管理64个中断向量的系统。PC/AT中使用了2片8259A,共可管理15个中断向量。CPU通过IO指令对8259A进行初始化后,芯片就可以根据当前设定的优先级状态通过INT引脚来通知CPU中断请求。CPU响应后,会从数据总线D7-D0获取从芯片发送的中断号。

CPU根据中断号要获取中断服务地址,就需要一张中段向量表(实模式)/中断描述符表(保护模式)来进行查询。x86微机支持256个中断:
实模式下每个中断向量占4个字节,低字放入偏移地址,高字放入段值。中断向量表共长1024字节,BIOS在启动后会在物理地址0开始初始化并设置中断向量表,中断服务程序由BIOS给出,向量是按顺序排列的。其中两片8259A支持的16个(由于IRQ2被用于级联输入,实际可使用的中断只有15个)硬中断被依次设置在中断向量0x20——0x2f中。Linux系统在刚开始加载内核时会用到显示和磁盘读的中断,然后在setup.s中重新初始化8259A并在head.s中重设一张中断描述符表。

对于Linux内核来说,中断信号分为两类:硬件中断和软件中断。
int 0——int 31,每个中断的功能根据Intel固定设定或者保留,属于软中断,intel称为异常。在kernel/traps.c中设置
int 32——int 47,对应于8259A发出的硬件中断,IRQ0——IRQ15
int 128,系统调用中断,在kernel/sched.c中设置
系统调用:eax放调用号,ebx,ecx,edx依次存放参数,故Linux0.11最多向内核传递三个参数。

系统时间,通过init/mian.c中的time_init()函数读取主板RT电路上保存的时间信息,再用过kernel/mktime.c中kernel_mktime()函数转化为Unix日历时间(从1970-01-01:00:00:00到当前位秒数)被保存在全局变量startup_time中内核使用。用户可使用time()系统调用来读取该值,超级用户可以通过stime()系统调用设置该值。系统定义了宏来获取当前时间
#define CURRENT_TIME (startup_time + jiffies/HZ)

 

jiffies是系统启动到当前的时钟滴嗒,10ms为单位,HZ=100是滴嗒频率。时钟滴嗒是由Intel 8253计数器产生的,它连接到8259A的IRQ0引脚上,由于事先设置了计数器频率,每隔10ms就会产生一个上升沿方波,经过8259A处理后产生一个IRQ0中断,就运行一次timer_interrupt中断处理程序。中断处理程序会对jiffies自增以及当前进程的时间计数和时间片切换等操作。

This entry was posted in 未分类. Bookmark the permalink.

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注