第 10 章 ia-32/intel 64 微机的系统编程技术

58
现现现现现现现现现现现 现现现现现现现现现现现 ( ( 3 3 ) ) http://www.njyangqs.co http://www.njyangqs.co 1 第 10 第 IA-32/Intel 64 第第第第 第第 第第

Upload: diella

Post on 12-Jan-2016

149 views

Category:

Documents


20 download

DESCRIPTION

第 10 章 IA-32/Intel 64 微机的系统编程技术. 10.1 处理器管理与初始化. 10.1.1 IA-32/Intel 64 处理器初始化. 硬件复位将使处理器 进入到实地址模式 ,并初始化每一个寄存器。 硬件复位后,单处理器系统中的处理器和多处理器系统中被选作 自引导处理器( bootstrap processor, BSP ) 的那个处理器会立即执行从 FFFF0H 地址开始 的软件初始化代码。 初始化期间多处理器系统中的其他处理器处于等待启动状态,直到软件初始化代码执行完后, BSP 会唤醒这些处理器,让其执行自配置代码。 - PowerPoint PPT Presentation

TRANSCRIPT

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/1

第 10 章 IA-32/Intel 64 微机的系统编程技术

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/2

10.1 处理器管理与初始化 10.1.1 IA-32/Intel 64 处理器初始化

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/3

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/4

• 硬件复位将使处理器进入到实地址模式进入到实地址模式,并初始化每一个寄存器。• 硬件复位后,单处理器系统中的处理器和多处理器系

统中被选作自引导处理器(自引导处理器( bootstrap processor, BSPbootstrap processor, BSP))的那个处理器会立即执行从 FFFF0HFFFF0H 地址开始地址开始的软件初始化代码。 • 初始化期间多处理器系统中的其他处理器处于等待启

动状态,直到软件初始化代码执行完后, BSPBSP 会唤醒这些处理器,让其执行自配置代码。 • 全部处理器初始化、配置和同步完成后,单处理器系

统中的处理器和多处理器系统中的 BSPBSP 开始执行操作系统的初始化部分或者执行起始任务(没有操作系统的时候)。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/5

10.1.2 实地址模式下的软件初始化 1. IA-32 微机在加电和复位后,就进入实地址模式,配

置必要的数据结构来执行基本的系统功能,比如配置中断向量表来处理中断和异常。

2. 开始执行位于物理地址 FFFF0H 处的初始化程序。3. 如果依然需要运行在实地址模式下,则加载附加的

操作系统模块和数据结构 4. 如果需要转到保护模式下运行(如 Windows 系统那

样),则加载运行保护模式所必须的数据结构,并转换到保护模式。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/6

10.1.3 保护模式下的软件初始化 实地址模式初始化

加载 IDT, GDT, TSS, LDT (可选)

使用页?是

至少要加载一个页目录和一张页表

加载包含了处理器进入保护模式后需要执行的代码的代码段

A

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/7

A

加载包含必要的中断和异常处理程序的一个或多个代码模块

初始化 GDTR, 控制寄存器 CR1~CR4, MTRRs

初始化 IDTR

处理器就通过设置 CR0.PE 值来进入保护模式

初始化 IDTR

IDTRIDTR 可以在切换到保护模式之前初始化,也可以在刚刚进可以在切换到保护模式之前初始化,也可以在刚刚进入保护模式还没有使能中断的时候初始化。 入保护模式还没有使能中断的时候初始化。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/8

10.1.4 IA-32e 模式的初始化 如果需要初始化 IA-32e 模式,操作系统必须先进入到保护模式,并使能分页机制。同时, IA-32e 模式还要求 CR4 的 PAE 位为 1 。

IA-32e 模式被激活后,系统地址寄存器 (GDTR, LDTR, IDTR, TR) 继续指向传统保护模式下的描述符表,这些表都在线性地址空间中的 4GBytes 以下的区域。进入 IA-32e 模式后, 64 位操作系统可以使用LGDT, LLDT, LIDT 和 LTR 指令为系统地址寄存器加载 64 位描述符表的地址。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/9

10.1.5 模式转换

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/10

1.1. 实地址模式转换到保护模式 实地址模式转换到保护模式

