中断初始化

来源:互联网 发布:linux mint 18安装 编辑:程序博客网 时间:2024/05/17 03:33

下面的分析是基于3.6.10内核版本。

中断描述符

硬中断产生之后通过门描述符来寻找中断处理程序的入口。中断描述符表的每个表项由8字节组成,叫做一个门描述符。主要包括三种门描述符:陷阱门、中断门和系统门。

这里看下中断门描述符的结构:

中断门描述主要包括中断如理程序所在的段选择符和段内偏移及一些标志位。低4字节的bit16~bit31为段选择符,bit0~15为段内偏移量的低16位,高4字节的bit31~16为段内偏移量的高16位。

 

中断描述符初始化

◆在arch/x86/kernel/head_64.S

.section .bss, "aw", @nobits

.align L1_CACHE_BYTES

ENTRY(idt_table)

.skip IDT_ENTRIES * 16

上面的汇编代码的意思是变量idt_table在.bss段内,预留空间大小为256*16字节,并且每个字节的值都为0

 

◆在arch/x86/kernel/cpu/common.c

struct desc_ptr idt_descr NR_VECTORS 16 1, (unsigned longidt_table };

IDT的大小为256*16字节,地址在idt_table

 

◆在arch/x86/kernel/cpu/common.ccpu_init函数中

load_idt((const struct desc_ptr *)&idt_descr);  

IDT表加载到IDTR寄存器中。中断描述符表IDT可以驻留在线性地址空间的任何地方,使用IDTR寄存器定位IDT表的位置。

 

下面看下初始化的整个流程:

1、 在start_kernel函数中会调用trap_init函数来初始化陷阱门和系统调用门,init_IRQ函数来初始化中断门描述符,调用early_irq_init初始化与硬件无关的中断门相关事项,在后面会分析此函数。

2、 init_IRQ函数通过x86_init操作集的intr_init调用native_init_IRQ函数

apic_intr_init();    

FIRST_EXTERNAL_VECTOR 

