我一直试图了解h / w中断如何通过内核在某些用户空间代码中结束。
我的研究让我明白:
1-外部设备需要CPU注意
2-它通过引发中断(h / w trance to cpu或bus)来通知CPU
3- CPU断言,保存当前上下文,查找ISR中的地址 中断描述符表(向量)
4- CPU切换到内核(特权)模式并执行ISR。
问题#1 :内核如何在中断向量表中存储ISR地址?它可能是通过向CPU发送CPU用户手册中描述的某些程序集来完成的吗?关于这个主题的更多细节请更好。
在用户空间中,程序员如何编写一段监听h / w设备通知的代码?
这是我目前所理解的。
5-该特定设备的内核驱动程序现在具有来自设备的消息,现在正在执行ISR。
问题#3 :如果用户空间的程序员想要轮询设备,我会认为这可以通过系统调用完成(或者至少这是我目前所理解的)。这是怎么做到的?如何让驱动程序告诉内核在特定的系统调用上被调用,以便它可以执行来自用户的请求?然后会发生什么,驱动程序如何将请求的数据返回给用户空间?
我可能完全偏离这里,任何指导都将不胜感激。 我不是在寻找具体的细节答案,我只想了解一般情况。
答案 0 :(得分:1)
问题#1:内核如何在中断向量表中存储ISR地址?
驱动程序调用{{1}}内核函数(在include/linux/interrupt.h
和kernel / irq / manage.c中定义),Linux内核将根据当前的CPU / arch规则以正确的方式注册它。
可能通过向CPU发送CPU用户手册中描述的某些程序集来完成它?
在x86 Linux内核中存储中断描述符表(IDT)中的ISR,它的格式由供应商(Intel - volume 3)描述,也在许多资源中描述,如http://en.wikipedia.org/wiki/Interrupt_descriptor_table和http://wiki.osdev.org/IDT以及{{ 3}}和http://phrack.org/issues/59/4.html。
指向IDT表的指针在特殊CPU寄存器(IDTR)中使用特殊汇编程序命令注册:http://en.wikibooks.org/wiki/X86_Assembly/Advanced_Interrupts和LIDT
。
如果用户空间中的程序员想要轮询设备,我会假设这将通过系统调用完成(或者至少这是我目前所理解的)。这是怎么做到的?如何让驱动程序告诉内核在特定的系统调用上被调用,以便它可以执行来自用户的请求?然后会发生什么,驱动程序如何将请求的数据返回给用户空间?
驱动程序通常SIDT
/ dev中的某些设备专用文件;指向多个驱动程序函数的指针已作为registers注册到此文件。用户空间程序打开此文件(syscall request_irq
),内核调用设备的特殊代码进行打开;然后在此fd上编程调用open
或poll
系统调用,内核将调用驱动程序文件操作read
或*poll
("File Operations")。驱动程序可能会将调用者置于睡眠状态(*read
),而irq处理程序会将其唤醒(wait_event*
- http://www.makelinux.net/ldd3/chp-3-sect-7.shtml)。
您可以阅读Jonathan Corbet,Alessandro Rubini和Greg Kroah-Hartman撰写的LINUX DEVICE DRIVERS(2005)中有关Linux驱动程序创建的更多信息:http://www.makelinux.net/ldd3/chp-6-sect-2