分享
 
 
 

基于i386的Linux实现特点剖析——关于中断

王朝system·作者佚名  2008-05-19
窄屏简体版  字體: |||超大  

摘要

??Linux内核在初始化阶段完成了对页式虚拟管理的初始化以后,便调用trap_init()和init_IRQ()两个函数进行中断机制的初始化。其中trap_init()主要是对一些系统保留的中断向量的初始化,而init_IRQ()则主要是用于外设的中断。

三、Linux下中断管理的实现

??1.中断向量表IDT的初始化

??Linux内核在初始化阶段完成了对页式虚拟管理的初始化以后,便调用trap_init()和init_IRQ()两个函数进行中断机制的初始化。其中trap_init()主要是对一些系统保留的中断向量的初始化,而init_IRQ()则主要是用于外设的中断。

void _init trap_init(void)

{

#ifdef CONFIG_EISA

if (isa_readl(0x0FFFD9) ==

'E+('I'

EISA_bus = 1;

#endif

set_trap_gate(0,÷_error);

set_trap_gate(1,&debug);

set_intr_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,&spurious_interrupt_bug);

set_trap_gate(16,&coprocessor_error);

set_trap_gate(17,&alignment_check);

set_trap_gate(18,&machine_check);

set_trap_gate(19,&simd_coprocessor_error);

set_system_gate(SYSCALL_VECTOR,&system_call);

/*

* default LDT is a single_entry callgate to lcall7 for iBCS

* and a callgate to lcall27 for Solaris/x86 binaries

*/

set_call_gate(&default_ldt[0],lcall7);

set_call_gate(&default_ldt[4],lcall27);

/*

_set_gate(a,12,3,addr);

//12 即1100b,类型码为100,即调用门

}

??这些函数都调用同一个子程序_set_gate(),第一个参数用以设置中断描述符表idt_table中的第n项,第二个参数对应于门格式中的D位加类型位段,第三个参数是对应的DPL位段。

#define _set_gate(gate_addr,type,dpl,addr)

do {

int _d0,_d1;

_asm_ _volatile_("movw %%dx,%%ax

")

"movw %4,%%dx

"

"mov1 %%eax,%0

"

"mov1 %%edx,%1"

:"=m" (*((long * ) (gate_addr))),

"=m" (*(1+(long *)(gate_addr))),"=&a" (_d0),"=&d" (_d1)

:"i" ((short) (0x8000+(dpl

"3" ((char *) (addr)),"2" (_KERNEL_CS

}while(0)

??在第一个“:”到第二个“:”之间为输出部,有四个约束输出,将有四个变量会被改变,分别为%0、%1、%2和%3相结合。其中%0和%1都是内存单元,分别和gate_addr、gate_addr+1结合,%2于局部变量_d0结合,存放在寄存器%%eax中;%3于局部变量_d1结合,存放在寄存器%%edx中。

??第二个“:”之后的部分是输入部,输出部已经定义了%0-%3,输入部中的第一个变量为%4,而紧接着的第二、第三个变量分别等价于输出部的%3和%2。输入部中说明的个输入变量地值,包括%3和%2,都会在引用这些变量之前设置好。在执行指令部的代码之前,会先将%%eax设成(_KERNEL_CS

有表格

??指令部第一条指令“movw %%dx,%%ax”,将%%dx的低16位移入%%ax的低16位,这样,在%%eax中,其高16位为_KERNEL_CS,而低16位为addr的低16位,形成了门结构中的第0-31位。

??第二条指令“movx %4 ,%%dx”,将%4放入%%dx中,也就是将门结构中的第32-47位放在%%dx中,而对于%%edx而言,就对应着门结构中的高32位。

??第三条指令“mov1 %%eax,%0”,将%%edx写入变量%0中,即*gate_addr。

??第四条指令“mov1 %%eax,%1”将%%edx写入变量%1中,即*(gate_addr+1)。

??将第三、第四条指令和起来看,就是将整个门结构的内容都写道*gate_addr中去了。

void _inti init_IRQ(void)

{

int i;

#ifndef CONFIG_X86_VISWS-APIC

init_ISA_irqs();

#else

init_VISWS_APIC_irqs();

#endif

/*

* Cover the whole vector space,no vector can escape

* us. (some of these will be overridden and become

* 'special' SMP interrupts)

*/

for (i=0;i

int vector = FIRST_EXTERNAL_VECTOR + i;

if (vector != SYSCALL_VECTOR)

set_intr_gate(vector,interrupt[i]);

}

#ifdef CONFIG_SMP

/*

* IRQ0 must ve given a fixed assignment and initialized,

* because it's used before the I0-APIC is set up.

*/

set_intr-gate(FIRST_DEVICE_VECTOR,interrupt[0]);

/*

* The reschedule interrupt is a CPU-to-CPU reschedule-helper

* IPI,driven by wakeup.

*/

set_intr_gate(RESCHEDULE_VECTOR,reschedule_interrupt);

/* IPI for generic function call */

set_intr_gate(CALL_FUCTION_VECTOR,call_funtion_interrupt);

#endif

#ifdef CONFIG_X86_LOCAL_APIC

/* IPI vectors for APIC spurious and error interrupts */

set_intr_gate(SPURIOUS_APIC_VECTOR,spurious_interrupt);

set_intr_gate(ERROR_APIC_VECTOR,error_interrupt);

#endif

/*

* Set the clock to HZ Hz, we already have a valid

* vector now;

*/

outb_p(0x34,0x43); /* binary, mode 2, LSB/MSB ,ch 0*/

outb_p(LATCH & 0xff,0x40); /* LSB */

outb(LATCH 8, 0x40); /* MSB */

#ifndef CONFIG_VISWS

setup_irq(2, &irq2)

#endif

/*

* External FPU? Set up irq13 if so,for

* original braindamaged IBM FERR coupling.

*/

if (boot_cpu_data.hard_math && !cpu_has_fpu)

setup_irq(13,&irq13);

??i386体系支持256各中断向量,扣除为cpu保留的向量,Linux作为通用操作系统,很难说剩下的中断向量是否够用。所以,在Linux系统中,为每个中断向量设置一个队列,而根据每个中断源所使用的中断向量,将其中断服务程序挂到相应的队列中,而数组irq_desc[]中的每个元素则是这样一个队列头部以及控制结构。当中断发生时,首先执行中断向量相对应的一段总服务程序,根据具体中断源的设备号在其所属队列中找到特定的服务程序加以执行。

??首先对PC的中断控制器8259A的初始化,并初始化了数组iirq_desc[]。接着从FIRST_EXTERNAL_VECTOR开始,设立NR_IRQS个中断向量的 IDT表项。常数FIRST_EXTERNAL_VECTOR定义为 0x20,而NR_IRQS则为224。其中还跳过了用于系统调用的向量0x80。

??忽略我们不关心的多处理器SMP结构和SG1工作站的特殊处理,剩下的就是对系统时钟的初始化。在PC中,定时器/计数器芯片8254共有三个通道,通道0是一个产生实时时钟信号的系统计时器,而程序中要设置的也就是通道0。用于控制8254的端口共有四个,前三个分别对应于单个通道的端口,最后一个通道对应于8254的控制字寄存器端口。

outb_p(0x34,0x43);//设置通道的工作方式

//选通通道0,先读写高字节,后读写低字节,工作于方式2,二进制数

outb_p(LATCH&0xff,0x40);

//写入低字节

outb(LATCH8,0x40);

//写入高字节

//设置通道0的记数值

??到此,已经设置好了IDT,也有了一个中断向量,0号中断时钟中断。但是,虽然该中断服务的入口地址已经设置到中断向量表中,但我们还没有把0号中断具体的中断服务程序挂到0号中断的队列中去。这时,这些中断地队列都是空的,因此,即使开了中断,并产生了时钟中断,也只不过是让它在中断处理的总服务程序中空跑一趟。

??设置好了中断向量表,中断队列都还是空的。想要中断程序生效,下一步就要初始化中断请求队列,并把具体的中断服务程序挂入中断队列中去。

??2、中断请求队列的初始化

??通用中断门是让多个中断源共用的,而且允许这种共用的结构在系统运行的过程中动态的改变,所以在IDT地初始化阶段只是为每个中断向量准备一个中断请求队列,从而

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有