中断分类

Linux系统中,中断分为:

  • 硬中断:由外部设备或者执行异常产生的需要快速处理的中断。如缺页中断、定时器硬件中断。

    根据内部产生还是外部产生,分为:

    1. 异常:异常是内部产生的中断,不可屏蔽。
    2. 外部中断:外部中断是由外部设备产生的,可以屏蔽。
  • 软中断:

    ​ 软中断是Linux系统中断处理的底半处理部分,是Linux模拟的中断。为了加快硬件中断的处理,防止数据的丢失,Linux对中断处理分为顶半处理和底半处理两部分,顶半处理程序快速处理硬件事件,把不是那么紧急的逻辑放到底半处理程序中,可以简单的认为硬终端处理程序为顶半处理程序,软中断处理程序为底半处理程序。软中断一般在硬中断处理程序执行后才会执行。但是当硬中断嵌套的时候,软中断会在所有的硬中断处理完毕后才会处理,当软中断太多,会放到ksoftirqd线程中处理。

内核初始化-中断

intel处理器有256个硬中断号。其中前32个中断号为异常使用,在内核初始化的时候进行初始化。内核初始化的代码流程如下:
可以看到首先初始化异常处理,再初始化部分外部中断,再初始化一部分软中断处理。


asmlinkage void __init start_kernel(void)
{lock_kernel();...//初始化调度模块sched_init();...sort_main_extable();// 初始化异常处理。trap_init();...// 初始化外部中断init_IRQ();...// 初始化定时器模块,同时,会注册定时器的软中断处理函数。init_timers();// 初始化软中断)softirq_init();time_init();...// 初始化acpi_early_init();
}

异常中断初始化

异常中断在内核中称为trap,异常中断初始化代码为

//门初始化。初始化中断向量表。系统有固定的256个硬件中断向量。
void __init trap_init(void)
{set_intr_gate(0,&divide_error);set_intr_gate_ist(1,&debug,DEBUG_STACK);set_intr_gate_ist(2,&nmi,NMI_STACK);set_intr_gate(3,&int3);set_system_gate(4,&overflow);   /* int4-5 can be called from all */set_system_gate(5,&bounds);set_intr_gate(6,&invalid_op);set_intr_gate(7,&device_not_available);set_intr_gate_ist(8,&double_fault, DOUBLEFAULT_STACK);set_intr_gate(9,&coprocessor_segment_overrun);set_intr_gate(10,&invalid_TSS);set_intr_gate(11,&segment_not_present);set_intr_gate_ist(12,&stack_segment,STACKFAULT_STACK);set_intr_gate(13,&general_protection);set_intr_gate(14,&page_fault);set_intr_gate(15,&spurious_interrupt_bug);set_intr_gate(16,&coprocessor_error);set_intr_gate(17,&alignment_check);
#ifdef CONFIG_X86_MCEset_intr_gate_ist(18,&machine_check, MCE_STACK);
#endifset_intr_gate(19,&simd_coprocessor_error);#ifdef CONFIG_IA32_EMULATIONset_system_gate(IA32_SYSCALL_VECTOR, ia32_syscall);
#endifset_intr_gate(KDB_VECTOR, call_debug);/** Should be a barrier for any external CPU state.*/cpu_init();
}

总结如下:

中断向量号 异常事件 Linux的处理程序
0 除法错误 Divide_error
1 调试异常 Debug
2 NMI中断 Nmi
3 单字节,int 3 Int3
4 溢出 Overflow
5 边界监测中断 Bounds
6 无效操作码 Invalid_op
7 设备不可用 Device_not_available
8 双重故障 Double_fault
9 协处理器段溢出 Coprocessor_segment_overrun
10 无效TSS Incalid_tss
11 缺段中断 Segment_not_present
12 堆栈异常 Stack_segment
13 一般保护异常 General_protection
14 页异常 Page_fault
15 Spurious_interrupt_bug
16 协处理器出错 Coprocessor_error
17 对齐检查中断 Alignment_check
0x80 系统调用 ia32_syscall
0xf9 内核调试 call_debug

上述中断处理函数都是汇编语言编写。一部分汇编直接处理完毕,一部分通过调用C函数帮助处理。
汇编代码在linux/arch/x86_64/entry.S中,大部分都是调用C函数do_中断处理函数名处理。
整理如下:

