"照葫芦画瓢"与"改例子代码为已所用"是软件工程师的一条捷径.

无论是Windows WDK/DDK还是Linux, 都提供了数不胜数的实例, 以供驱动编程学习与实际项目的需要.

以USB驱动为例, 在WDK的例子程序中, 涵盖了KMDF, UMDF, EXE一系列代码例子.

而Linux中则更为丰富, 其包含了Host, composite, hub, 以及各类USB设备的驱动源代码, 让有兴趣了解USB的学习者能够更加深入地掌握USB的软件编程与部分原理.

但是, 无论复杂的软件还是系统, 都有一个对应的总体设计目标, 以及各种不同的条条框框规则.

初看这些规则,感觉教条, 无趣, 不知所以然, 随着对驱动以及操作系统内核的接触的深入, 渐渐地明白了其中的一些规则.

因此, 我们可以学习Windows WDK/DDK或者Linux中的例子或者内核源代码, 最终将这些例子或者源代码"为我的项目所用", 但要感悟体会内核驱动程序甚至系统的设计目标, 并非一朝一夕所能达成.

以Windows WDK中对内核驱动的设计目标为例:

  • Portable from one platform to another.
  • Configurable to various hardware and software platforms.
  • Always preemptible and always interruptible.
  • Multiprocessor-safe on multiprocessor platforms.
  • Object-based.
  • Packet-driven I/O with reusable IRPs.
  • Capable of supporting asynchronous I/O.

一共有以上七条.
比较难理解的是:
第三, 四以及第七条.
这三条也回答了"第九篇:万丈高楼平地起-驱动编程基础知识点"中的一些基础问题.
第三条:

Always Preemptible and Always Interruptible

The goal of the preemptible, interruptible design of the operating system is to maximize system performance. Any thread can be preempted by a thread with a higher priority, and any driver's interrupt service routine (ISR) can be interrupted by a routine that runs at a higher interrupt request level (IRQL).

可抢占与可被中断的设计目标是为了系统性能的最大化.

线程优先级决定了可抢占

中断请求级别决定了可被中断

The kernel component determines when a code sequence runs, according to one of these prioritizing criteria:

  • The kernel-defined run-time priority scheme for threads.

    Every thread in the system has an associated priority attribute. In general, most threads havevariable priority attributes: they are always preemptible and are scheduled to run round-robin with all other threads that are currently at the same priority level. Some threads havereal-time priority attributes: these time-critical threads run to completion unless they are preempted by a thread that has a higher real-time priority attribute. The Microsoft Windows architecture does not provide an inherently real-time system.

    Whatever its priority attribute, any thread in the system can be preempted when hardware interrupts and certain types of software interrupts occur.

微软的Windows系统不是"实时"系统.
不管该线程的优先级是多少, 它都是可以被硬件与软件中断的.
  • The kernel-defined interrupt request level (IRQL) to which a particular interrupt vector is assigned on a given platform.

    The kernel prioritizes hardware and software interrupts so that some kernel-mode code, including most drivers, runs at higher IRQLs, thereby making it have a higher scheduling priority than other threads in the system. The particular IRQL at which a piece of kernel-mode driver code executes is determined by the hardware priority of its underlying device.

    Kernel-mode code is always interruptible: an interrupt with a higher IRQL value can occur at any time, thereby causing another piece of kernel-mode code that has a higher system-assigned IRQL to be run immediately on that processor. However, when a piece of code runs at a given IRQL, the kernel masks all interrupt vectors with a lesser or equal IRQL value on the processor.

IRQLs相对于线程, 具有更高的调试优先权.

The lowest IRQL level is called PASSIVE_LEVEL. At this level, no interrupt vectors are masked. Threads generally run at IRQL=PASSIVE_LEVEL. The next higher IRQL levels are for software interrupts. These levels include APC_LEVEL, DISPATCH_LEVEL or, for kernel debugging, WAKE_LEVEL. Device interrupts have still higher IRQL values. The kernel reserves the highest IRQL values for system-critical interrupts, such as those from the system clock or bus errors.

列举了几个不同级别的IRQL.

Some system support routines run at IRQL=PASSIVE_LEVEL, either because they are implemented as pageable code or access pageable data, or because some kernel-mode components set up their own threads.

某些系统例程运行在最低级别的IRQL=PASSIVE_LEVEL上, 纠其原因:

代码是可被分页的

代码访问了可被分页的数据

或者是某些系统模块创建了他们自己的线程(? 这个为什么也是运行在IRQL= PASSIVE_LEVEL的原因, 不是特别清楚)

