FreeBSD 5 内核中断处理的最大特点是将中断处理程序在线程的上下文中运行 。
为此,内核为每个注册的中断源(即vector)准备一个内核线程,即中断线程,
其任务就是等待中断的发生,一旦发生,便运行相应的中断处理程序 。
FreeBSD 5这样做,有好处也有坏处 。好处是可以简化线程和中断的互斥关系,
并使得中断处理可以阻塞 。
坏处是每次响应中断都要进行线程调度,可能有两次线程上下文的切换
(从用户线程切到中断线程再切回来) 。未来的想法是进行lazy scheduling,
即尽可能借用当前线程的上下文,只有在中断要阻塞时才进行真正的调度 。
与中断有关的源代码主要在
sys/kern/kern_intr.c (与体系结构无关的中断代码)
sys/i386/i386/intr_Machdep.c (与i386体系结构相关的中断代码)
sys/i386/isa/atpic.c (与8259A相关的.c代码)
sys/i386/isa/atpic_vector.s (与8259A相关的.s代码)
Contents
1,登记IRQ中断源
1.1 数据结构与函数
1.2 8259A的登记过程
2,IRQ中断的处理过程
3, 软件中断swi
3.1 软件中断的登记
3.2 软件中断的调度
-------------------------------
1,登记IRQ中断源
1.1 数据结构与函数
中断向量表有多个vector,0-31为CPU用,32~32 15对应IRQ0~IRQ15
一个vector对应一个source,数据类型是struct intsrc
代码:
/*
* An interrupt source. The upper-layer code uses the PIC methods to
* control a given source. The lower-layer PIC drivers can store additional
* private data in a given interrupt source such as an interrupt pin number
* or an I/O APIC pointer.
*/
struct intsrc {
struct pic *is_pic;
struct ithd *is_ithread;
u_long *is_count;
u_long *is_straycount;
u_int is_index;
};
其实在vector后面的是中断控制器,如8259A,I/O APIC等,
事实上,对中断源的控制实际上就是对中断控制器的操作,
因此,在struct intsrc中有成员struct pic *is_pic,
即中断控制器的操作函数表,通过这个表,可以为不同的中断控制器
定义不同的操作,达到demultiplex的作用 。这里pic是
programmable interrupt controller的意思 。
代码:
/*
* Methods that a PIC provides to mask/unmask a given interrupt source,
* "turn on" the interrupt on the CPU side by setting up an IDT entry, and
* return the vector associated with this source.
*/
struct pic {
void (*pic_enable_source)(struct intsrc *);
void (*pic_disable_source)(struct intsrc *);
void (*pic_eoi_source)(struct intsrc *);
void (*pic_enable_intr)(struct intsrc *);
int (*pic_vector)(struct intsrc *);
int (*pic_source_pending)(struct intsrc *);
void (*pic_suspend)(struct intsrc *);
void (*pic_resume)(struct intsrc *);
};
系统中所有的中断源组成一个数组,由于当采用I/O APIC作为中断控制器时,
可以有191个中断号(IRQ),因此该数组大小定义为191 。
代码:
static struct intsrc *interrupt_sources[NUM_IO_INTS];
/* With I/O APIC"s we can have up to 191 interrupts. */
#define NUM_IO_INTS 191
所谓登记中断源,就是将实际的中断控制器的对应struct intsrc数据结构
添加到该数组中去 。同时,系统为每个登记的中断源创建一个中断线程,
中断处理程序就在该线程的上下文中运行,该线程的入口函数为ithread_loop(),
struct intsrc结构成员is_ithread指向描述中断线程的数据结构struct ithd,
而struct ithd结构成员it_td指向真正的线程结构struct thread,从而将中断
与系统的调度单元线程联系起来 。
代码:
/*
* Describe an interrupt thread. There is one of these per interrupt vector.
* Note that this actually describes an interrupt source. There may or may
推荐阅读
- 1、系统安装 FreeBSD网站平台建设全过程
- 用FREEBSD作开发的一些实现方式
- FreeBSD下的内存文件系统
- FreeBSD中/etc下的文件简介
- FreeBSD下Apache2.0运行模型分析及性能调整
- 试用QEMU,安装个FreeBSD 5.3
- FreeBSD下有关分区和mount的一些问题
- RSYNC ON FreeBSD 5.2 HOWTO V1.0
- 系统核心 自订 FreeBSD Kernel
- 一些FreeBSD相关的安全问题