中断向量号 异常事件 Linux汇编 调用c函数 处理结果
0 除法错误 Divide_error do_divide_error 发送SIGFPE信号
1 调试异常 Debug do_debug 发送SIGTRAP信号
2 NMI中断 Nmi do_nmi
3 单字节,int 3 Int3 do_int3 发送SIGTRAP信号
4 溢出 Overflow do_overflow 发送SIGSEGV信号
5 边界监测中断 Bounds do_bounds 发送SIGSEGV信号
6 无效操作码 Invalid_op do_invalid_op 发送SIGILL信号
7 设备不可用 Device_not_available math_state_restore 发送SIGSEGV信号
8 双重故障 Double_fault do_double_fault
9 协处理器段溢出 Coprocessor_segment_overrun do_coprocessor_segment_overrun 发送SIGFPE信号
10 无效TSS Invalid_tss do_invalid_TSS 发送SIGSEGV信号
11 缺段中断 Segment_not_present do_segment_not_present 发送SIGBUS信号
12 堆栈异常 Stack_segment do_stack_segment
13 一般保护异常 General_protection do_general_protection
14 页异常 Page_fault do_page_fault 处理缺页中断
15 Spurious_interrupt_bug do_spurious_interrupt_bug
16 协处理器出错 Coprocessor_error do_coprocessor_error 发送SIGFPE信号
17 对齐检查中断 Alignment_check do_alignment_check 发送SIGBUS信号
0x80 系统调用 ia32_syscall
0xf9 内核调试 call_debug do_call_debug

外部中断初始化

中断控制器硬件APIC分为两种:本地APIC和全局APIC。本地APIC集成在CPU内部,每个CPU都有一个,用于处理本地中断请求,CPU可以通过APIC向其他CPU发送中断,现在主要用于CPU之间的通信(IPI)。全局APIC主要是连接外部设备,用于外部设备的中断。在内核中断初始化的时候,会初始化三个与IPI相关中断。

void __init init_IRQ(void)
{int i;/*** 该函数主要是初始化硬件* 1. 初始化本地APIC控制芯片* 2. 初始化8259A芯片/init_ISA_irqs();/** 清空32以后的中断向量表。(除了系统调用和内核调试用的中断号)*/for (i = 0; i < (NR_VECTORS - FIRST_EXTERNAL_VECTOR); i++) {int vector = FIRST_EXTERNAL_VECTOR + i;if (i >= NR_IRQS)break;if (vector != IA32_SYSCALL_VECTOR && vector != KDB_VECTOR) { set_intr_gate(vector, interrupt[i]);}}
// 多处理器通信中断
#ifdef CONFIG_SMPset_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]);set_intr_gate(RESCHEDULE_VECTOR, reschedule_interrupt);set_intr_gate(INVALIDATE_TLB_VECTOR, invalidate_interrupt);set_intr_gate(CALL_FUNCTION_VECTOR, call_function_interrupt);
#endif
// 本地APIC中断
#ifdef CONFIG_X86_LOCAL_APIC/* self generated IPI for local APIC timer */set_intr_gate(LOCAL_TIMER_VECTOR, apic_timer_interrupt);set_intr_gate(SPURIOUS_APIC_VECTOR, spurious_interrupt);set_intr_gate(ERROR_APIC_VECTOR, error_interrupt);
#endifsetup_timer();if (!acpi_ioapic)setup_irq(2, &irq2);
}

总结如下:

中断向量号 中断名 异常事件 中断处理函数 调用c函数 处理结果
0xfc RESCHEDULE_VECTOR 处理器间中断, 用于cpu之间同学,其他cpu要求重新调度 reschedule_interrupt smp_reschedule_interrupt 将线程调度标志置为需要重新调度。之后内核检查标志的时候会重新调度线程
0xfd INVALIDATE_TLB_VECTOR 处理器间中断, 用于cpu之间通信,其他cpu要求TLB缓存失效 invalidate_interrupt smp_invalidate_interrupt cpu刷新TLB
0xfa CALL_FUNCTION_VECTOR 处理器间中断, 用于cpu之间通信,让另外的cpu调用某个函数 call_function_interrupt smp_call_function_interrupt 函数数据通过call_data_struct传送,cpu会调用该函数
0xef LOCAL_TIMER_VECTOR APIC定期器中断 apic_timer_interrupt smp_apic_timer_interrupt 触发定时器的软中断
0xff SPURIOUS_APIC_VECTOR 伪中断 spurious_interrupt smp_spurious_interrupt 忽略
0xfe ERROR_APIC_VECTOR APIC错误 error_interrupt smp_error_interrupt 打印错误

0xfa中断说明:
当cpu需要另一个cpu执行某个函数时,只需要初始化

struct call_data_struct {void (*func) (void *info);void *info;atomic_t started;atomic_t finished;int wait;
};

的结构体,然后发出一个0xfa中断即可。

软中断初始化

软中断初始化分为两部分:

  1. 初始化定时器时,会打开TIMER_SOFTIRQ的软中断,并设置中断处理函数为run_timer_softirq。
  2. softirq_init函数执行,会打开TASKLET_SOFTIRQ和HI_SOFTIRQ,处理函数分别为 tasklet_action和 tasklet_hi_action。

软中断的线程处理机制就不说了。

转载于:https://www.cnblogs.com/stonehat/p/8681639.html

