init_ir_技术实现篇
1. 中断的初始化
中断向量号是8位的,那么它一共有256项(0-255),所以中断描述符表最多只有256项,中断向量表也是256项。
对于不同的中断,在中断初始化和中断处理过程中,其处理方式是不一样的,尤其是不同类型的中断,其处理响应机制差别较大,后面会详述。这里先描述中断的初始化过程。
从中断触发的源角度,可以将中断分为内部中断(0~31号中断向量号)和外部中断(32~255号中断向量号),linux初始化过程中,会先初始化内部中断,再初始化外部中断。这两种中断的初始化区别如下:
1. 内部中断(0~31号、0x80作为中断号)
只要初始化:
1) 相关的中断向量表
2. 外部中断(0~255中的除了0~31号、0x80的其他中断号)
需要初始化:
1) 相关的中断向量表
2) 以及中断控制器(控制器负责优先级排队、屏蔽等工作)
0x1: 内部中断初始化
内部中断的初始化需要对0~31号和0x80号系统保留中断向量的初始化,这部分草走在trap_init()中完成
\linux-3.15.5\arch\x86\kernel\traps

void __init trap_init(void)
{
int i; #ifdef CONFIG_EISA
void __iomem *p = early_ioremap(0x0FFFD9, 4); if (readl(p) == 'E' + ('I'<<8) + ('S'<<16) + ('A'<<24))
EISA_bus = 1;
early_iounmap(p, 4);
#endif
/*
trap_init()主要是调用set_xxx_gate(中断向量, 中断处理函数)
set_xxx_gate()就是按照中断门的格式填写中断向量表的 Intel x86支持4种"门描述符":
1) 调用门(call gate)
2) 陷阱门(trap gate)
3) 中断门(iinterrupt gate)
4) 任务门(task gate)
*/
set_intr_gate(X86_TRAP_DE, divide_error);
set_intr_gate_ist(X86_TRAP_NMI, &nmi, NMI_STACK);
/* int4 can be called from all */
set_system_intr_gate(X86_TRAP_OF, &overflow);
set_intr_gate(X86_TRAP_BR, bounds);
set_intr_gate(X86_TRAP_UD, invalid_op);
set_intr_gate(X86_TRAP_NM, device_not_available);
#ifdef CONFIG_X86_32
set_task_gate(X86_TRAP_DF, GDT_ENTRY_DOUBLEFAULT_TSS);
#else
set_intr_gate_ist(X86_TRAP_DF, &double_fault, DOUBLEFAULT_STACK);
#endif
set_intr_gate(X86_TRAP_OLD_MF, coprocessor_segment_overrun);
set_intr_gate(X86_TRAP_TS, invalid_TSS);
set_intr_gate(X86_TRAP_NP, segment_not_present);
set_intr_gate_ist(X86_TRAP_SS, &stack_segment, STACKFAULT_STACK);
set_intr_gate(X86_TRAP_GP, general_protection);
set_intr_gate(X86_TRAP_SPURIOUS, spurious_interrupt_bug);
set_intr_gate(X86_TRAP_MF, coprocessor_error);
set_intr_gate(X86_TRAP_AC, alignment_check);
#ifdef CONFIG_X86_MCE
set_intr_gate_ist(X86_TRAP_MC, &machine_check, MCE_STACK);
#endif
set_intr_gate(X86_TRAP_XF, simd_coprocessor_error); /* Reserve all the builtin and the syscall vector: */
for (i = 0; i < FIRST_EXTERNAL_VECTOR; i++)
set_bit(i, used_vectors); #ifdef CONFIG_IA32_EMULATION
set_system_intr_gate(IA32_SYSCALL_VECTOR, ia32_syscall);
set_bit(IA32_SYSCALL_VECTOR, used_vectors);
#endif
//设置系统调用中断
#ifdef CONFIG_X86_32
set_system_trap_gate(SYSCALL_VECTOR, &system_call);
set_bit(SYSCALL_VECTOR, used_vectors);
#endif /*
* Set the IDT descriptor to a fixed read-only location, so that the
* "sidt" instruction will not leak the location of the kernel, and
* to defend the IDT against arbitrary memory write vulnerabilities.
* It will be reloaded in cpu_init() */
__set_fixmap(FIX_RO_IDT, __pa_symbol(idt_table), PAGE_KERNEL_RO);
idt_descr.address = fix_to_virt(FIX_RO_IDT); /*
* Should be a barrier for any external CPU state:
*/
cpu_init(); x86_init.irqs.trap_init(); #ifdef CONFIG_X86_64
memcpy(&debug_idt_table, &idt_table, IDT_ENTRIES * 16);
set_nmi_gate(X86_TRAP_DB, &debug);
set_nmi_gate(X86_TRAP_BP, &int3);
#endif
}

