从内核 Space 到用户 Space:中断的内部工作原理
From Kernel Space to User Space: Inner-workings of Interrupts
我一直在尝试了解 h/w 中断是如何通过内核在某些用户 space 代码中结束的。
我的研究使我明白:
1- 外部设备需要 CPU
注意
2- 它通过引发中断(h/w 恍惚到 cpu 或总线)向 CPU 发出信号
3- CPU断言,保存当前上下文,在
中断描述符 table(向量)
4- CPU 切换到内核(特权)模式并执行 ISR。
问题 #1:内核如何将 ISR 地址存储在中断向量中 table?这可能是通过向 CPU 发送 CPUs 用户手册中描述的一些程序集来完成的?这个问题越详细越好。
在用户 space 中,程序员如何编写一段代码来监听 h/w 设备通知?
这是我目前的理解。
5- 该特定设备的内核驱动程序现在收到来自该设备的消息并正在执行 ISR。
问题 #3:如果用户 space 中的程序员想要轮询设备,我认为这将通过系统调用(或至少这是我到目前为止所理解的)。这是怎么做到的?驱动程序如何告诉内核在特定系统调用时被调用,以便它可以执行用户的请求?然后会发生什么,驱动程序如何将请求的数据返回给用户space?
我在这里可能完全偏离轨道,任何指导将不胜感激。
我不是在寻找具体的细节答案,我只是想了解大概的情况。
Question #1: How did the kernel store ISR address in interrupt vector table?
Driver 调用 request_irq
内核函数(在 include/linux/interrupt.h
和 kernel/irq/manage.c 中定义),Linux 内核将以正确的方式注册它根据当前 CPU/arch 规则。
It might probably be done by sending the CPU some piece of assembly described in the CPUs user manual?
在 x86 Linux 内核中将 ISR 存储在中断描述符 Table (IDT) 中,其格式由供应商描述 (Intel - volume 3) and also in many resources like http://en.wikipedia.org/wiki/Interrupt_descriptor_table and http://wiki.osdev.org/IDT and http://phrack.org/issues/59/4.html and http://en.wikibooks.org/wiki/X86_Assembly/Advanced_Interrupts。
指向 IDT table 的指针被注册在特殊的 CPU 寄存器 (IDTR) 中,使用特殊的汇编程序命令:LIDT
and SIDT
.
If the programmer in user space wanted to poll the device, I would assume this would be done through a system call (or at least this is what I understood so far). How is this done? How can a driver tell the kernel to be called upon a specific systemcall so that it can execute the request from the user? And then what happens, how does the driver gives back the requested data to user space?
Driver 通常 registers some device special file in /dev; pointers to several driver functions are registered for this file as "File Operations". User-space program opens this file (syscall open
), and kernels calls device's special code for open; then program calls poll
or read
syscall on this fd, kernel will call *poll
or *read
of driver's file operations (http://www.makelinux.net/ldd3/chp-3-sect-7.shtml). Driver may put caller to sleep (wait_event*
) and irq handler will wake it up (wake_up*
- http://www.makelinux.net/ldd3/chp-6-sect-2).
您可以在 Jonathan Corbet、Alessandro Rubini 和 Greg LINUX DEVICE DRIVERS(2005 年)一书中阅读有关 linux driver 创作的更多信息 Kroah-Hartman:https://lwn.net/Kernel/LDD3/
- 第 3 章:字符 Drivers https://lwn.net/images/pdf/LDD3/ch03.pdf
- 第 10 章:中断处理 https://lwn.net/images/pdf/LDD3/ch10.pdf
我一直在尝试了解 h/w 中断是如何通过内核在某些用户 space 代码中结束的。
我的研究使我明白:
1- 外部设备需要 CPU
注意2- 它通过引发中断(h/w 恍惚到 cpu 或总线)向 CPU 发出信号
3- CPU断言,保存当前上下文,在 中断描述符 table(向量)
4- CPU 切换到内核(特权)模式并执行 ISR。
问题 #1:内核如何将 ISR 地址存储在中断向量中 table?这可能是通过向 CPU 发送 CPUs 用户手册中描述的一些程序集来完成的?这个问题越详细越好。
在用户 space 中,程序员如何编写一段代码来监听 h/w 设备通知?
这是我目前的理解。
5- 该特定设备的内核驱动程序现在收到来自该设备的消息并正在执行 ISR。
问题 #3:如果用户 space 中的程序员想要轮询设备,我认为这将通过系统调用(或至少这是我到目前为止所理解的)。这是怎么做到的?驱动程序如何告诉内核在特定系统调用时被调用,以便它可以执行用户的请求?然后会发生什么,驱动程序如何将请求的数据返回给用户space?
我在这里可能完全偏离轨道,任何指导将不胜感激。 我不是在寻找具体的细节答案,我只是想了解大概的情况。
Question #1: How did the kernel store ISR address in interrupt vector table?
Driver 调用 request_irq
内核函数(在 include/linux/interrupt.h
和 kernel/irq/manage.c 中定义),Linux 内核将以正确的方式注册它根据当前 CPU/arch 规则。
It might probably be done by sending the CPU some piece of assembly described in the CPUs user manual?
在 x86 Linux 内核中将 ISR 存储在中断描述符 Table (IDT) 中,其格式由供应商描述 (Intel - volume 3) and also in many resources like http://en.wikipedia.org/wiki/Interrupt_descriptor_table and http://wiki.osdev.org/IDT and http://phrack.org/issues/59/4.html and http://en.wikibooks.org/wiki/X86_Assembly/Advanced_Interrupts。
指向 IDT table 的指针被注册在特殊的 CPU 寄存器 (IDTR) 中,使用特殊的汇编程序命令:LIDT
and SIDT
.
If the programmer in user space wanted to poll the device, I would assume this would be done through a system call (or at least this is what I understood so far). How is this done? How can a driver tell the kernel to be called upon a specific systemcall so that it can execute the request from the user? And then what happens, how does the driver gives back the requested data to user space?
Driver 通常 registers some device special file in /dev; pointers to several driver functions are registered for this file as "File Operations". User-space program opens this file (syscall open
), and kernels calls device's special code for open; then program calls poll
or read
syscall on this fd, kernel will call *poll
or *read
of driver's file operations (http://www.makelinux.net/ldd3/chp-3-sect-7.shtml). Driver may put caller to sleep (wait_event*
) and irq handler will wake it up (wake_up*
- http://www.makelinux.net/ldd3/chp-6-sect-2).
您可以在 Jonathan Corbet、Alessandro Rubini 和 Greg LINUX DEVICE DRIVERS(2005 年)一书中阅读有关 linux driver 创作的更多信息 Kroah-Hartman:https://lwn.net/Kernel/LDD3/
- 第 3 章:字符 Drivers https://lwn.net/images/pdf/LDD3/ch03.pdf
- 第 10 章:中断处理 https://lwn.net/images/pdf/LDD3/ch10.pdf