Chinaunix首页 | 论坛 | 博客
  • 博客访问: 106922
  • 博文数量: 40
  • 博客积分: 2058
  • 博客等级: 大尉
  • 技术积分: 409
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-07 16:49
文章分类

全部博文(40)

文章存档

2011年(3)

2010年(17)

2009年(14)

2008年(6)

我的朋友

分类: LINUX

2010-10-24 12:03:34

2010.10.8日课堂概念解析
关于中断的三个结构体:
中断控制器描述符irq_chip 和硬件相关
/**
   * struct irq_chip - hardware interrupt chip descriptor
   *
   * @name:               name for /proc/interrupts
   * @startup:            start up the interrupt (defaults to ->enable if NULL)
   * @shutdown:           shut down the interrupt (defaults to ->disable if NULL)
   * @enable:             enable the interrupt (defaults to chip->unmask if NULL)
   * @disable:            disable the interrupt
   * @ack:                start of a new interrupt
   * @mask:               mask an interrupt source
   * @mask_ack:           ack and mask an interrupt source
   * @unmask:             unmask an interrupt source
   * @eoi:                end of interrupt - chip level
   * @end:                end of interrupt - flow level
  * @set_affinity:       set the CPU affinity on SMP machines
  * @retrigger:          resend an IRQ to the CPU
  * @set_type:           set the flow type (IRQ_TYPE_LEVEL/etc.) of an IRQ
  * @set_wake:           enable/disable power-management wake-on of an IRQ
  *
  * @bus_lock:           function to lock access to slow bus (i2c) chips
  * @bus_sync_unlock:    function to sync and unlock slow bus (i2c) chips
  *
  * @release:            release function solely used by UML
  * @typename:           obsoleted by name, kept as migration helper
*/
 
struct irq_chip {
         const char      *name;
         unsigned int    (*startup)(unsigned int irq);
         void            (*shutdown)(unsigned int irq);
         void            (*enable)(unsigned int irq);
         void            (*disable)(unsigned int irq);
 
         void            (*ack)(unsigned int irq);
         void            (*mask)(unsigned int irq);
         void            (*mask_ack)(unsigned int irq);
         void            (*unmask)(unsigned int irq);
         void            (*eoi)(unsigned int irq);
 
         void            (*end)(unsigned int irq);
         int             (*set_affinity)(unsigned int irq,
                                         const struct cpumask *dest);
         int             (*retrigger)(unsigned int irq);
         int             (*set_type)(unsigned int irq, unsigned int flow_type);
         int             (*set_wake)(unsigned int irq, unsigned int on);
 
         void            (*bus_lock)(unsigned int irq);
         void            (*bus_sync_unlock)(unsigned int irq);
 
         /* Currently used only by UML, might disappear one day.*/
 #ifdef CONFIG_IRQ_RELEASE_METHOD
         void            (*release)(unsigned int irq, void *dev_id);
 #endif
         /*
          * For compatibility, ->typename is copied into ->name.
          * Will disappear.
          */
         const char      *typename;
 };

中断服务程序描述符 -- 软件实现
/**
 * struct irqaction - per interrupt action descriptor
  * @handler:    interrupt handler function
  * @flags:      flags (see IRQF_* above)
  * @name:       name of the device
  * @dev_id:     cookie to identify the device
  * @next:       pointer to the next irqaction for shared interrupts
  * @irq:        interrupt number
  * @dir:        pointer to the proc/irq/NN/name entry
  * @thread_fn:  interupt handler function for threaded interrupts
  * @thread:     thread pointer for threaded interrupts
  * @thread_flags:       flags related to @thread
  */
 struct irqaction {                                                                                                                                              
        irq_handler_t handler;
         unsigned long flags;
         const char *name;
         void *dev_id;
         struct irqaction *next;
         int irq;
         struct proc_dir_entry *dir;
         irq_handler_t thread_fn;
         struct task_struct *thread;
         unsigned long thread_flags;
 };