0x2: 外部中断初始化
外部中断的初始化需要:
1. 对除了0~31、0x80中断号之外的其它中断向量
2. 中断控制器的初始化(相比内部中断初始化多了这一步)
这两步操作都在在init_IRQ()中完成
\linux-3.15.5\arch\x86\kernel\i8259.c

void __init init_IRQ(void)
{
int i; /*
* We probably need a better place for this, but it works for
* now ...
*/
x86_add_irq_domains(); /*
* On cpu 0, Assign IRQ0_VECTOR..IRQ15_VECTOR's to IRQ 0..15.
* If these IRQ's are handled by legacy interrupt-controllers like PIC,
* then this configuration will likely be static after the boot. If
* these IRQ's are handled by more mordern controllers like IO-APIC,
* then this vector space can be freed and re-used dynamically as the
* irq's migrate etc.
*/
for (i = 0; i < legacy_pic->nr_legacy_irqs; i++) //对于单CPU结构,
per_cpu(vector_irq, 0)[IRQ0_VECTOR + i] = i; //x86_init.irqs.intr_init()等价于调用:native_init_IRQ()
x86_init.irqs.intr_init();
} void __init native_init_IRQ(void)
{
int i; /* Execute any quirks before the call gates are initialised: */
x86_init.irqs.pre_vector_init(); //调用 init_ISA_irqs apic_intr_init(); /*
* Cover the whole vector space, no vector can escape
* us. (some of these will be overridden and become
* 'special' SMP interrupts)
*/
/*
interrupt数组,它保存的是每个中断服务程序的入口地址,它的定义是在\linux-3.15.5\arch\x86\kernel\entry_32.S中
*/
for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++)
{
//设置32~255号中断
/* IA32_SYSCALL_VECTOR could be used in trap_init already. */
if (!test_bit(i, used_vectors))
{
//要除去0x80中断
set_intr_gate(i, interrupt[i-FIRST_EXTERNAL_VECTOR]);
}
} if (!acpi_ioapic && !of_ioapic)
setup_irq(2, &irq2); #ifdef CONFIG_X86_32
/*
* External FPU? Set up irq13 if so, for
* original braindamaged IBM FERR coupling.
*/
if (boot_cpu_data.hard_math && !cpu_has_fpu)
setup_irq(FPU_IRQ, &fpu_irq); irq_ctx_init(smp_processor_id());
#endif
}
init_ir_技术实现篇的更多相关文章
- Android插件化技术——原理篇
<Android插件化技术——原理篇> 转载:https://mp.weixin.qq.com/s/Uwr6Rimc7Gpnq4wMFZSAag?utm_source=androi ...
- iOS开发——网络使用技术OC篇&网络爬虫-使用正则表达式抓取网络数据
网络爬虫-使用正则表达式抓取网络数据 关于网络数据抓取不仅仅在iOS开发中有,其他开发中也有,也叫网络爬虫,大致分为两种方式实现 1:正则表达 2:利用其他语言的工具包:java/Python 先来看 ...
- iOS开发之多线程技术——NSOperation篇
本篇将从四个方面对iOS开发中使用到的NSOperation技术进行讲解: 一.什么是NSOperation 二.我们为什么使用NSOperation 三.在实际开发中如何使用NSOperation ...
- iOS开发之多线程技术——GCD篇
本篇将从四个方面对iOS开发中GCD的使用进行详尽的讲解: 一.什么是GCD 二.我们为什么要用GCD技术 三.在实际开发中如何使用GCD更好的实现我们的需求 一.Synchronous & ...
- android apk 防止反编译技术第一篇-加壳技术
做android framework方面的工作将近三年的时间了,现在公司让做一下android apk安全方面的研究,于是最近就在网上找大量的资料来学习.现在将最近学习成果做一下整理总结.学习的这些成 ...
- iOS开发之多线程技术—GCD篇
本篇将从四个方面对iOS开发中GCD的使用进行详尽的讲解: 一.什么是GCD 二.我们为什么要用GCD技术 三.在实际开发中如何使用GCD更好的实现我们的需求 一.Synchronous & ...
- android apk 防止反编译技术第二篇-运行时修改字节码
上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372.接下来我们将介绍另一种防止a ...
- android apk 防止反编译技术第二篇-运行时修改Dalvik指令
上一篇我们讲了apk防止反编译技术中的加壳技术,如果有不明白的可以查看我的上一篇博客http://my.oschina.net/u/2323218/blog/393372.接下来我们将介绍另一种防止a ...
- 2020 年了,Java 日志框架到底哪个性能好?——技术选型篇
大家好,之前写(shui)了两篇其他类型的文章,感觉大家反响不是很好,于是我乖乖的回来更新硬核技术文了. 经过本系列前两篇文章我们了解到日志框架大战随着 SLF4j 的一统天下而落下帷幕,但 SLF4 ...
随机推荐
- std::string 用法总结
标准C++中的string类的用法总结 相信使用过MFC编程的朋友对CString这个类的印象应该非常深刻吧?的确,MFC中的CString类使用起来真的非常的方便好用.但是如果离开了MFC框架,还有 ...
- 安装oracle11g不能启动图形化界面
问题:安装oracle11g时出现xhost: unable to open display "192.168.2.12:0.0".打不开图形化界面等. 终极解决方法:1.使用X ...
- ios程序中存储的回忆
可编程序中的存储区域基本上分为:静态存储区,栈区,堆区,代码区. 1.静态存储区(全局存储区):该块内存在程序编译期间就已经分配好,并且在程序运行期间都一直存在,主要用于存储静态数据,全局数据和常量. ...
- Groovy 反射字符串常量方法
Keywords: Groovy, Reflection, 反射 The Reflection of Groovy String constant style method. Groovy支持以下的方 ...
- JAVA自学作业03
JAVA自学作业03 1.请用最有效率的方式计算2*8的结果 使用位运算是最有效率的. System.out.println(2<<3); 2.请交换两整数的值 int x = 10; i ...
- SpringMVC(2)—SpringMVC整合Spring的HelloWorld
一.这是一个SpringMVC框架的案例HelloWorld 功能:HelloWorld 二.SpringMVC运行流程 1.流程 请求-->springDispatcherServlet的ur ...
- spring注解之@profile
spring中@profile与maven中的profile很相似,通过配置来改变参数. 例如在开发环境与生产环境使用不同的参数,可以配置两套配置文件,通过@profile来激活需要的环境,但维护两套 ...
- 咏南新BS开发框架
咏南新BS开发框架 咏南WEB框架支持负载均衡群集. 咏南WEB桌面框架演示:47.106.93.126:9999 咏南WEB手机框架本地:47.106.93.126:8077 咏南CS框架下载:ht ...
- Map network drive遇到报错“The network folder specified is currently mapped using a different user name and password”,怎么办?
--------------------------- Windows --------------------------- The network folder specified is curr ...
- HRMS(人力资源管理系统)-从单机应用到SaaS应用-系统介绍
上周发布的<2018,全新出发(全力推动实现住有所居)>文章,其中记录了个人在这5年过程中的成长和收获,有幸认识了不少博客园的朋友,大家一起学习交流,在这个过程当中好多朋友提出SaaS系统 ...