美文网首页
Linux内核设计与实现——中断和中断处理

Linux内核设计与实现——中断和中断处理

作者: leon4ever | 来源:发表于2018-04-25 22:18 被阅读68次

    操作系统的核心任务,包含对硬件设备的有效管理,为了避免轮询(周期性检查),通过中断机制,即硬件在需要的时候向内核发出信号。

    1.中断

    硬件——电信号——中断控制器——处理器
    每个中断有唯一的数字标志

    异常:处理器执行时产生错误指令(除0)或者特殊情况(缺页)等,必须依靠内核来处理的时候,处理器回产生一个异常

    2. 中断处理程序

    响应特定中断时,会通过中断向量表找到一个对应的中断处理程序,被内核调用来响应中断的,运行于中断上下文的特殊上下文中。

    3. 上半部与下半部的对比

    中断处理程序要快! VS 中断处理程序完成的工作量多!
    把中断处理切为两个部分,

    • 上半部是接收到中断就立即执行,但是只做有严格时限的工作
    • 能够允许稍后完成的工作会推迟到下半部,在合适的时机,下半部会开中断执行

    4. 注册中断处理程序

    /*
     * irg     - 表示要分配的中断号
     * handler - 实际的中断处理程序
     * flags   - 标志位,表示此中断的具有特性
     * name    - 中断设备名称的ASCII 表示,这些会被/proc/irq和/proc/interrupts文件使用
     * dev     - 用于共享中断线,多个中断程序共享一个中断线时(共用一个中断号),依靠dev来区别各个中断程序
     * 返回值:
     * 执行成功:0
     * 执行失败:非0
     */
    int request_irq(unsigned int irq,
                    irq_handler_t handler,
                    unsigned long flags,
                    const char* name,
                    void *dev)
    

    释放中断处理程序:
    void free_irq(unsigned int irq, void *dev)

    5. 中断上下文

    当执行一个中断处理程序的时候,内核处于中断上下文,与进程没啥关系,没有后备进程,所以不可以睡眠。
    中断处理程序打断了其它的代码(甚至可能打断另一中断处理程序,以及软中断),所以必须快速,简洁

    6. 中断处理机制的实现

    如图


    中断处理机制.png

    ret_from_intr负责检查重新调度是否正在挂起,如果返回用户空间(也就是说中断的是用户空间),那么schedule()被调用,如果返回内核空间(中断的是内核本身),只有preempt_count为0时,schedule()才会被调用,否则抢占内核是不安全的。

    7. 中断控制

    控制中断是因为需要提供同步,通过禁止中断,可以确保某个中断处理程序不会抢占当前的代码,还可以禁止内核抢占。
    同时,还需要保护机制来防止来自其他处理器的并发访问,内核代码一般都需要锁,伴随着禁止本地中断。
    其实就是禁止中断提供保护机制,防止来自其他中断处理程序的并发访问。

    函数 说明
    local_irq_disable() 禁止本地中断传递
    local_irq_enable() 激活本地中断传递
    local_irq_save() 保存本地中断传递的当前状态,然后禁止本地中断传递
    local_irq_restore() 恢复本地中断传递到给定的状态
    disable_irq() 禁止给定中断线,并确保该函数返回之前在该中断线上没有处理程序在运行
    disable_irq_nosync() 禁止给定中断线
    enable_irq() 激活给定中断线
    irqs_disabled() 如果本地中断传递被禁止,则返回非0;否则返回0
    in_interrupt() 如果在中断上下文中,则返回非0;如果在进程上下文中,则返回0
    in_irq() 如果当前正在执行中断处理程序,则返回非0;否则返回0

    相关文章

      网友评论

          本文标题:Linux内核设计与实现——中断和中断处理

          本文链接:https://www.haomeiwen.com/subject/rlkulftx.html