Similarly, some standard driver routines usually run at IRQL=PASSIVE_LEVEL. However, several standard driver routines run either at IRQL=DISPATCH_LEVEL or, for a lowest-level driver, at device IRQL (also calledDIRQL). For more information about IRQLs, see Managing Hardware Priorities.

最底层的驱动, 很大概率上, 将会运行在DIRQL上.

Every routine in a driver is interruptible. This includes any routine that is running at a higher IRQL than PASSIVE_LEVEL. Any routine that is running at a particular IRQL retains control of the processor only if no interrupt for a higher IRQL occurs while that routine is running.

任何驱动例程都是可被中断的, 包括运行高级别的IRQL上的例程.

Unlike the drivers in some older personal computer operating systems, a Microsoft Windows driver's ISR isnever a large, complex routine that does most of the driver's I/O processing. This is because any driver'sinterrupt service routine (ISR) can be interrupted by another routine (for example, by another driver's ISR) that runs at a higher IRQL. Thus, the driver's ISR does not necessarily retain control of a CPU, uninterrupted, from the beginning of its execution path to the end.

In Windows drivers, an ISR typically saves hardware state information, queues adeferred procedure call (DPC), and then quickly exits. Later, the system dequeues the driver's DPC so that the driver can complete I/O operations at a lower IRQL (DISPATCH_LEVEL). For good overall system performance, all routines that run at high IRQLs must relinquish control of the CPU quickly.

ISR尽快处理该由它处理的事情, 将可以推迟处理的事情交由DPC.

In Windows, all threads have a thread context. This context consists of information that identifies the process that owns the thread, plus other characteristics such as the thread's access rights.

线程与线程上下文的关系

In general, only a highest-level driver is called in the context of the thread that is requesting the driver's current I/O operation. An intermediate-level or lowest-level driver cannever assume that it is executing in the context of the thread that requested its current I/O operation.

最高层的驱动往往运行在发起IO请求的线程环境下.

Consequently, driver routines usually execute in an arbitrary thread context—the context of whatever thread is current when a standard driver routine is called. For performance reasons (to avoid context switches), very few drivers set up their own threads.

驱动例程与任意线程上下文的关系

Multiprocessor-Safe

The Microsoft Windows NT-based operating system is designed to run uniformly on uniprocessor and symmetric multiprocessor (SMP) platforms, and kernel-mode drivers should be designed to do likewise.

In any Windows multiprocessor platform, the following conditions exist:

  • All CPUs are identical, and either all or none of the processors must have identical coprocessors.
假设,要么所有的CPU都具备相同的协处理器, 要么所有的CPU都没有协处理器.
  • All CPUs share memory and have uniform access to memory.
所有的CPU对共享内存的访问权限是相同的.
  • In a symmetric platform, every CPU can access memory, take an interrupt, and access I/O control registers. (By contrast, in anasymmetric multiprocessor machine, one CPU takes all interrupts for a set of subordinate CPUs.)
与非对称多处理器架构不同, 对称多处理器中的每一个CPU, 都能访问内存, 处理中断, 该问IO控制registers.

To run safely on an SMP platform, an operating system must guarantee that code that executes on one processor does not simultaneously access and modify data that another processor is accessing and modifying. For example, if a lowest-level driver's ISR is handling a device interrupt on one processor, it must have exclusive access to device registers or critical, driver-defined data, in case its device interrupts simultaneously on another processor.

SMP上必须保证数据的同步问题.

Furthermore, drivers' I/O operations that are serialized in a uniprocessor machine can be overlapped in an SMP machine. That is, a driver's routine that processes incoming I/O requests can be executing on one processor while another routine that communicates with the device executes concurrently on another processor. Whether kernel-mode drivers are executing on a uniprocessor or symmetric multiprocessor machine, they must synchronize access to any driver-defined data or system-provided resources that are shared among driver routines, and synchronize access to the physical device, if any.

在单处理器上的IO操作是串行化处理的.

而在SMP上, 就存在, 一个CPU在处理IO(运行IO处理的驱动例程), 同时在另外一个CPU上则在处理与设备的通迅工作(运行了另外一段驱动例程).

同样, 无论是单处理器还是SMP, 都必须包括数据同步问题的解决,以及对硬件访问的同步.