① 使用 CLI 指令屏蔽硬件中断,软件要保证在模式转换期间没有中断和异常产生。 NMI 也要用附加的硬件电路进行屏蔽。

② 用 LGDT 指令将 GDT 的基地址装载到 GDTR 中。③ 执行 MOV CR0, reg 指令来设置 CR0 中的 PE 位(

如果允许页式管理还要设置 PG 位)。④ MOV CR0, reg 指令后立即执行一句 far JMP 或者

far CALL (通常目的地址就是本指令的下一条指令地址)。此步骤后,系统进入保护模式。

⑤ 如果要使用局部描述符表,则执行 LLDT 指令将LDT 的段选择符加载到 LDTR 中。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/11

⑥ 执行 LTR 指令加载指向初始的保护模式任务的段选择符到任务寄存器,也可能加载的是指向一段用于存储 TSS 信息的存储区域的段选择符。

⑦ 进入保护模式后,段寄存器会继续保留它们在实地址模式下的内容,第 4 步的远跳会复位 CS 寄存器,而其它的段寄存器需要进行必要的设置。可以通过重装的方法为其它段寄存器赋值,如果不用 ES, FS 和 GS,需要用 null 选择符来填充。也可以通过执行一个到新任务的 JMP 或 CALL 指令复位段寄存器的值并转移到一个新的代码段。

⑧ 执行 LIDT 指令将保护模式 IDT 的地址和界限装载进 IDTR 。

⑨ 执行 STI 指令来取消对硬件中断的屏蔽。执行必要的硬件操作使能 NMI 中断。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/12

2. 2. 从保护模式返回到实地址模式 从保护模式返回到实地址模式

① 用 CLI 指令屏蔽硬件中断, NMI 用外部硬件电路进行屏蔽

② 如果保护模式下采用了页式存储管理,则需要将程序控制传送到与物理地址保持一致的线性地址空间中,确认 GDT 和 IDT 在具有这样的线性地址的页中,清除 CR0 中的 PG ,将 0H 放入 CR3 中,使得 TLB 被清除。

③ 将程序控制传送到一个只有 64KB 大小的可读段中,这一操作使得 CS 寄存器中的段符合实地址模式的限制。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/13

④ 为 SS, DS, ES, FS 和 GS 加载选择符,该选择符指向的段描述符需要包含符合实地址模式需要的值,如64KB 的界限值、 G=0, E=0, W=1, P=1 ,基地址可以任意。这些段寄存器必须加载非空段选择符,否则段寄存器在实地址模式下是不可用的。

⑤ 执行一条 LIDT 指令来指向实地址模式的中断向量表,该表应该是在 1MB 的实地址模式地址空间中。

⑥ 将 CR0.PE 清零,转换到实地址模式。⑦ 执行一条 far JMP 指令跳转到实地址模式的程序中

。这一操作清空了指令队列,将相应的基地址、访问权限装载进 CS 寄存器。

⑧ 根据实地址模式下的需要,装载 SS, DS, ES, FS 和GS 。凡是不使用的段寄存器都填充 0 。

⑨ 执行 STI 指令,取消对硬件中断的屏蔽,执行必要的硬件操作来使能 NMI 中断。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/14

3. 3. 从保护模式到从保护模式到 IA-32eIA-32e 模式的转换 模式的转换

① 在保护模式下,使用 MOV CR0, reg 指令,另CR0.PG = 0 ,禁止分页。

② 设置 CR4.PAE=1 ,使能物理地址扩展。如果这一步失败,则产生一个 GP#错误。

③ 将 4级页映射表 (PML4) 的物理基地址装载进 CR3。

④ 通过设置 IA32_EFER.LME=1 来使能 IA-32e 模式。

⑤ 通过设置 CR0.PG=1 来允许页式存储管理。这一操作使处理器设置 IA32_EFER.LMA=1

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/15

4. 4. 从从 IA-32eIA-32e 模式到保护模式的转换 模式到保护模式的转换

① 先转换到兼容模式。② 通过设置 CR0.PG=0 来撤出 IA-32e 模式。这一操

