Windows程序如何与Windows NT内核交互或发出命令?
内核如何返回任何数据?
答案 0 :(得分:0)
老兄,这是一个非常广泛的问题。
我推荐这本书Windows Internals By Mark Russinovich et ag,如果你真的想要坚持这个。另一本好书是经典Operating Systems by Deitel et al。
然后开始使用Inside Windows NT by Helen Custer(第1版) - 这是一本非常基本的书(请注意,最后一个链接有第2版封面的图片 - 这是更详细的方式) 。
简而言之。
Windows组件之间有多种通信协议。他们中的大多数将在一天结束时通过一些共享内存(例如缓冲区,堆栈等)使用传递数据。但协议可能非常复杂,并且对于不同的通信而言也是不同的。
我给你的建议是上面的书籍,并确定Windows操作系统的架构是如何挂在一起的。从这里您将看到各种组件如何通信。
(应用书呆子的脸) - 相信我,这些都是学习Windows和操作系统的好书,如果那就是浮动你的船。
答案 1 :(得分:0)
请尝试阅读:Chapter 5 - Windows NT 4.0 Workstation Architecture。它应该足够开始了。
最后,某些API直接在某些用户态DLL中构建。这些是直接执行的。其他需要内核模式的帮助/服务。
对于这些(我从上面的链接引用)
应用程序使用API对用户模式进行图形调用 动态链接库。实现调用的组件创建了一个 内核模式陷阱调用Executive来切换其线程和复制 其调用参数从其用户模式堆栈到其内核模式堆栈。 然后,处理器的堆栈寄存器切换到指向内核 模式。现在线程可以在Executive中运行。
应用程序使用本地与受保护的子系统进行通信 过程调用(LPC),一种独立于应用程序的方法 同一台计算机上的组件之间的通信。之后 线程切换到内核模式,Microkernel调度LPC 交货。
使用Fast LPC,一种优化的通信方法,Microkernel 认识到来自应用程序的调用涉及到一个线程 环境子系统。它考虑调用应用程序线程和 要配对的接收子系统线程。接收线程可以 现在使用发送线程中的未到期时间。
图形调用参数传递给接收子系统 线。接收线程切换回用户模式以完成 图形请求。
子系统完成其任务,然后将控制权返回给 等待通过相同的方法调用应用程序中的线程。
调用线程(来自DLL)之前切换回用户模式 将控制权返回给应用程序。
微软操作系统工程师也使用了共享的概念 内存窗口加快沟通。数据是临时的 由进程管理器管理的共享内存窗口 行政人员。这使应用程序可以看到子系统的内存 并且在不使用LPC的情况下共享数据。但是,因为应用程序 线程必须仍然在Executive,内核/用户模式转换中运行 和线程切换仍然是必需的。
这里有一些注释exactly
是如何完成调用的(使用的是什么ASM命令):The system call dispatcher on x86如果需要它。
答案 2 :(得分:0)
为了回答这个问题,了解用户和内核模式之间的区别非常重要。内核模式是最有特权的CPU模式,执行代码可以完全访问硬件。它用于最低级别的操作系统功能。用户模式是一种更受限制的CPU模式。它可以防止代码直接访问硬件。应用程序在用户模式下运行当然,他们仍然需要以某种方式访问硬件,因此他们需要调用内核。
这就是你的问题所在。为了允许用户模式代码调用内核,Windows内核设置了一个入口点。在基于x86的系统上,此入口点是软件中断(int 2e)或sysenter / syscall指令。执行这些指令会导致CPU模式切换,将CPU从用户模式转换为内核模式。一旦CPU切换模式,它就会调用内核指定的函数。在Windows中,此功能是系统服务调度程序。
系统服务调度程序负责调用用户模式代码所需的内核服务。它采用由用户模式代码指定的函数号,并在系统服务描述符表(SSDT)中查找。 SSDT基本上是每个内核服务的函数指针列表。一旦识别出正确的内核服务,它就会使用用户模式应用程序也指定的参数调用它。内核服务完成后,CPU通过iret指令(如果来自软件中断)或sysexit / sysret(如果来自sysenter / syscall)返回应用程序。
所有这些听起来都非常复杂,这就是Windows为程序员隐藏这些细节的原因。 Windows不是要求它们通过内核设置的入口点直接与内核通信,而是为程序员提供了几个DLL,这些DLL为它们做到了这一点。
现在这里再次变得更加复杂。从用户模式调用内核服务的过程在ntdll.dll中实现,但大多数程序员不直接使用ntdll.dll。相反,它导出一组称为Native API的通用内核服务。在此之上,Win32 API在kernel32.dll中实现。 kernel32.dll中的大多数函数都只是ntdll.dll中函数的包装。
你可能会问为什么这样做。为什么不让kernel32.dll直接调用内核函数?这样做的原因是允许不同的多用户模式API。 Windows NT旨在支持多个API,不仅包括Win32,还支持POSIX和OS / 2。每个用户模式API调用ntdll.dll来实现自己的API,防止他们自己直接调用内核服务。