Linux x86_64 内核中断初始化

中断分类

Linux 系统中, 中断分为:

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

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

异常: 异常是内部产生的中断, 不可屏蔽

外部中断: 外部中断是由外部设备产生的, 可以屏蔽

软中断:

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

内核初始化 - 中断

intel 处理器有 256 个硬中断号其中前 32 个中断号为异常使用, 在内核初始化的时候进行初始化内核初始化的代码流程如下:

可以看到首先初始化异常处理, 再初始化部分外部中断, 再初始化一部分软中断处理asmlinkagevoid__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,÷_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);

#ifdefCONFIG_X86_MCE

set_intr_gate_ist(18,&machine_check,MCE_STACK);

#endif

set_intr_gate(19,&simd_coprocessor_error);

#ifdefCONFIG_IA32_EMULATION

set_system_gate(IA32_SYSCALL_VECTOR,ia32_syscall);

#endif

set_intr_gate(KDB_VECTOR,call_debug);

/*

* Should be a barrier for any external CPU state.

*/

cpu_init();

}

总结如下:中断向量号异常事件Linux 的处理程序0除法错误Divide_error

1调试异常Debug

2NMI 中断Nmi

3单字节,int 3Int3

4溢出Overflow

5边界监测中断Bounds

6无效操作码Invalid_op

7设备不可用Device_not_available

8双重故障Double_fault

9协处理器段溢出Coprocessor_segment_overrun

10无效 TSSIncalid_tss

11缺段中断Segment_not_present

12堆栈异常Stack_segment

13一般保护异常General_protection

14页异常Page_fault

15Spurious_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_errordo_divide_error发送 SIGFPE 信号

1调试异常Debugdo_debug发送 SIGTRAP 信号

2NMI 中断Nmido_nmi

3单字节,int 3Int3do_int3发送 SIGTRAP 信号

4溢出Overflowdo_overflow发送 SIGSEGV 信号

5边界监测中断Boundsdo_bounds发送 SIGSEGV 信号

6无效操作码Invalid_opdo_invalid_op发送 SIGILL 信号

7设备不可用Device_not_availablemath_state_restore发送 SIGSEGV 信号

8双重故障Double_faultdo_double_fault

9协处理器段溢出Coprocessor_segment_overrundo_coprocessor_segment_overrun发送 SIGFPE 信号

10无效 TSSInvalid_tssdo_invalid_TSS发送 SIGSEGV 信号

11缺段中断Segment_not_presentdo_segment_not_present发送 SIGBUS 信号

12堆栈异常Stack_segmentdo_stack_segment

13一般保护异常General_protectiondo_general_protection

14页异常Page_faultdo_page_fault处理缺页中断

15Spurious_interrupt_bugdo_spurious_interrupt_bug

16协处理器出错Coprocessor_errordo_coprocessor_error发送 SIGFPE 信号

17对齐检查中断Alignment_checkdo_alignment_check发送 SIGBUS 信号

0x80系统调用ia32_syscall

0xf9内核调试call_debugdo_call_debug

外部中断初始化

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

{

inti;

/**

* 该函数主要是初始化硬件

* 1. 初始化本地 APIC 控制芯片

* 2. 初始化 8259A 芯片

/

init_ISA_irqs();

/*

* 清空 32 以后的中断向量表(除了系统调用和内核调试用的中断号)

*/

for(i=0;i

intvector=FIRST_EXTERNAL_VECTOR+i;

if(i>=NR_IRQS)

break;

if(vector!=IA32_SYSCALL_VECTOR&&vector!=KDB_VECTOR){

set_intr_gate(vector,interrupt[i]);

}

}

// 多处理器通信中断

#ifdefCONFIG_SMP

set_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 中断

#ifdefCONFIG_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);

#endif

setup_timer();

if(!acpi_ioapic)

setup_irq(2,&irq2);

}

总结如下:中断向量号中断名异常事件中断处理函数调用 c 函数处理结果0xfcRESCHEDULE_VECTOR处理器间中断, 用于 cpu 之间同学,其他 cpu 要求重新调度reschedule_interruptsmp_reschedule_interrupt将线程调度标志置为需要重新调度。之后内核检查标志的时候会重新调度线程

0xfdINVALIDATE_TLB_VECTOR处理器间中断, 用于 cpu 之间通信,其他 cpu 要求 TLB 缓存失效invalidate_interruptsmp_invalidate_interruptcpu 刷新 TLB

0xfaCALL_FUNCTION_VECTOR处理器间中断, 用于 cpu 之间通信,让另外的 cpu 调用某个函数call_function_interruptsmp_call_function_interrupt函数数据通过 call_data_struct 传送,cpu 会调用该函数

0xefLOCAL_TIMER_VECTORAPIC 定期器中断apic_timer_interruptsmp_apic_timer_interrupt触发定时器的软中断

0xffSPURIOUS_APIC_VECTOR伪中断spurious_interruptsmp_spurious_interrupt忽略

0xfeERROR_APIC_VECTORAPIC 错误error_interruptsmp_error_interrupt打印错误

0xfa 中断说明:

当 cpu 需要另一个 cpu 执行某个函数时, 只需要初始化structcall_data_struct{

void(*func)(void*info);

void*info;

atomic_tstarted;

atomic_tfinished;

intwait;

};

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