The Windows NT kernel component exports a synchronization mechanism, called a spin lock, that drivers can use to protect shared data (or device registers) from simultaneous access by one or more routines that are running concurrently on a symmetric multiprocessor platform. The kernel enforces two policies regarding the use of spin locks:

  • Only one routine can hold a particular spin lock at any given moment. Before accessing shared data, each routine that must reference the data must first attempt to acquire the data's spin lock. To access the same data, another routine must acquire the spin lock, but the spin lock cannot be acquired until the current holder releases it.
  • The kernel assigns an IRQL value to each spin lock in the system. A kernel-mode routine can acquire a particular spin lock only when the routine is run at the spin lock's assigned IRQL.
SPIN LCOK的作用.
SPIN LOCK的规则:
1. 唯一占有属性
2. IRQL与SPIN LOCK的关联属性(防止高IRQL例程抢占低IRQL例程 SPIN LOCK, 导致死锁)

These policies prevent a driver routine that usually runs at a lower IRQL but currently holds a spin lock from being preempted by a higher-priority driver routine that is trying to acquire the same spin lock. Thus, a deadlock is avoided.

The IRQL that is assigned to a spin lock is generally that of the highest-IRQL routine that can acquire the spin lock.

For example, a lowest-level driver's ISR frequently shares a state area with the driver's DPC routine. The DPC routine calls a driver-supplied critical section routine to access the shared area. The spin lock that protects the shared area has an IRQL equal to the DIRQL at which the device interrupts. As long as the critical-section routine holds the spin lock and accesses the shared area at DIRQL, the ISR cannot be run in either a uniprocessor or SMP machine.

  • The ISR cannot be run in a uniprocessor machine because the device interrupt is masked, as described inAlways Preemptible and Always Interruptible.
  • In an SMP machine, the ISR cannot acquire the spin lock that protects the shared data while the critical-section routine holds the spin lock and accesses the shared data at DIRQL.
SPIN LOCK的第二条规则在单处理器与SMP中所起的作用.
这里, 由于DPC的Critical section占有SPIN LOCK时, 该SPIN LOCK的IRQL是DIRQL, 屏闭了相同IRQL的中断, 所以,在单处理器上中断不可能被执行, 起到了包括作用.

A set of kernel-mode threads can synchronize access to shared data or resources by waiting for one of the kernel's dispatcher objects: an event, mutex, semaphore, timer, or another thread. However, most drivers do not set up their own threads because they have better performance when they avoid thread-context switches. Whenever time-critical kernel-mode support routines and drivers run at IRQL = DISPATCH_LEVEL or at DIRQL, they must use the kernel's spin locks to synchronize access to shared data or resources.

内核同步对象也可以起到内核数据同步的作用.

但是, 为了减少线程环境切换的消耗, 驱动往往避免创建内核线程.

For more information, see Spin Locks, Managing Hardware Priorities, and Kernel Dispatcher Objects.

Supporting Asynchronous I/O

The I/O manager provides asynchronous I/O support so that the originator of an I/O request (usually a user-mode application but sometimes another driver) can continue executing, rather than wait for its I/O request to be completed. Asynchronous I/O support improves both the overall system throughput and the performance of any code that makes an I/O request.

With asynchronous I/O support, kernel-mode drivers do not necessarily process I/O requests in the same order in which they were sent to the I/O manager. The I/O manager, or a higher-level driver, can reorder I/O requests as they are received. A driver can split a large data transfer request into smaller transfer requests. Moreover, a driver can overlap I/O request processing, particularly in a symmetric multiprocessor platform, as mentioned inMultiprocessor-Safe.

Furthermore, a kernel-mode driver's processing of an individual I/O request is not necessarily serialized. That is, a driver does not necessarily process each IRP to completion before it starts processing the next incoming I/O request.

When a driver receives an IRP, it responds by carrying out as much IRP-specific processing as it can. If the driver supports asynchronous IRP processing, it can send an IRP to the next driver, if necessary, and begin processing the next IRP without waiting for the first one to be completed. The driver can register a "completion routine," which the I/O manager calls when another driver has finished processing an IRP. Drivers provide a status value in the IRP's I/O status block, which other drivers can access to determine the status of an I/O request.

Drivers can maintain state information about their current I/O operations in a special part of their device objects, called adevice extension.

For more information, see Handling IRPs and Input/Output Techniques.

异步处理的设计目标, 事实上, 也是着眼于提高系统的性能.
同时, 异步处理也尽可能地利用了SMP相对于单处理器架构的优势.