作使处理器设置 IA32_EFER.LMA = 0 。③ 将传统页表目录基地址加载到 CR3 。④ 设置 IA32_EFER.LME=0 来禁止 IA-32e 模式。⑤ 设置 CR0.PG=1 来允许传统页式保护模式。⑥ 在 MOV CR0, reg 指令之后一定要有一条分支指令

来允许分页。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/16

10.2 任务管理 10.2.1 任务概述 • 任务执行空间任务执行空间

代码段代码段 数据段数据段 堆栈段堆栈段

• 任务状态段(任务状态段( TSSTSS )) 段寄存器、通用寄存器、段寄存器、通用寄存器、 EFLAGEFLAG 寄存寄存

器、器、 EIPEIP 寄存器、寄存器、 CR3CR3 寄存器、任务寄存器寄存器、任务寄存器、、 LDTRLDTR 寄存器中的内容 寄存器中的内容

I/OI/O映像基地址和映像基地址和 I/OI/O映像 映像 特权级特权级 00 ,, 11 ,, 22 下堆栈的指针 下堆栈的指针 指向前一个任务的链指针 指向前一个任务的链指针

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/17

10.2.2 用于任务管理的数据结构 1. 任务状态段( Task-State Segment, TSS )

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/18

2. TSS 描述符D7 D0

段界限 7~0

段界限 15~8基址 7~0

基址 15~8

基址 23~16

基址 31~24

TYPES

AVL

DPLP

G D/B L 段界限 19~16

0

1

2

3

4

5

6

7

TYPE=1001BTYPE=1001B 表示该任务是非活动任务;表示该任务是非活动任务; TYPE=1011BTYPE=1011B表示该任务处于忙状态(正在执行或被挂起)。 表示该任务处于忙状态(正在执行或被挂起)。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/19

• TSS 描述符只能放在 GDT 中,不能在 LDT 或者IDT 中。• 任何一个 CPL 值小于或等于 TSS 描述符中 DPL 值

的程序或过程,都可以使用 CALL 或 JMP语句调度这个任务。• 一般只有那些具有特权级的程序可以执行任务切换

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/20

10.2.3 任务切换 1.1. 任务切换的原因任务切换的原因

① 当前的程序、任务或者过程执行一个到 GDT 中 TSS描述符的 JMP 或者 CALL 指令;

② 当前的程序、任务或过程执行一条到 GDT 中或当前LDT 中任务门描述符的 JMP 或 CALL 指令;

③ 一个向量指向 IDT 中任务门的中断或异常发生;④ 当 EFLAGS 寄存器中 NT 位被置上时,当前任务执

行了一个 IRET 指令。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/21

2.2. 任务切换的步骤任务切换的步骤1) 从任务门或者前一任务链接域中获得新任务的 TSS 段选择符

作为 JMP 或 CALL 指令的操作数;2) 检查当前任务是否允许切换新任务。要求当前任务的 CPL 和

新任务段选择符中的 RPL 一定要小于等于 TSS 描述符或被引用任务门的 DPL 。但异常、中断(软中断除外)和 IRET指令无需考虑目标任务门或 TSS 描述符中的 DPL 就能够产生任务切换。

3) 确认新任务的 TSS 描述符被标识为当前的,并且段界限大于等于 67H 。验证新任务是可用的。

4) 确认当前 TSS ,新 TSS 以及所有任务切换中用到的段描述符都被分页存储到系统存储器中。

5) 如果任务切换是由 JMP 或 IRET 指令引起的,处理器将把当前任务 TSS 描述符的忙状态位清零,否则该位依然设置为 1。

6) 如果是 IRET 指令引起的任务切换。则在 EFLAGS临时映像中清除 NT标志,否则,保持该位原来的值。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/22

7) 从任务寄存器中取出当前 TSS 的基地址并将通用寄存器、段选择符、 EFLAGS 寄存器的映像和 EIP 的内容拷贝到当前任务的 TSS 中。

8) 如果任务切换是由 CALL 指令,异常或中断引起,则处理器会将新任务的 EFLAGS 中 NT 位置 1;否则,新任务的EFLAGS 中 NT 位不变。

9) 如果任务切换是由执行 CALL , JMP 指令、异常或中断引起的,处理器会将新任务的 TSS 描述符中的忙标志位置 1;否则该位不变(还是 1 )。

