• [Fw]初探linux中断系统(2)


    初探linux中断系统(2)

    中断系统初始化的过程

    用来初始化中断系统的函数位于arch/x86/kernel/irqinit.c,定义如下

    复制代码
    void __init init_IRQ(void)
    {
    int i;

    /*
    * 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++)
    per_cpu(vector_irq,
    0)[IRQ0_VECTOR + i] = i;

    x86_init.irqs.intr_init();
    }
    复制代码

    函数写的很简单,留下的疑问是x86_init是做什么的?

    在arch/x86/include/asm/x86_init.h中可以找到,x86_init是一个x86_init_ops类型的结构体,其中irqs是一个x86_init_irqs类型的结构体。

    struct x86_init_irqs {
    void (*pre_vector_init)(void);
    void (*intr_init)(void);
    void (*trap_init)(void);
    };

    在arch/x86/kernel/x86_init.c中找到x86_init的初始默认赋值:

    复制代码
    struct x86_init_ops x86_init __initdata = {

    ...

    .irqs
    = {
    .pre_vector_init
    = init_ISA_irqs,
    .intr_init
    = native_init_IRQ,
    .trap_init
    = x86_init_noop,
    },

    ...
    };
    复制代码

    对于这几个函数,我们又要回到开头的irqinit.c中来寻找了。先看之前调用的intr_init,也就是native_init_IRQ:

    复制代码
    void __init native_init_IRQ(void)
    {
    int i;

    /* Execute any quirks before the call gates are initialised: */
    x86_init.irqs.pre_vector_init();

    apic_intr_init();

    /*
    * Cover the whole vector space, no vector can escape
    * us. (some of these will be overridden and become
    * 'special' SMP interrupts)
    */
    for (i = FIRST_EXTERNAL_VECTOR; i < NR_VECTORS; i++) {
    /* IA32_SYSCALL_VECTOR could be used in trap_init already. */
    if (!test_bit(i, used_vectors))
    set_intr_gate(i, interrupt[i
    -FIRST_EXTERNAL_VECTOR]);
    }

    if (!acpi_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
    }
    复制代码

    其中pre_vector_init对应着init_ISA_irqs,主要完成了irq_desc的初始化分配。

    复制代码
    void __init init_ISA_irqs(void)
    {
    int i;

    #if defined(CONFIG_X86_64) || defined(CONFIG_X86_LOCAL_APIC)
    init_bsp_APIC();
    #endif
    legacy_pic
    ->init(0);

    /*
    * 16 old-style INTA-cycle interrupts:
    */
    for (i =0; i < legacy_pic->nr_legacy_irqs; i++) {
    struct irq_desc *desc = irq_to_desc(i);

    desc
    ->status = IRQ_DISABLED;
    desc
    ->action = NULL;
    desc
    ->depth =1;

    set_irq_chip_and_handler_name(i,
    &i8259A_chip,
    handle_level_irq,
    "XT");
    }
    }
    复制代码

    完成数据结构的初始化后就是对硬件资源的分配了,不做深究。

    在完成初始化后,每当用户request一个新的中断操作后,成功注册将更新系统维护的链表,具体可见前篇。

  • 相关阅读:
    tornado用户验证
    tornado cookie安全性
    XSS攻击
    《R语言入门》语言及环境简单介绍
    angular学习(十五)——Provider
    Tomcat 8(九)解读Tomcat组件的生命周期(Lifecycle)
    Windows之Xmanager连接linux打开Oracle视图操作
    CreateEvent和SetEvent及WaitForSingleObject的使用方法
    利用Sharepoint 创建轻量型应用之基本功能配置!
    android开发源代码分析--多个activity调用多个jni库的方法
  • 原文地址:https://www.cnblogs.com/bittorrent/p/3373580.html
Copyright © 2020-2023  润新知