diff --git "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--ioapic.md" "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--ioapic.md" index 51048a8..e69de29 100755 --- "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--ioapic.md" +++ "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--ioapic.md" @@ -1,13 +0,0 @@ -irq_desc 数组有 NR_IRQS 个元素, NR_IRQS 并不是 256-32(!!!), 实际上, 虽然中断描述符表中一共有 256 项(前 32 项用作异常和 intel 保留), 但并不是所有中断向量都会使用到, 所以中断描述符数组也不一定是 256-32 项, CPU 可以使用多少个中断是由中断控制器(PIC、APIC)或者内核配置决定的, 我们看看 NR_IRQS 的定义 -```c -/* IOAPIC 为外部中断控制器 */ -#ifdef CONFIG_X86_IO_APIC -#define CPU_VECTOR_LIMIT (64 * NR_CPUS) -#define NR_IRQS \ - (CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ? \ - (NR_VECTORS + CPU_VECTOR_LIMIT) : \ - (NR_VECTORS + IO_APIC_VECTOR_LIMIT)) -#else /* !CONFIG_X86_IO_APIC: NR_IRQS_LEGACY = 16 */ -#define NR_IRQS NR_IRQS_LEGACY -#endif -``` \ No newline at end of file diff --git "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\344\270\255\346\226\255\345\217\267\346\230\240\345\260\204.md" "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\344\270\255\346\226\255\345\217\267\346\230\240\345\260\204.md" index 6da97f3..a2d18f9 100755 --- "a/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\344\270\255\346\226\255\345\217\267\346\230\240\345\260\204.md" +++ "b/linux/\345\206\205\346\240\270-\351\251\261\345\212\250/\344\270\255\346\226\255/\347\241\254\344\270\255\346\226\255--\344\270\255\346\226\255\345\217\267\346\230\240\345\260\204.md" @@ -103,4 +103,47 @@ out_free_desc: return ret; } -``` \ No newline at end of file +``` + +Linux内核支持众多的处理器体系结构,因此从系统角度来看,Linux内核中断管理可以分成如下4层。 + +硬件层,例如CPU和中断控制器的连接。 +处理器架构管理,例如CPU中断异常处理。 +中断控制器管理,例如IRQ中断号的映射。 +Linux内核通用中断处理器层,例如中断注册和中断处理。 + +注册中断API函数request_irq()/ request_threaded_irq()是使用Linux内核软件中断号(俗称软件中断号或IRQ中断号),而不是硬件中断号 +```c +/* include/linux/interrupt.h */ +int request_threaded_irq (unsigned int irq, irq_handler_t handler, + irq_handler_t thread_fn, unsigned long irqflags, + const char *devname, void *dev_id) +``` + +其中,参数irq在Linux内核中称为IRQ number或 interrpt line,这是一个Linux内核管理的虚拟中断号,并不是指硬件的中断号。 + +内核中有一个宏NR_IRQS来表示系统支持中断数量的最大值,NR_IRQS和平台相关. + +例如VexpressV2P-CA15_CA7平台的定义。 + +# x86 +irq_desc 数组有 NR_IRQS 个元素, NR_IRQS 并不是 256-32(!!!), 实际上, 虽然中断描述符表中一共有 256 项(前 32 项用作异常和 intel 保留), 但并不是所有中断向量都会使用到, 所以中断描述符数组也不一定是 256-32 项, CPU 可以使用多少个中断是由中断控制器(PIC、APIC)或者内核配置决定的, 我们看看 NR_IRQS 的定义 +```c +/* IOAPIC 为外部中断控制器 */ +#ifdef CONFIG_X86_IO_APIC +#define CPU_VECTOR_LIMIT (64 * NR_CPUS) +#define NR_IRQS \ + (CPU_VECTOR_LIMIT > IO_APIC_VECTOR_LIMIT ? \ + (NR_VECTORS + CPU_VECTOR_LIMIT) : \ + (NR_VECTORS + IO_APIC_VECTOR_LIMIT)) +#else /* !CONFIG_X86_IO_APIC: NR_IRQS_LEGACY = 16 */ +#define NR_IRQS NR_IRQS_LEGACY +#endif +``` + +此外, Linux内核定义了一个位图(!!!无论是R树存储描述符还是数组存放, 这个位图可用来分配irq!!!)来管理这些中断号 +/* [kernel/irq/irqdesc.c] */ +#define IRQ_BITMAP_BITS NR_IRQS +static DECLARE_BITMAP (allocated_irqs, IRQ_BITMAP_BITS); + +位图变量allocated_irqs分配NR_IRQS比特位(!!!无论是R树存储描述符还是数组存放, 这个位图用来分配irq!!!),每个比特位表示一个中断号。