10)从任务寄存器中将新任务 TSS 的段选择符和描述符取出来。11)将新 TSS 内容装入到处理器中,这包括 LDTR 寄存

器、 CR3 、 EFLAGS 寄存器、 EIP 寄存器、通用寄存器和段选择符的内容。

12)装入与新任务 TSS 段选择符相关的描述符。13)开始执行新任务

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/23

10.3 IA-32 微机的 BIOS 10.3.1 BIOS及其基本功能

BIOS ( Basic Input Output System )是基本输入输出系统,它包含主板上的一片 ROM 、 E2PROM 或Flash Memory芯片以及被固化在该芯片中的一组程序,这组程序( BIOS 程序)称为固件固件( Firmware )。系统开机后, BIOS 程序被首先启动执行,它为计算机提供最低级最低级的、最直接最直接的硬件初始化和外围设备的控制与支持。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/24

• 系统参数的设置与存放 系统参数的设置与存放 • 开机自检开机自检 (PowerOn SelfTest, POST) (PowerOn SelfTest, POST) • 初始化 初始化 • 提供系统功能调用 提供系统功能调用 • 系统启动自举系统启动自举

BIOSBIOS 的功能的功能

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/25

10.3.2 BIOS 程序的执行流程 引导块启动

解压 Runtime模块

控制转给Runtime 模

Runtime 模块启动

解压 POST模块

POST 模块启动

按 Del键了?

是 解压COMS

Setup 模块执行 CMOS Setup 模块

继续解压POST 模块

完成 POST 启动操作系统引导程序

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/26

10.3.3 BIOS 程序开发

• 开发人员要熟悉汇编编程。• 开发人员要熟悉硬件。 • 开发人员要规划好上层接口。 • 分配好模块,组织好存储区。 • 进行严格的软件测试。 • 选择好必要的开发工具。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/27

10.4 Windows 2000/XP 设备驱动程序设计10.4.1 Windows 2000/XP 的设备驱动程序

虚拟设备驱动程序( VDD )

内核模式驱动程序

文件系统驱动程序

保留设备驱动程序

PnP驱动程序

WDM驱动程序

类驱动程序 迷你驱动程序

可以使 DOS 应用程序访问 x86平台上的硬件,也可以支持Windows 9x 下的对端口访问

是一种遵循电源管理协议并能在 Windows 98 和

Windows 2000 间实现源代码级兼容的 PnP驱动程序

在本地硬盘或网络上实现标准 PC文件系统模型(包括多层次目录结

构和命名文件概念)

过滤器驱动程序

完整功能驱动程序

主要包括Windows NT早期版本的驱动程序,它直接控制一个硬设备而不用其他驱动程序帮助,可以不做修改地在

Windows 2000 中运行

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/28

1. 1. 基本概念基本概念设备对象设备对象:系统为帮助软件管理硬件而创建的一个数据

结构。一个物理设备可以有多个这样的数据结构。

物理设备对象物理设备对象:简称 PDO ,处于设备对象栈最底层的设备对象。每个物理设备被创建一个 PDO

功能设备对象功能设备对象:简称 FDO ,在 PDO 之上,描述设备功能的相关数据结构。

过滤器设备对象过滤器设备对象:简称 FiDOs ,在 FDO 的上面或下面,分别称为上层过滤器和下层过滤器。用于修改现有功能驱动程序的行为。

设备对象栈设备对象栈:设备对象栈代表处理请求的驱动程序层次。

10.4.2 WDM 的基本结构

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/29

FiDO

FDO

FiDO

PDO

上层过滤器驱动程序

功能驱动程序

下层过滤器驱动程序

总线驱动程序

IRP

I/O 系统服务

Win32子系统

应用程序

I/O 管理器

用户态

核心态

设备对象栈

46页

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/30

WDM驱动程序模型中,每个硬件设备可以有多个驱动程序:功能驱动程序功能驱动程序 :管理 FDO 所代表的设备,负责其初始化、处理 I/O 操作完成时产生的中断事件并为用户提供一种适当的设备控制方式。过滤器驱动程序过滤器驱动程序:用于监视和修改 IRP流。硬件或软件人员可利用过滤器驱动程序修改现有功能驱动程序的行为。总线驱动程序总线驱动程序:负责管理硬件和计算机之间的连接。这个驱动程序实际上和同类设备共同拥有。如 PCI总线驱动程序。

