命令和程序如何与Window OS通信

时间:2011-09-06 10:21:33

标签: kernel windows-nt

Windows程序如何与Windows NT内核交互或发出命令?

内核如何返回任何数据?

3 个答案:

答案 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,防止他们自己直接调用内核服务。