struct irq_2_iommu;
/**
 * struct irq_desc - interrupt descriptor
 * @irq:        interrupt number for this descriptor
 * @timer_rand_state:    pointer to timer rand state struct
 * @kstat_irqs:        irq stats per cpu
 * @irq_2_iommu:    iommu with this irq
 * @handle_irq:        highlevel irq-events handler [if NULL, __do_IRQ()]
 * @chip:        low level interrupt hardware access
 * @msi_desc:        MSI descriptor
 * @handler_data:    per-IRQ data for the irq_chip methods
 * @chip_data:        platform-specific per-chip private data for the chip
 *            methods, to allow shared chip implementations
 * @action:        the irq action chain
 * @status:        status information
 * @depth:        disable-depth, for nested irq_disable() calls
 * @wake_depth:        enable depth, for multiple set_irq_wake() callers
 * @irq_count:        stats field to detect stalled irqs
 * @last_unhandled:    aging timer for unhandled count
 * @irqs_unhandled:    stats field for spurious unhandled interrupts
 * @lock:        locking for SMP
 * @affinity:        IRQ affinity on SMP
 * @node:        node index useful for balancing
 * @pending_mask:    pending rebalanced interrupts
 * @threads_active:    number of irqaction threads currently running
 * @wait_for_threads:    wait queue for sync_irq to wait for threaded handlers
 * @dir:        /proc/irq/ procfs entry
 * @name:        flow handler name for /proc/interrupts output
 */

中断描述符表
struct irq_desc {
    unsigned int        irq;
    struct timer_rand_state *timer_rand_state;
    unsigned int            *kstat_irqs;
#ifdef CONFIG_INTR_REMAP
    struct irq_2_iommu      *irq_2_iommu;
#endif
    irq_flow_handler_t    handle_irq;
    struct irq_chip        *chip;
    struct msi_desc        *msi_desc;
    void            *handler_data;
    void            *chip_data;
    struct irqaction    *action;    /* IRQ action list */
    unsigned int        status;        /* IRQ status */

    unsigned int        depth;        /* nested irq disables */
    unsigned int        wake_depth;    /* nested wake enables */
    unsigned int        irq_count;    /* For detecting broken IRQs */
    unsigned long        last_unhandled;    /* Aging timer for unhandled count */
    unsigned int        irqs_unhandled;
    raw_spinlock_t        lock;
#ifdef CONFIG_SMP
    cpumask_var_t        affinity;
    const struct cpumask    *affinity_hint;
    unsigned int        node;
#ifdef CONFIG_GENERIC_PENDING_IRQ
    cpumask_var_t        pending_mask;
#endif
#endif
    atomic_t        threads_active;
    wait_queue_head_t       wait_for_threads;
#ifdef CONFIG_PROC_FS
    struct proc_dir_entry    *dir;
#endif
    const char        *name;
} ____cacheline_internodealigned_in_smp;
中断向量号:
   中断向量:Intel X86 的系列微机共支持256种向量中断,为使处理器可以容易地识别每种中断源,将他们从0到256进行了编号,即赋以一个中断类型码n,Intel把这个8位的无符号整数叫做向量,即中断向量。

    所有256种中断可分为两大类:异常和中断。
    异常又分为故障(fault)和陷阱(Trap),他们的共同特点是既不使用中断控制器,又不能被屏蔽。
中断又分为:外部可屏蔽中断和外部非屏蔽中断。所有I/O设备产生的中断均称引起可屏蔽中断,而紧急的事件(如硬件故障)引起的故障则产生非屏蔽中断。
    非屏蔽中断的向量和异常的向量是固定的,而可屏蔽中断的向量可以通过对中断控制器的编程来改变
Linux对256个中断向量的分配如下:
编号0~31的向量对应于异常和非屏蔽中断(中断向量类型是固定的)
编号为32~47的向量(即由I/O设备引起的中断)分配给可屏蔽中断
剩余的、编号为48~255的向量用来标示软中断。Linux只使用了其中的一个(即128或0x80向量)来实现系统调用。
中断描述符表:
    在实地址模式中,cpu把内存中从0开始的1KB空间作为一个中断向量表。表中的每个表项占四个字节,有两个字节的段地址和两个字节的偏移量组成,这样构成的地址便是相应中断处理程序的入口地址。但是,在保护 模式下,有4个字节的表项构成的中断向量表显然满足不了要求。这是因为:除了两个字节的段描述符,偏移量必须用4个字节来表示而且要有反应模式切换的信息。因此,在保护模式下,中断向量表中的表项由八个字节组成。中断向量表也该称作中断描述符表(Interrupt Descriptor Table,IDT),其中的每个表项叫做一个门描述符(gate descriptor)
中断控制器:
    中断控制器是一种硬件结构,在Inter X86中使用中断控制器8259A来响应15个外部中断源每个8259A可以管理8个中断源。
中断线:
    与中断源相连的每条线叫做中断线,常把申请一条中断线称为申请一个IRQ或者是申请一个中断号。

 
阅读(546) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~