2. 2. 硬件设备的驱动程序种类硬件设备的驱动程序种类

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/31

总线驱动程序检测到新的硬件

用户使用控制面板中的“添加新硬件”向导安装一个设备

PnP 管理器为该设备和它的驱动程序在注册表的配置表中添加一些条目

PnP 管理器可能需要调整已经分配给已存在设备的资源,使需要的资源对新设备可用

3. 3. 设备驱动程序安装的顺序设备驱动程序安装的顺序硬件接入

PnP 管理器创建 PDO

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/32

驱动程序被装入后,执行 DriverEntry 程序。来设置驱动程序中各个例程的入口地址

PnP 管理器参照注册表中的信息查找与创建的PDO相关的过滤器和功能驱动程序

PnP 管理器装入最底层的过滤器驱动程序并调用其 AddDevice函数。该函数创建一个 FiDO,从而在过滤器驱动程序和 FiDO 之间建立了

水平连接

按照 INF文件的指令安装驱动程序

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/33

PnP 管理器继续向上执行,依次装入并调用每个低层过滤器、功能驱动程序和每个高层过滤器,

直到完成整个设备对象栈

AddDevice 把 PDO连接到 FiDO上

PnP 管理器给设备发送各种 PnP IRP

PnP 管理器给发送“启动设备” PnP IRP告诉驱动程序已经给它分配了哪些资源 ,驱动程序

使用这些资源分配启动它的设备

驱动程序处于等待处理 IRP 的状态

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/34

当应用程序因要向驱动程序提出各类请求(如读、写数据等)而调用相关函数的时候,就会使得I/O 管理器创建一个 I/O请求包( IRP )。 通常一个 I/O请求包 (IRP) 先被送到设备对象栈的最上层驱动程序然后逐渐过滤到下面的驱动程序。每一层驱动程序都可以决定如何处理 IRP ,既可以直接处理完该 IRP 就不再向下传,也可以处理完后继续传递,还可以只做向下传递的工作。 当下层将请求处理完,返回的信息又通过该包的结构逐层向上传递。

4. IRP4. IRP 传递的顺序传递的顺序

46页

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/35

I/O请求包( IRP )是驱动程序操作的中心,它是一个内核“对象”,是预先定义的数据结构是预先定义的数据结构,,带有带有一组对它进行操作的一组对它进行操作的 I/OI/O 管理器程序管理器程序。 I/O 管理器接收到一个 I/O请求后,在把它传递到合适的驱动程序栈中的最高驱动程序之前,分配并初始化一个 IRP 。一个一个 IRPIRP 有一个固定的首部和一个可变数目的有一个固定的首部和一个可变数目的 I/OI/O栈栈。

10.4.3 I/O请求包 (IRP)

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/36

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/37

• 创建异步 IRP 的 IoBuildAsynchronousFsdRequest• 创建同步 IRP 的 IoBuildSynchronous- FsdRequest• 创建同步 IRP_MJ_DEVICE_CONTROL 或

IRP_MJ_INTERNAL_DEVICE_CONTROL请求的IoBuildDeviceIoControlRequest

• 创建其他种类 IRP 的 IoAllocateIrp• 创建某些 IRP 的子 IRP 的 IoMakeAssociatedIrp 。

创建 IRP 的可以是 I/O 管理器,也可以是其他的驱动程序。能创建 IRP 的函数有:

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/38

在创建一个 IRP 时,同时还创建了一个与之关联的IO_STACK_LOCATION 结构数组,它是 I/O栈中的一项,它包含的成员包括 :• MajorFunction (该 IRP 的主功能码)• MinorFunction (该 IRP 的副功能码)• Parameters ( IRP参数)• DeviceObject (与该栈单元对应的设备对象地址)• FileObject (内核文件对象地址)• CompletionRoutine ( I/O 完成程序地址)• Context (任意的与上下文相关的值)。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/39

