zoukankan      html  css  js  c++  java
  • 43、Windows驱动程序模型笔记(一)

    1、通常,驱动程序在某些不可预测线程的上下文中应该使用异步方式处理I/O请求。我们使用术语任意线程上下文(arbitrary thread context)来描述驱动程序并不知道(或并不关心)处理器当前执行在哪一个线程上的上下文。

    2Windows 2000使用对称多处理器模型,即所有的处理器都是相同的,系统任务和用户模式程序可以执行在任何一个处理器上,并且所有处理器都平等地访问内存。多处理器的存在给设备驱动程序带来了一个困难的同步问题,因为执行在多个CPU上的代码可能同时访问共享数据或共享硬件资源。Windows 2000提供了一个同步对象,自旋锁(spin lock),驱动程序可以使用它来解决多处理器的同步问题。

    3、当CPU运行在 PASSIVE_LEVEL级时,当前运行的线程可以被任何优先级大于它的线程抢先。然而,一旦CPUIRQL大于PASSIVE_LEVEL级,线程抢先将不再发生,此时CPU执行在使CPU越过PASSIVE_LEVEL级的任意线程上下文中。但是,运行在任何IRQL级上的活动都可以被更高 IRQL级上的活动中断。所以驱动程序必须假定在任何时刻都可能失去控制权,而此时系统可能需要执行更基本的任务。

    4、为了实现可配置性,首先应该在代码中避免直接引用硬件,即使是在平台相关的条件编译块中也是这样。应该使用HAL工具或调用低级总线驱动程序,或者实现一个标准的或定制的控制接口,并通过控制面板程序与用户交互。另外,还应该支持Windows管理仪器(WMI)控件,这种控件允许用户和管理员在分布式企业环境中配置硬件特征。最后,应该使用注册表作为配置信息的数据库,这可以使配置信息在系统重新启动后仍然存在。

    5、为了实现这种可移植性,驱动程序应该全部用C写,并且只使用ANSI C标准规定的语言元素。应避免使用编译器厂商专有的语言特征,并避免使用没有被操作系统内核输出的运行时间库函数(参见第三章)。如果不能避免驱动程序中的平台依赖,至少应该用条件编译指令隔离这些代码。

    6、可以把一个完整的驱动程序看作是一个容器,它包含许多例程,当操作系统遇到一个IRP时,它就调用这个容器中的例程来执行该IRP的各种操作。

    可以把一个完整的驱动程序看作是一个容器,它包含许多例程,当操作系统遇到一个IRP时,它就调用这个容器中的例程来执行该IRP的各种操作。有些例程,例如DriverEntryAddDevice,还有与几种IRP对应的派遣函数将出现在每一个这样的容器中。需要对IRP排队的驱动程序一般都有一个 StartIo例程。执行DMA传输的驱动程序应有一个AdapterControl例程。大部分能生成硬件中断的设备,其驱动程序都有一个中断服务例程 (ISR)和一个推迟过程调用(DPC)例程。驱动程序一般都有几个支持不同类型IRP的派遣函数,其中三个派遣函数是必须的。所以,WDM驱动程序开发 者的一个任务就是为这个容器选择所需要的例程。

    wps_clip_image-17377

    图示 P21 1-5 WDM驱动程序“容器”中的内容

    7、有三种注册表键负责配置。它们是硬件(hardware)键、类 (class)键、服务(service)键。必须明确一点,这些名字(hardwareclassservice)并不是某个专用子键的名称:它 们是这三种键的一般称谓,其具体的路径名要取决于它们所属的设备。概括地讲,硬件键包含单个设备的信息,类键涉及所有相同类型设备的共同信息,服务键包含 驱动程序信息。有时人们用实例(instance)软件(software)来代表硬件键和服务键。

        设备的硬件键出现在注册表local machine分支的\System\CurrentControlSet\Enum子键上。

        应用程序经常需要访问注册表中关于硬件设备的信息。为了使这成为可能而同时又不暴露重要的Enum键,Microsoft提供了一组SetupDiXxx函数。

       设备接口的符号连接名(通过枚举该接口GUID的所有实例或者从WM_DEVICECHANGE消息的参数中获得这个名字)ClassGUID是设备类GUID(全局唯一标识符)ASCII形式;在效果上,它是一个指向该设备类键的指针。Service指向服务键。

    类键 所有设备类的类键都出现在HKLM\System\CurrentControlSet\Control\Class键中。它们的键名是由Microsoft赋予的GUID值。

    服务(或软件) 对设备驱动程序重要的最后一个键是服务键。它指出驱动程序执行文件的位置,以及控制驱动程序装入的一些参数。服务键位于HKLM\System\CurrentControlSet\Services键中。

        当我说系统装入一个驱动程序时,是指系统把驱动程序的映像映射到虚拟内存中,并重定位内存参考,最后调用驱动程序的主入口点。主入口点通常命名为 DriverEntry。我将在本章后面讲述DriverEntry函数。如果驱动程序已经在内存中,则装入过程仅仅是增加驱动程序映像的参考计数。

    8、驱动程序的装入顺序并不是很重要。系统以PnP管理器装入驱动程序的顺序调用驱动程序的AddDevice函数,而这个顺序与设备对象在设备堆栈中出现的顺序完全一致。

    wps_clip_image-17380

    图示2-2 设备递归枚举过程

    图示2-2显示了一个由多个设备堆栈组成的树形结构,但这并不表示IRP必须从上一层的PDO流向下一层的FiDO。实际上,一个堆栈的PDO驱动程序就是其下一层堆栈的FDO驱动程序,见图示2-2中的阴影块。当驱动程序以PDO角色接收到一个IRP时,它对该IRP执行一些操作但不发出这个或其它IRP到设备(FDO角色)。相反,当总线驱动程序以FDO角色接收到一个IRP时,它可能需要向设备发送某些IRP(PDO角色)

    wps_clip_image-8556

    图示 图2-8 设备(位于二级总线)读请求处理流程

  • 相关阅读:
    我爱Java系列之---【SpringBoot打成war包部署】
    279. Perfect Squares
    矩阵dfs--走回路
    112. Path Sum
    542. 01 Matrix
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    Invert Binary Tree
    563 Binary Tree Tilt
    145 Binary Tree Postorder Traversal
  • 原文地址:https://www.cnblogs.com/mydomain/p/1921223.html
Copyright © 2011-2022 走看看