第十二篇:从生稣出熟稣,从熟稣出醍醐-再读内核驱动设计目标相关推荐

  1. 「第十二篇」漏洞扫描

    批注[--] 表示他人.自己.网络批注参考资料来源于* 书中批注* CSDN* GitHub* Google* 维基百科* YouTube* MDN Web Docs由于编写过程中无法记录所有的URL ...

  2. MySQL数据库,从入门到精通:第十二篇——MySQL数据类型详解

    MySQL数据库,从入门到精通:第十二篇--MySQL数据类型详解 第 12 章_MySQL数据类型精讲 1. MySQL中的数据类型 2. 整数类型 2. 1 类型介绍 2. 2 可选属性 2. 2 ...

  3. 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探

    SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...

  4. matlab最优控制实验报告_第十二篇 章 用MATLAB解最优控制问题及应用实例 最优控制课件.ppt...

    第十二篇 章 用MATLAB解最优控制问题及应用实例 最优控制课件.ppt 综上所述可得结论:Q=diag(1,0,0),R=2时,系统各方面响应较好. 矩阵Q变大时,反馈矩阵变大: 当Q的对角线上第 ...

  5. CCIE-LAB-第十二篇-EIGRP+EIGRP末节区域+leak map+分发列表

    CCIE-LAB-第十二篇-EIGRP+EIGRP末节区域+leak map+分发列表 实际中,思科只会给你5个小时去做下面的全部配置 这个是CCIE-LAB的拓扑图 问题 翻译:1.确保分支3分支4 ...

  6. CCNA-第十二篇-STP+ACL(下)

    CCNA-第十二篇-STP+ACL(下) 首先说说要跳跳了 立个小FLAG, 两个月内急速完成CCIE理论+LAB实操 因为接了个工作,主要我能做到就能做这份工作. 其实NP中间的点很多都会,只是因为 ...

  7. CCIE理论-第十二篇-IPV6-NDP协议

    CCIE理论-第十二篇-IPV6-NDP协议 首先我们知道 在IPV4中 A:0.0.0.1-126.255.255.255 B:128.0.0.1-191.255.255.255 C:192.0.0 ...

  8. 国外交友网站开发源码 第十二篇

    最近由于工作生活的事情比较多,所以就没有更新,这篇是国外交友网站开发源码 第十二篇 希望大家能够喜欢. 私信列表 class WechatController extends SiteControll ...

  9. 第四十二篇 面对对象进阶

    目录 面对对象进阶 * 补充(数据类装饰器:复制类中的数据属性) 一.类的继承 1.什么是继承 2.为什么用继承 3.对象的继承 4.继承与抽象 5.继承的应用 6.对象查找属性的顺序 二.类的派生 ...

最新文章

  1. jquery input事件
  2. jboss fuse 教程_JBoss Fuse:使用JEXL的动态蓝图文件
  3. 高等数学公式大全_高中物理知识思维导图大全,赶紧收藏!
  4. 淘宝面试-Strcpy与memcpy两函数的经典实现
  5. linux 卸载 1.6,在linux上卸载nump1.6.1并安装nump1.5.1,[它将要使用gipsyoasi II version6]...
  6. 解决IE7中移动文件夹无法收藏问题
  7. python数学实验与建模司守奎pdf_数学建模算法与程序司守奎.pdf
  8. 字节跳动面试分享:java从入门到精通第五版答案位置
  9. 调查问卷设计的一般步骤与方法
  10. 开juǎn有益系列(一)——Binary search(二分查找/折半查找算法)
  11. 本地版BLAST使用
  12. 致敬科比,实现查询科比每赛季数据的Web服务器
  13. Git团队协作工作流程
  14. 推荐12个优质技术公众号!
  15. 代码之外——醒世良言
  16. 网络营销推广怎么做(更全面的网络营销知识点)
  17. 魔兽世界linux客户端,使用Wine在Linux下玩魔兽世界
  18. DPDK-RSS负载均衡分流
  19. php环境下安装并运行laravel教程
  20. 利用matlab绘制简单IFS图形(Sierpinski三角形和BarnsleyFern巴恩斯利蕨)

热门文章

  1. Android path.op 和canvas.clipPath使用一例
  2. 局域网对战平台 linux,在Linux下可用Wine安装和运行完美对战平台、金山游侠2002体验版...
  3. 23-tcp协议——TIME_WAIT状态和FIN_WAIT2状态
  4. antd动态换主题颜色
  5. 嵌入式:ARM嵌入式系统开发流程概述
  6. 恒指傻瓜操作系统(一)
  7. 信息安全从业人员认证证书一览表
  8. 计算机一级考试空格符号选择题,2018年9月计算机一级考试MSOffice练习题二
  9. 基于MFC的平行投影算法
  10. Matlab多次重复实验记录结果,MATLAB数据处理实验记录与总结.doc