在栈 Parameters 成员中,有几个常用的的参数 :• Create ( IRP_MJ_CREATE请求,创建 IRP )• Close ( IRP_MJ_CLOSE请求,关闭 IRP )• Read ( IRP_MJ_READ请求,读 IRP )• Write ( IRP_MJ_WRITE请求,写 IRP )• StartDevice ( IRP_MJ_PNP 的

IRP_MN_START_DEVICE请求,启动设备)• DeviceIOControl ( IRP_MJ_IOCTL请求, IOCTL

IRP )。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/40

大部分参数可以和 Win32函数对应起来

参数 Win32 API

Creat CreateFile

Read ReadFile

Write WriteFile

DeviceIOControl DeviceIoControl

CloseHandle Close

返回

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/41

创建完 IRP 后,可以使用下面的代码做必要设置,并把IRP发送到设备驱动程序。

PDEVICE_OBJECT DeviceObject; //// 设备对象结构设备对象结构PIO_STACK_LOCATION stack =

IoGetNextIrpStackLocation ( Irp ); //// 获得该获得该 IRPIRP 第一第一个堆栈单元的指针个堆栈单元的指针

stack->MajorFunction = IRP_MJ_Xxx; //// 填充填充 MajorFunctionMajorFunction 代码代码

…… //// 可以对栈做其他初始化的工作可以对栈做其他初始化的工作// // 这里可能运行这里可能运行 StartIoStartIo

NTSTATUS status = IoCallDriver ( DeviceObject, Irp );//// 把把 IRPIRP发送到设备驱动程序发送到设备驱动程序

返回

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/42

