Linux内核中断(X86)

基本上Linux支持的平台都或多或少采用了中断的概念,中断可以周期性产生或者随机产生,如:网卡硬件在收到数据包时会产生中断,而后内核中断处理例程将进行处理。

中断的分类:

  • 硬件中断

                由与CPU连接的外设产生的中断,外设无法产生中断,是通过一个中断控制器产生中断。

  • 软中断

由内核模拟实现的一种中断机制,是平台无关的,它依赖于硬件中断。

同步中断和异常:

        由CPU自身产生,例如 除零 或用户空间应用程序访问了一个地址空间,该地址空间没有关联物理页,这将产生缺页异常,内核需要关注CPU产生的各种异常,并进行响应的处理。

异步中断:

它们由外部设备产生,可能发生于任何时间,当中断产生时内核可能处于任何状态,内核会尽快处理该类型中断,然后将CPU时间交还给用户进程。

中断号:

每一个中断都有一个中断号,用于区分不同的中断情况,例如:网卡,当数据分组到来时,将产生中断号N,内核会识别这个网卡中断并调用合适的处理例程,但是不同体系架构支持的中断号数量不一,如IA32处理器仅支持最大15个中断数目,并且其中一些已分配给固定的设备: 鼠标、键盘等。

中断共享:

为了解决中断数量少而采用的一种中断使用方式,多个设备使用一个中断号来使系统支持更多的设备,这需要内核和硬件均支持才能做好。

CPU产生中断中,会根据中断号调用相应的中断服务例程,以x86架构为例,在初始化系统时会安装各类中断例程到IDT(中断描述符表),中断号为索引每个中断项就是中断处理例程的地址。

内核安装的CPU内部中断历程:

static const __initconst struct idt_data def_idts[] = {
	INTG(X86_TRAP_DE,		asm_exc_divide_error),
	INTG(X86_TRAP_NMI,		asm_exc_nmi),
	INTG(X86_TRAP_BR,		asm_exc_bounds),
	INTG(X86_TRAP_UD,		asm_exc_invalid_op),
	INTG(X86_TRAP_NM,		asm_exc_device_not_available),
	INTG(X86_TRAP_OLD_MF,		asm_exc_coproc_segment_overrun),
	INTG(X86_TRAP_TS,		asm_exc_invalid_tss),
	INTG(X86_TRAP_NP,		asm_exc_segment_not_present),
	INTG(X86_TRAP_SS,		asm_exc_stack_segment),
	INTG(X86_TRAP_GP,		asm_exc_general_protection),
	INTG(X86_TRAP_SPURIOUS,		asm_exc_spurious_interrupt_bug),
	INTG(X86_TRAP_MF,		asm_exc_coprocessor_error),
	INTG(X86_TRAP_AC,		asm_exc_alignment_check),
	INTG(X86_TRAP_XF,		asm_exc_simd_coprocessor_error),

#ifdef CONFIG_X86_32
	TSKG(X86_TRAP_DF,		GDT_ENTRY_DOUBLEFAULT_TSS),
#else
	INTG(X86_TRAP_DF,		asm_exc_double_fault),
#endif
	INTG(X86_TRAP_DB,		asm_exc_debug),

#ifdef CONFIG_X86_MCE
	INTG(X86_TRAP_MC,		asm_exc_machine_check),
#endif

	SYSG(X86_TRAP_OF,		asm_exc_overflow),
#if defined(CONFIG_IA32_EMULATION)
	SYSG(IA32_SYSCALL_VECTOR,	entry_INT80_compat),
#elif defined(CONFIG_X86_32)
	SYSG(IA32_SYSCALL_VECTOR,	entry_INT80_32),
#endif
};

以上是中断的地址,在内核启动过程中Start_Kernel->trap_init

void __init idt_setup_traps(void)
{
	idt_setup_from_table(idt_table, def_idts, ARRAY_SIZE(def_idts), true);
}

内核中断涉及的数据结构:


//这个结构体在5.x内核版本中扩展了很多,我裁剪了不太重要的成员。
struct irq_desc {
	struct irq_common_data	irq_common_data; //该中断的信息 如 中断号、 dev_id(实现中断共享的关键)
	irq_flow_handler_t	handle_irq;
	struct irqaction	*action;	/* IRQ action list */ 中断处理例程链表
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值