传统的中断控制器:8259A ●8259A:设置起始中断向量号 。参见arch/x86/kernel/i825932.c::init8259A() void init_8259A(int auto_eoi){ outb_pic-this has to work on a wide range of PC hardware. / outb_pic(Ox11,PIC_MASTER_CMD);ICW1:select 8259A-1 init outb_pic(0x20 0.PIC_MASTER_IMR);/ICW2:8259A-1 IRO-7 mapped to 0x20-0x27 outb_pic(1U <PIC_CASCADE_IR,PIC_MASTER_IMR);/8259A-1 (the master)has a slave on IR2◆/ if(auto_eoi)/◆master does Auto E0I◆/ outb_pic(MASTER_ICW4_DEFAULT PIC_ICW4_AEOI,PIC_MASTER_IMR): else/◆master expects normal EOI◆/ outb_pic(MASTER_ICW4_DEFAULT,PIC_MASTER_IMR): outb_pic(Ox11,PIC_SLAVE_CMD);ICWI:select 8259A-2 init * outb_pic(Ox20 8,PIC_SLAVE_IMR);ICW2:8259A-2 IRO-7 mapped to 0x28-0x2f outb_pic(PIC_CASCADE_IR,PIC_SLAVE_IMR);/8259A-2 is a slave on master's IR2/ outb_pic(SLAVE_ICW4_DEFAULT,PIC_SLAVE_IMR):/ 东香兰(xlanchenoustc,edu,cn)(计算丸应Linux状作系统分析Chapter5中断和齐家 (ctober 21.2014 15/阅
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 传统的中断控制器:8259A 8259A:设置起始中断向量号 参见arch/x86/kernel/i8259_32.c::init_8259A() . . void init_8259A(int auto_eoi) { ... /* * outb_pic - this has to work on a wide range of PC hardware. */ outb_pic(0x11, PIC_MASTER_CMD); /* ICW1: select 8259A-1 init */ outb_pic(0x20 + 0, PIC_MASTER_IMR); /* ICW2: 8259A-1 IR0-7 mapped to 0x20-0x27 */ outb_pic(1U << PIC_CASCADE_IR, PIC_MASTER_IMR); /* 8259A-1 (the master) has a slave on IR2 */ if (auto_eoi) /* master does Auto EOI */ outb_pic(MASTER_ICW4_DEFAULT | PIC_ICW4_AEOI, PIC_MASTER_IMR); else /* master expects normal EOI */ outb_pic(MASTER_ICW4_DEFAULT, PIC_MASTER_IMR); outb_pic(0x11, PIC_SLAVE_CMD); /* ICW1: select 8259A-2 init */ outb_pic(0x20 + 8, PIC_SLAVE_IMR); /* ICW2: 8259A-2 IR0-7 mapped to 0x28-0x2f */ outb_pic(PIC_CASCADE_IR, PIC_SLAVE_IMR); /* 8259A-2 is a slave on master’s IR2 */ outb_pic(SLAVE_ICW4_DEFAULT, PIC_SLAVE_IMR); /* ... } 陈香兰(xlanchen@ustc.edu.cn) (计算机应用教研室 Linux操作系统分析Chapter 5 中断和异常 @计算机学院嵌入式系统实验室@苏州研究院中国科学技术大学Fall 2014) October 21, 2014 15 / 69
传统的中断控制器:8259A ● 8259A:禁止/激活某个IRQ线,参见arch/x86/kerne1/i825932.c void disable_8259A_irg(unsigned int irq){ unsigned int mask I <irq; unsigned long flags; spin_lock_irqsave(&i8259A_lock,flags): cached_irq_mask mask:; if (irq&8) outb(cached_slave_mask,PIC_SLAVE_IMR); else outb(cached_master_mask,PIC_MASTER_IMR): spin_unlock_irgrestore(&i8259A_lock,flags): unsigned int cached_irq_mask Oxffff; inc1ude/asm-x86/i8259.h中: #define_byte(x.y)(((unsigned char )&(y))[x]) #define cached_master_mask (_byte(0,cached_irq_mask)) #define cached_slave_mask (byte(1,cached_irq_mask)) 陈香兰(x1 anchenoustc,edu,cn)(计算丸应Linux禄作系统分折Chapter5中断和并常 (ctober 21.2014 15/阅
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 传统的中断控制器:8259A 8259A:禁止/激活某个IRQ线,参见arch/x86/kernel/i8259_32.c . . void disable_8259A_irq(unsigned int irq) { unsigned int mask = 1 << irq; unsigned long flags; spin_lock_irqsave(&i8259A_lock, flags); cached_irq_mask |= mask; if (irq & 8) outb(cached_slave_mask, PIC_SLAVE_IMR); else outb(cached_master_mask, PIC_MASTER_IMR); spin_unlock_irqrestore(&i8259A_lock, flags); } . . ... unsigned int cached_irq_mask = 0xffff; . . include/asm-x86/i8259.h中: #define __byte(x, y) (((unsigned char *)&(y))[x]) #define cached_master_mask (__byte(0, cached_irq_mask)) #define cached_slave_mask (__byte(1, cached_irq_mask)) 陈香兰(xlanchen@ustc.edu.cn) (计算机应用教研室 Linux操作系统分析Chapter 5 中断和异常 @计算机学院嵌入式系统实验室@苏州研究院中国科学技术大学Fall 2014) October 21, 2014 15 / 69
传统的中断控制器:8259A ● 8259A:禁止/激活某个IRQ线,参见arch/x86/kerne1/i825932.c void enable_8259A_irq(unsigned int irq){ unsigned int mask =(1 <irq); unsigned long flags; spin_lock_irqsave(&i8259A_lock,flags): cached_irq_mask &mask; if (irq&8) outb(cached_slave_mask,PIC_SLAVE_IMR); else outb(cached_master_mask,PIC_MASTER_IMR): spin_unlock_irgrestore(&i8259A_lock,flags): unsigned int cached_irq_mask Oxffff; inc1ude/asm-x86/i8259.h中: #define_byte(x.y)(((unsigned char )&(y))[x]) #define cached_master_mask (_byte(0,cached_irq_mask)) #define cached_slave_mask (byte(1,cached_irq_mask)) 陈香兰(x1 anchenoustc,edu,cn)(计算丸应Linux禄作系统分折Chapter5中断和并常 (ctober 21.2014 15/阅
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 传统的中断控制器:8259A 8259A:禁止/激活某个IRQ线,参见arch/x86/kernel/i8259_32.c . . void enable_8259A_irq(unsigned int irq) { unsigned int mask = ~(1 << irq); unsigned long flags; spin_lock_irqsave(&i8259A_lock, flags); cached_irq_mask &= mask; if (irq & 8) outb(cached_slave_mask, PIC_SLAVE_IMR); else outb(cached_master_mask, PIC_MASTER_IMR); spin_unlock_irqrestore(&i8259A_lock, flags); } . . ... unsigned int cached_irq_mask = 0xffff; . . include/asm-x86/i8259.h中: #define __byte(x, y) (((unsigned char *)&(y))[x]) #define cached_master_mask (__byte(0, cached_irq_mask)) #define cached_slave_mask (__byte(1, cached_irq_mask)) 陈香兰(xlanchen@ustc.edu.cn) (计算机应用教研室 Linux操作系统分析Chapter 5 中断和异常 @计算机学院嵌入式系统实验室@苏州研究院中国科学技术大学Fall 2014) October 21, 2014 15 / 69
异常 。X86处理器发布了大约20种不同的异常。 ·某些异常通过硬件出错码说明跟异常相关的信息 ·内核为每个异常提供了一个专门的异常处理程序 # Exception type Exception handler Signal 0 Divide error fault divide_error() SIGFPE Debug fault/trap debug() SIGTRAP 2 NMI interrupt nmi() None 3 Breakpoint trap int3() SIGTRAP 4 Overflow trap overflow() SIGSEGV 5 Bounds check fault bounds() SIGSEGV 6 Invalid opcode fault invalid_op() SIGILL 7 Device not available fault device_not_available() SIGSEGV 8 Double fault Abort double_fault() SIGSEGV Coprocessor segment overrun fault coprocessor_segment_overrun() SIGFPE 香兰(x1 anchenoustc,edu,cn)(计算机应Linux根作系统分折Chapter5中断和齐常 (ctober 21.2014 16/6阅
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 异常 X86处理器发布了大约20种不同的异常。 某些异常通过硬件出错码说明跟异常相关的信息 内核为每个异常提供了一个专门的异常处理程序 # Exception type Exception handler Signal 0 Divide error fault divide_error() SIGFPE 1 Debug fault/trap debug() SIGTRAP 2 NMI interrupt nmi() None 3 Breakpoint trap int3() SIGTRAP 4 Overflow trap overflow() SIGSEGV 5 Bounds check fault bounds() SIGSEGV 6 Invalid opcode fault invalid_op() SIGILL 7 Device not available fault device_not_available() SIGSEGV 8 Double fault Abort double_fault() SIGSEGV 9 Coprocessor segment overrun fault coprocessor_segment_overrun() SIGFPE 陈香兰(xlanchen@ustc.edu.cn) (计算机应用教研室 Linux操作系统分析Chapter 5 中断和异常 @计算机学院嵌入式系统实验室@苏州研究院中国科学技术大学Fall 2014) October 21, 2014 16 / 69
异常 # Exception type Exception handler Signal 10 Invalid TSS fault invalid_tss() SIGSEGV 11 Segment not present fault segment_not_present() SIGBUS 12 Stack exception fault stack_segment() SIGBUS 13 General protection fault general_protection() SIGSEGV 14 Page Fault fault page_fault() SIGSEGV 15 Intel reserved None None 16 Floating-pointer error fault coprocessor_error SIGFPE 17 Alignment check fault alignment_check() SIGBUS 18 Machine check Abort machine_check() None 19 SIMD floating point fault simd_coprocessor_error() SIGFPE 1口4四是42月00 陈香兰(x1 anchenoustc,edu,cn)(计算丸应Linux禄作系统分折Chapter5中断和并常 0 ctober21,201416/阅
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 异常 # Exception type Exception handler Signal 10 Invalid TSS fault invalid_tss() SIGSEGV 11 Segment not present fault segment_not_present() SIGBUS 12 Stack exception fault stack_segment() SIGBUS 13 General protection fault general_protection() SIGSEGV 14 Page Fault fault page_fault() SIGSEGV 15 Intel reserved - None None 16 Floating-pointer error fault coprocessor_error SIGFPE 17 Alignment check fault alignment_check() SIGBUS 18 Machine check Abort machine_check() None 19 SIMD floating point fault simd_coprocessor_error() SIGFPE 陈香兰(xlanchen@ustc.edu.cn) (计算机应用教研室 Linux操作系统分析Chapter 5 中断和异常 @计算机学院嵌入式系统实验室@苏州研究院中国科学技术大学Fall 2014) October 21, 2014 16 / 69