下面是 IoCallDriver 的执行过程:NTSTATUS IoCallDriver ( PDEVICE_OBJECT device, PIRP

Irp ){ IoSetNextIrpStackLocation ( Irp ); PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation ( Irp ); //// 获得栈单元指针获得栈单元指针 stack->DeviceObject = device ; //// 设置设备对象结设置设备对象结

构地址构地址 ULONG fcn = stack->MajorFunction ; //// 得到主功能号得到主功能号 PDRIVER_OBJECT driver = device->DriverObject;

//// 获得驱动程序对象的地址获得驱动程序对象的地址 return ( *driver->MajorFunction[fcn] )( device, Irp );

//// 利用主功能号调用相应的派遣函数利用主功能号调用相应的派遣函数} *driver-> MajorFunction[fcn]*driver-> MajorFunction[fcn] 是函数指针,它所指向的派遣函数是函数指针,它所指向的派遣函数

是在是在 DriverEntryDriverEntry 例程中指定的。例程中指定的。返回 Driverentry 返回

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/43

WDM驱动程序包含许多函数(例程),操作系统调用这些例程来执行对 IRP 的各种操作。基本驱动程序函数 I/O 控制函数 派遣函数

DriverEntry

AddDevice

StartIO

AdapterControl

OnInterrupt

DpcForIsr

DispatchPnp

DispatchPower

DispatchWmi

DispatchRead

DispatchWrite

StartIO 处理请求队列、 AdapterControl 处理 DMA 操作OnInterrupt 处理中断。

10.4.4 WDM驱动程序的结构

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/44

在每个 WDM驱动程序中,下列函数必须有:• DriverEntry函数:这个例程是每一个设备驱动程序的

入口。在这个例程中完成某些全局初始化工作,还要设置响应各种用户请求的分发例程与 I/O 控制例程的入口。

• AddDevice函数:对于功能驱动程序,其 AddDevice函数的基本职责是创建一个设备对象并把它连接到以PDO 为底的设备堆栈中。

• DispatchPnp函数:用于处理 IRP_MJ_PNP 消息,以便能实现即插即用的功能。

• DispatchPower函数:用于实现对电源管理的支持。• DispatchWmi函数:WMI 是微软实现的基于 Web 的企业管理工业标准,该函数用于处理有关的消息。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/45

下面是一段下面是一段 DriverEntryDriverEntry 程序的片段程序的片段:extern "C" NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN

PUNICODE_STRING RegistryPath ){ // // 初始化函数的入口地址初始化函数的入口地址 DriverObject->DriverUnload = DriverUnload; DriverObject->DriverExtension->AddDevice = AddDevice; DriverObject->DriverStartIo = StartIo; DriverObject->MajorFunction[IRP_MJ_PNP] = DispatchPnp; DriverObject->MajorFunction[IRP_MJ_POWER]=

DispatchPower; DriverObject->MajorFunction[IRP_MJ_SYSTEM_CONTROL]

= DispatchWmi; …… // // 这里可以加入其他这里可以加入其他 MajorFunctionMajorFunction 处理函数的入口地址处理函数的入口地址

返回

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/46

// // 如果驱动程序需要访问设备的服务键,则备份如果驱动程序需要访问设备的服务键,则备份 RegistryPathRegistryPathservkey.Buffer = ( PWSTR ) ExAllocatePool ( PagedPool, RegistryPath->Length+ sizeof ( WCHAR )); if ( !servkey.Buffer ) return STATUS_INSUFFICIENT_RESOURCES; servkey.MaximumLength = RegistryPath->Length + sizeof ( WCHAR ); RtlCopyUnicodeString ( &servkey, RegistryPath ); return STATUS_SUCCESS;}

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/47

添加一个设备添加一个设备NTSTATUS AddDevice ( PDRIVER_OBJECT DriverObject,

PDEVICE_OBJECT pdo ){ NTSTATUS status; PDEVICE_OBJECT fdo; Status=IoCreateDevice ( DriveObject, sizeof ( WDM_DEVICE_EXTENSION ) , NULL, FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo ); //// 在在 fdofdo 中产生我们的功能设备中产生我们的功能设备

对象对象 if ( NT_ERROR ( status )) Return status;……}

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/48

下面是下面是 IRPIRP派遣函数的一个框架:派遣函数的一个框架:NTSTATUS DispatchXxx ( PDEVICE_OBJECT device, PIRP Irp){ PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation ( Irp ); //// 获得栈单元指针获得栈单元指针 PDEVICE_EXTENSION pdx = ( PDEVICE_EXTENSION ) device->DeviceExtension; //// 获得设备扩展获得设备扩展 …… //// 其他其他 IRPIRP 处理操作处理操作 return STATUS_Xxx; //// 返回状态码返回状态码}

返回

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/49

对对 WDMWDM请求包运行机制的总结请求包运行机制的总结1. 应用程序通过 CreateFileCreateFile 等等 Win32Win32函数来进行有关

的请求。2. I/O 管理器创建 IRP 。3.3. 设置设置 IRPIRP 中的主功能代码和对中的主功能代码和对 IRPIRP栈做各种初始化栈做各种初始化工作。工作。如果需要对 IRP排队,则调用 StartIo 处理IRP队列

4.4. 将将 IRPIRP发送到派遣程序发送到派遣程序 (按照 DriverEntry 中指定的入口地址来调用相关的派遣程序)。

5. 执行有关的派遣程序,实际处理对实际处理对 IPRIPR 的操作的操作。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/50

支持即插即用主要是指实现一个 AddDevice 程序和一个 IRP_MJ_PNP 处理程序。这个 PnP IRP 有 8 个次功能代码(它们的主功能代码都是 IRP_MJ_PNP )。 ·   IRP_MN_START_DEVICE 分配资源并启动设备·   IRP_MN_QUERY_REMOVE_DEVICE 询问一个设备是否可以删除·   IRP_MN_REMOVE_DEVICE 设备被拔出,删除设备·   IRP_MN_CANCEL_REMOVE_DEVICE 取消查询删除请求·   IRP_MN_STOP_DEVICE 停止设备进行资源重新分配·   IRP_MN_QUERY_STOP_DEVICE 询问设备是否可以停止·   IRP_MN_CANCEL_STOP_DEVICE 取消查询停止请求· IRP_MN_SURPRISE_REMOVAL 用户在意外下拔出设备

10.4.5 即插即用

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/51

NTSTATUS DispatchPnp( PDEVICE_OBJECT fdo, PIRP Irp ){ PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation( Irp ); ULONG fcn = stack->MinorFunction; // // 取副功能码取副功能码 static NTSTATUS status=STATUS_SUCCESSswitch( fcn ) // // 按照副功能码调用相关的处理函数按照副功能码调用相关的处理函数 { case IRP_MN_START_DEVICE: HandleStartDevice( fdo,Irp );break; case IRP_MN_QUERY_REMOVE_DEVICE :HandleQueryRemove( fdo, Irp ); …… }; if( fcn >= arraysize( fcntab )) return DefaultPnpHandler( fdo, Irp ); return status;}

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/52

WDM 有 4 个标准的资源类型,分别是:• CmResourceTypePort (端口资源)• CmResourceTypeMemory (内存资源)

• CmResourceTypeInterrupt (中断资源)

• CmResourceTypeDma ( DMA资源)

10.4.6 数据的读 /写

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/53

1. 内存与端口访问

尽管 PC 机的 I/O端口是单独编址的,但为了做到和统一编址的机器兼容性, Windows 2000 的设计者使用了硬件抽象层( HAL )的概念。无论是单独编址还是统一编址,只需要使用下表 8 中所给的函数就可以访问端口和内存了。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/54

数据宽度 端口访问函数 内存访问函数

8 位 READ_PORT_UCHARWRITE_PORT_UCHAR

READ_REGISTER_UCHARWRITE_ REGISTER _UCHAR

16 位 READ_PORT_USHORTWRITE_PORT_USHORT

READ_ REGISTER _USHORTWRITE_ REGISTER _USHORT

32 位 READ_PORT_ULONGWRITE_PORT_ULONG

READ_ REGISTER _ULONGWRITE_ REGISTER _ULONG

8 位字符串

READ_PORT_BUFFER_UCHARWRITE_PORT_BUFFER_UCHAR

READ_ REGISTER _BUFFER_UCHARWRITE_ REGISTER _BUFFER_UCHAR

16 位 字符串

READ_PORT_BUFFER_USHORTWRITE_PORT_BUFFER_USHORT

READ_ REGISTER _BUFFER_USHORTWRITE_ REGISTER _BUFFER_USHORT

32 位 字符串

READ_PORT_BUFFER_ULONGWRITE_PORT_BUFFER_ULONG

READ_ REGISTER _BUFFER_ULONGWRITE_ REGISTER _BUFFER_ULONG

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/55

2. 响应中断

响应中断首先要配置中断,也就是截获中断,然后就需要编写中断处理程序。配置中断资源是在 StartDevice函数中实现的,使用从CmResourceTypeInterrupt 描述符中得到的参数来调用IoConnectInterrupt函数。和实模式下一样,在调用IoConnectInterrupt 进行中断配置前应该禁止 PC 机的中断,调用之后再允许设备中断。

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/56

驱动程序根据 INF文件中的指令安装。 INF文件含有安装一个 WDM 设备驱动程序需要的所有必需的信息,包括要复制的文件列表和要创建的注册表项等。 驱动程序可执行文件被复制到正确的位置,通常是Winnt\System32\Drivers 目录,然后创建各种注册表项。 INF文件是一个文本文件,它由节组成,每一节从括在方括号中的节名称开始,后面是节的内容,大部分段都含有一系列“ keyword = value”形式的项。

10.4.7 WDM驱动程序的安装文件

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/57

节 项 值 描 述

[Version]

Signature

ProviderClass

ClassGuidDriverVer

$Windows NT$, $Windows 95$或 $Chicago$INF文件创建者系统定义的类名字,或用户指定的新的类名字匹配的类GUID驱动程序的版本号

[Strings]%String%=”Value”

指定一个字符串

[Manufacturer]

%manufacturer%=models

指定厂商名和对应的 models节的名称

[models]指定产品名称、对应的 install节的名称和硬件 ID , 0 个或多个兼容 ID

现代微机原理与接口技术现代微机原理与接口技术 (( 第第 33版版 ))

http://www.njyangqs.com/http://www.njyangqs.com/58

节 项 值 描 述

[install]

Copyfiles=@filename | filelistAddreg=addregProfileItems

指定要复制的文件,或列出 filelist节的名称指定 addreg节的名称列出指定要添加到“开始”菜单中的项

[DestinationDirs]

DefaultDestDir=dirid,[subdir]filelist= dirid,[subdir]

对默认文件复制和 filelist节中的文件复制 , 指 定 目 录 ID 和 可 选 的 子 目录。 dirid 是一个目录代码,指示存放文件的标准位置。 Windows 2000DDK定义了 这 些 代 码 , 如 代 码 10 表示Windows 目录

[filelist] 要安装的文件列表

[addreg] 添加新的键和值