for_each_clear_bit_from(iused_vectorsNR_VECTORS) {  

/* IA32_SYSCALL_VECTOR could be used in trap_init already. */  

set_intr_gate(iinterrupt[FIRST_EXTERNAL_VECTOR]);  

 

apic_intr_init用来初始化与APIC中断控制器相关的中断门描述符的。FIRST_EXTERNAL_VECTOR值为0x20IDT表中外部中断向量从32开始。在前面trap_init函数中对所有的陷阱门描述符和系统调用门描述符都设置了used_vectors数组中的相应位,剩下没有设置的就是用作外部中断的中断门描述符了。Interrupt数组保存了这些外部中断描述符门的处理程序的地址。

3alloc_intr_gate函数首先调用alloc_system_vector设置中断向量对应在used_vectors数组中的位,然后调用set_intr_gate函数设置一个中断描述符表项。

static inline void set_intr_gate(unsigned int nvoid *addr

 

 BUG_ON((unsigned)n 0xFF);  

 _set_gate(nGATE_INTERRUPTaddr00__KERNEL_CS);  

}  

首先判断中断向量号是否大于255,然后调用_set_gate函数。

static inline void _set_gate(int gateunsigned typevoid *addr 

        unsigned dplunsigned istunsigned seg 

  

 pack_gate(&stype, (unsigned long)addrdplistseg);    

 write_idt_entry(idt_tablegate&s);  

}  

pack_gate函数主要是填充中断门描述符表项的8字节的相应位。中断处理程序地址填充为段内偏移,段选择符为__KERNEL_CS,特权级DPL0,用户态程序不能访问中断门。所有中断程序的访问都必须经过中断门,这样中断的处理就限制在内核态了。

 

中断入口

在前面中断描述符初始化中看到一般外部硬中断的处理程序地址存放在Interrupt数组中。下面看下Interrupt:(arch/x86/kernel/entry_64.S)

.section .init.rodata,"a"

ENTRY(interrupt)

.section .entry.text

.p2align 5

.p2align CONFIG_X86_L1_CACHE_SHIFT

ENTRY(irq_entries_start)

INTR_FRAME

vector=FIRST_EXTERNAL_VECTOR

.rept (NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7

.balign 32

  .rept 7

    .if vector < NR_VECTORS

      .if vector <> FIRST_EXTERNAL_VECTOR

CFI_ADJUST_CFA_OFFSET -8

      .endif

1: pushq_cfi $(~vector+0x80)    //将中断向量号取反加上0x80后压栈

      .if ((vector-FIRST_EXTERNAL_VECTOR)%7) <> 6

jmp 2f

      .endif

      .previous    //使汇编器返回到前面的数据段进行汇编

.quad 1b       //存储着标签1处的地址

      .section .entry.text

vector=vector+1

    .endif

  .endr

2: jmp common_interrupt

.endr

CFI_ENDPROC

END(irq_entries_start)

 

.previous

END(interrupt)

.previous

1、 变量Interrupt数组位于.init.rodata数据段中,变量irq_entries_start位于.entry.text代码段中。

2、 下面来看下irq_entries_start干了些什么。宏INTR_FRAME用来初始化中断时的栈帧状态。Vector初始值为FIRST_EXTERNAL_VECTOR(即为32),在外循环中会重复(NR_VECTORS-FIRST_EXTERNAL_VECTOR+6)/7 = (256 – 32 + 6) / 7 = 32次。

3、 内循环重复7次,宏pushq_cfi使用pushq指令将(~vector+0x80)的值压栈,然后做一些检查之后就跳转到common_interrupt函数。

 

上面的代码相当于是把NR_VECTORS-FIRST_EXTERNAL_VECTOR个中断处理程序的地址存在变量Interrupt数组开始的数据段中,处理程序的代码存储在变量irq_entries_start开始的代码段中。common_interrupt函数是这些中断处理程序的公共的入口,只是每个中断压栈的参数中断向量号不同而已。

common_interrupt函数分析:

common_interrupt:

XCPT_FRAME

addq $-0x80,(%rsp) /* Adjust vector to [-256,-1] range */

interrupt do_IRQ

/* 0(%rsp): old_rsp-ARGOFFSET */

ret_from_intr:

common_interrupt函数使用宏interrupt来调用do_IRQ函数,当然在进入do_IRQ函数之前,做了压栈保存现场的操作,以及设置gs寄存器值等。

进入do_IRQ函数之后的处理流程这里就不分析了。

 

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 网上有人黑我怎么办? 公司前台没事做怎么办 股票跌到谷底了怎么办 cad无法进一步缩小怎么办 dnf更新错误280怎么办 win7电脑屏幕倒过来了怎么办 电脑画面缩小了怎么办 每次客户不付款怎么办 如果客户不付款怎么办 支付宝逾期起诉怎么办 卖号被骗了怎么办 网上交易视频被骗了怎么办 闲鱼卖游戏账号被骗怎么办 网银锁住了怎么办 电脑密码锁住了怎么办 苹果x旋转不了怎么办 苹果x黑白屏怎么办 dell网卡坏了怎么办 笔记本连网速慢怎么办 无线充电太慢怎么办 vivo手机速度慢怎么办 台式电脑很卡怎么办 电脑网卡驱动程序不正常怎么办 电脑没有网卡驱动怎么办 电脑网络网速差怎么办 小米wifi测速慢怎么办 电脑网速特别慢怎么办 戴尔电脑网速慢怎么办 电脑网络特别慢怎么办? 电脑上网很慢怎么办 笔记本网速太慢怎么办 ns下载特别慢怎么办 人人视频弹广告怎么办 忘记华为账号密码怎么办 手机电源键不灵怎么办 智能手机返回键失灵怎么办 手机关闭失灵了怎么办 生死狙击密保忘了怎么办 魔域密保问题忘了怎么办 小米账号无法登陆怎么办 老公突然出车祸怎么办