软中断初始化

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

初始化定时器时, 会打开 TIMER_SOFTIRQ 的软中断, 并设置中断处理函数为 run_timer_softirq

softirq_init 函数执行, 会打开 TASKLET_SOFTIRQ 和 HI_SOFTIRQ, 处理函数分别为 tasklet_action 和 tasklet_hi_action

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

来源: https://www.cnblogs.com/stonehat/p/8681639.html

linux中断初始化程序,Linux x86_64 内核中断初始化相关推荐

  1. linux 中断 应用程序,Linux中断编程

    本文转载自[微信公众号:机械猿,ID:on_ourway]经微信公众号授权转载,如需转载与原文作者联系 基本概念 中断是指CPU在执行程序时,由于内外部事件或由程序预先安排的事件,导致CPU 暂停当前 ...

  2. linux连接到程序,Linux下C程序的链接过程

    今天看到一个很有意思的小程序,它让我对Linux下C程序的编译链接有了一个全新的认识! 这个程序的就是写一个简单的输出"hello World!": 要求:1.不使用C运行库,写一 ...

  3. linux 查找某个程序,Linux查找特定程序whereis实例详解

    Linux 查找特定程序 whereis whereis 命令主要用于查找程序文件,并提供这个文件的二进制可执行文件.源代码文件和使用手册存放位置. 1.查找命令程序 例如,查找 touch 命令 [ ...

  4. linux亮度调节程序,linux调节屏幕亮度

    新建三个文本文件并给予执行权限: up.sh if [ ! -w /sys/class/backlight/intel_backlight/brightness ];then echo "p ...

  5. linux服务端 程序,linux服务端程序tunning过程简要总结

    8种机械键盘轴体对比 本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选? 步骤1:网络丢包的原因定位 ethtool -S eth0 rx_dropped代表丢包发生在linux 内核缓冲区,丢 ...

  6. 嵌入式linux如何下载程序,Linux平台的下载程序-嵌入式系统-与非网

    有许多网络文件下载工具可以在Windows平台下很好地工作,如NetAnts."网际快车".TelePro等,还有像WebZip那样功能强大的离线浏览器.这些工具使我们可以在Win ...

  7. linux rcs 应用程序,Linux下的rcS文件的一些分析

    由于init=/linuxrc, 因此,在文件系统挂载后,运行的第一个程序就是根目录下的linuxrc,而这是一个指向/bin/busybox的链接,因此,系统起来后运行的第一个程序就是busybox ...

  8. linux文件读取程序,Linux系统编程:文件的读取写入

    一.read系统调用 一旦有了与一个打开文件描述相关连的文件描述符,只要该文件是用O_RDONLY或O_RDWR标志打开的,就可以用read()系统调用从该文件中读取字节 函数原型: ssize_t ...

  9. linux运行vb程序,Linux可执行文件ELF结构及程序加载运行

    Linux下ELF文件类型分为以下几种: 1.可重定位文件,例如SimpleSection.o: 2.可执行文件,例如/bin/bash: 3.共享目标文件,例如/lib/libc.so. 在Linu ...

最新文章

  1. 【青少年编程】【四级】创意画图
  2. python之进程和线程的对比
  3. 是同步方法还是 synchronized 代码?-- 详解多线程同步规则
  4. php 微信 返回,php版微信返回用户text输入的方法
  5. C语言通过用户输入将八进制转换为十六进制(附完整源码)
  6. java 获取光标_如何在java中使用Windows API获取当前鼠标光标类型?
  7. 《vue2.0基础系列》目录大全,你要的都在这里
  8. npm查找全局安装包命令
  9. php对象复制,PHP 对象复制 - 对象复制 - phpStudy
  10. MyCat基于MySQL实现主从切换
  11. Eclipse主题与Monaco字体
  12. 【javaEE】——多线程进阶(锁策略:面试相关考点)04
  13. java jdk生成安卓app证书
  14. python label背景透明_如何使tkinter标签的背景透明,以便只看到文本?
  15. 电脑上计算机三个键盘的使用方法,干货:全方面介绍电脑键盘各键功能与组合键使用方法...
  16. 【愚公系列】2021年12月 攻防世界-简单题-CRYPTO-005(Railfence)
  17. TP房产系统_Tphouse_tpfangchan 1.2.7升级开源版多站点多城市房产系统源码带小程序
  18. 修改Docker默认的数据目录
  19. RabbitMQ学习笔记(一)
  20. 武纺淘宝网站项目总结

热门文章

  1. 使用NPOI编辑Office(Excel)
  2. 二叉搜索树(BinarySearchTree)
  3. 读《巨人的陨落》第二部有感
  4. Unity Shader 屏幕后处理之血屏
  5. workbeach约束简称_实际工程中,经常遇到两个构件通过光滑圆柱销钉的连接,这种约束称为...
  6. springdata JPA配置
  7. 刚毕业在深圳做程序员,我来聊聊月薪1万在大城市生活能剩下多少
  8. 海康威视网络摄像机SADP软件
  9. 高血压,注意什么,预防
  10. 怎么解决上台发言紧张的问题