【问题标题】:From Kernel Space to User Space: Inner-workings of Interrupts从内核空间到用户空间:中断的内部工作
【发布时间】:2015-05-24 14:55:02
【问题描述】:

我一直试图了解硬件中断是如何通过内核最终出现在某些用户空间代码中的。

我的研究让我明白:

1- 外部设备需要 CPU 关注

2- 它通过引发中断(h/w trance 到 cpu 或总线)向 CPU 发出信号

3- CPU 断言,保存当前上下文,查找 ISR 的地址 中断描述符表(向量)

4- CPU 切换到内核(特权)模式并执行 ISR。

问题#1:内核如何在中断向量表中存储 ISR 地址?可能通过向 CPU 发送一些 CPU 用户手册中描述的组件来完成?请在这个主题上越详细越好。


在用户空间中,程序员如何编写一段代码来监听硬件设备通知?

这是我目前所理解的。

5- 该特定设备的内核驱动程序现在已收到来自该设备的消息,并且正在执行 ISR。

问题#3:如果用户空间的程序员想要轮询设备,我会假设这将通过系统调用来完成(或者至少这是我目前所理解的)。这是怎么做到的?驱动程序如何告诉内核在特定的系统调用上被调用,以便它可以执行来自用户的请求?然后会发生什么,驱动程序如何将请求的数据返回给用户空间?

我可能在这里完全偏离轨道,任何指导将不胜感激。 我不是在寻找具体细节的答案,我只是想了解大致情况。

【问题讨论】:

  • 有用链接:lwn.net/images/pdf/LDD3/ch10.pdf - Jonathan Corbet、Alessandro Rubini 和 Greg Kroah-Hartman 的 LINUX DEVICE DRIVERS (2005) 第 10 章。如果使用标准的Linux内核,可以使用linux接口(和手册)进行驱动,无需深入了解CPU ISR寄存器机制(哪个CPU - x86/x86_64/arm?)。

标签: linux-kernel operating-system


【解决方案1】:

问题 #1:内核如何将 ISR 地址存储在中断向量表中?

驱动调用request_irq内核函数(在include/linux/interrupt.h和kernel/irq/manage.c中定义),Linux内核会根据当前的CPU/arch规则以正确的方式注册它。

这可能是通过向 CPU 发送一些 CPU 用户手册中描述的组件来完成的?

在 x86 Linux 内核中,ISR 存储在中断描述符表 (IDT) 中,它的格式由供应商 (Intel - volume 3) 以及许多资源中描述,例如 http://en.wikipedia.org/wiki/Interrupt_descriptor_table 和 http://wiki.osdev.org/IDT 和 http://phrack.org/issues/59/4.html 和 http://en.wikibooks.org/wiki/X86_Assembly/Advanced_Interrupts。

指向 IDT 表的指针使用特殊的汇编器命令注册在特殊 CPU 寄存器 (IDTR) 中:LIDT 和 SIDT。

如果用户空间的程序员想要轮询设备,我会假设这将通过系统调用来完成(或者至少这是我目前所理解的)。这是怎么做到的?驱动程序如何告诉内核在特定的系统调用上被调用,以便它可以执行来自用户的请求?然后会发生什么,驱动程序如何将请求的数据返回给用户空间?

驱动程序通常registers /dev 中的一些设备特殊文件;指向多个驱动程序函数的指针为此文件注册为"File Operations"。用户空间程序打开这个文件(syscall open),内核调用设备的特殊代码来打开;然后程序在这个 fd 上调用poll 或read syscall,内核将调用驱动程序的文件操作(http://www.makelinux.net/ldd3/chp-3-sect-7.shtml)的*poll 或*read。驱动程序可以让调用者进入睡眠状态 (wait_event*) 并且 irq 处理程序将唤醒它 (wake_up* - http://www.makelinux.net/ldd3/chp-6-sect-2 )。

您可以在 Jonathan Corbet、Alessandro Rubini 和 Greg Kroah-Hartman 所著的 LINUX DEVICE DRIVERS (2005) 一书中了解更多关于 linux 驱动程序创建的信息:https://lwn.net/Kernel/LDD3/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-10-22
    • 1970-01-01
    • 2016-06-26
    • 2012-06-23
    • 1970-01-01
    • 2014-08-18
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多