Linux x86_64内核中断初始化相关推荐

  1. linux中断初始化程序,Linux x86_64 内核中断初始化

    Linux x86_64 内核中断初始化 中断分类 Linux 系统中, 中断分为: 硬中断: 由外部设备或者执行异常产生的需要快速处理的中断如缺页中断定时器硬件中断 根据内部产生还是外部产生, 分为 ...

  2. 初步了解Linux内核中断初始化

    在linux内核中,用struct irq_chip结构体描述一个可编程中断控制器,它的整个结构和调度器中的调度类类似,里面定义了中断控制器的一些操作: 在中断处理中所涉及的几个重要的数据结构:中断描 ...

  3. Linux x86_64 APIC中断路由机制分析

    不同CPU体系间的中断控制器工作原理有较大差异,本文是<Linux mips64r2 PCI中断路由机制分析>的姊妹篇,主要分析Broadwell-DE X86_64 APIC中断路由原理 ...

  4. Linux x86_64内核终止D状态的进程

    在上一篇文章< Linux x86内核终止D状态的进程>中,我展示了32位x86系统中如何编码杀死D进程.本文我将展示一种64位x86系统上的方法.         说实话,64位系统上做 ...

  5. linux 命令 sys_call_table地址,Linux x86_64 内核查找sys_call_table注意事项

    /*----------------------------------------------------*/ 本文档的CopyRight归jonathan所有,可自由转载,转载时请保持文档的完整性 ...

  6. rt5350 中断初始化

    linux 下的中断初始化,实际就是对 irq_desc 这个结构体进行初始化,其中最关键莫过于 irq_flow_handler_t    handle_irq            中断处理函数 ...

  7. linux内核看门狗关闭方法,linux内核中断之看门狗

    一:内核中断 linux内核中的看门狗中断跟之前的裸板的中断差不多,在编写驱动之前,需要线把内核自带的watch dog模块裁剪掉,要不然会出现错误:在Device Drivers /Watchdog ...

  8. linux内核网络初始化,Linux内核--网络栈实现分析

    本文分析基于内核Linux Kernel 1.2.13 以后的系列博文将深入分析Linux内核的网络栈实现原理,这里看到曹桂平博士的分析后,也决定选择Linux内核1.2.13版本进行分析. 原因如下 ...

  9. Linux 内核中断内幕【转】

    转自:http://www.ibm.com/developerworks/cn/linux/l-cn-linuxkernelint/ 本文对中断系统进行了全面的分析与探讨,主要包括中断控制器.中断分类 ...

  10. c6x Linux 内核中断分析

    1. 内核中断介绍 1.1 中断简介 所有支持Linux的平台都采用了中断(interrupt)的概念,以便(因种种原因)引入周期性的中断.需要区分两种类型的中断. 1. 硬件中断(hardware ...

最新文章

  1. 近期活动盘点:高级机器学习训练营、基于神经网络的代码自动生成” “开放学术图谱”、西山金融科技产业创新论坛...
  2. oracle library cache lock,【DB】彻底搞清楚library cache lock的成因和解决方法(一)
  3. 计算机核心配件是什么,计算机的核心是什么
  4. Gen系列服务器,新计算、新体验 | 新华三全新HPE Gen10系列服务器响彻“云”端
  5. Mybatis异常_02_Result Maps collection already contains value for
  6. 04737 c++ 自学考试2019版 第四章课后练习 程序设计题 2
  7. 郁闷好久的电脑问题终于搞定---电脑经常死机
  8. docker多个容器一起打包_如何实现多个docker容器同时执行一条命令?
  9. 3.1 Zend_Db_Adapter
  10. 日历2017 年终总结新年工作汇报PPT模板免费下载_PPTX图片设计素材_包图网888pic.com...
  11. 一个计算机系统配置有3台打印机,我们是局域网3站点 3台电脑共享一个打印机 3台电脑相同的系统 打印参数也设置完全一样 但是打印出来的效果却不同 请问什么原因?需要怎么设置?...
  12. 2021年茶艺师(中级)考试内容及茶艺师(中级)考试总结
  13. 设置局域网内共享磁盘
  14. Android之使用通知栏通知的三种方法(短内容、长内容、图片通知)
  15. Reapp 混合应用 - 帮助构建前所未所的强大应用(Reapp Hybrid apps - help you build powerful apps like never before)
  16. Avoid mutating a prop directly子传父报错解决
  17. 微软在盗版黑屏事件可能犯下极大的错误
  18. 【Ruby on Rails全栈课程】4.1 点赞功能
  19. 基于matlab支持向量机SVM多分类手写体数字识别
  20. 如何在鲲鹏920安装Ubuntu

热门文章

  1. luoguP3600 随机数生成器 期望概率DP + DP优化
  2. 一、配置etcd数据库
  3. LeetCode - 不错的题目 - Longest Consecutive Sequence
  4. split() 注意事项.
  5. 01.使用File类读写文件
  6. 机器学习-斯坦福:学习笔记1-机器学习的动机与应用
  7. 【转】C#中的Stream
  8. 筛选DataTable数据的方法
  9. Bootstrap-分页插件Paginator
  10. Hibernate Annotation 设置字段的默认值