Windows 版 (精华区)
发信人: wugang (◆◆King◆◆), 信区: OS
标 题: 在Windows NT 下实现对I/O地址的访问
发信站: 紫 丁 香 (Tue Oct 12 23:02:00 1999), 转信
南京师范大学物理系
单学民
---- Windows NT 操作系统设置的进程模式会使运行在其中的应
用程序访问I/O地址的指令引起保护性的失败。这使得应用程序
需要附以一个设备驱动程序进行I/O操作。设备驱动程序运行在
内核模式,这使得在这种状态的中运行的进程可以执行I/O操
作。
---- Windows 95/98 是仅为 Intel 类型机器设计的,没有额外
复杂的I/O需求,而Windows NT 被设计成可以在不同机器机构上
进行移植。这使得Windows NT 的系统模式要求驱动程序的编写
者要考虑一台机器可能有多种类型的总线,这可能需要在总线之
间传递地址。这种模式还要区别I/O空间和内存空间。在多总线
的机器中每一总线可以既支持内存又支持I/O循环。
---- 根据定义,I/O寄存器或者端口访问是通过I/O循环实现
的。然而,在一些系统中外部总线的I/O空间可以被映像到进程
内存空间。硬件抽象层(Hardware Abstract Layer)决定这
些。要访问I/O寄存器,驱动程序编写者必须知道寄存器在那一
总线,它的I/O 空间地址在那条总线。一条总线是由其接口类行
(如 ISA 、PCI 等)和编号(从零开始)决定的。
---- 下面是一个假象设备访问I/O的例子,接口类型:ISA 编号
0 地址 0xE700。设备描述如下:
Offset Size Usage
0 1 Command register
1 1 Status register
2 2 Word data register
4 4 Dword data register
---- 用开发NT 设备驱动程序的工具包DriverDorks 可以用以下
步骤访问设备:
---- 建立一个KIoRange的对象映像设备寄存器。
KIoRange DeviceIos;
Status = DevceIos.Initialize(
Isa, // 总线类型
0, // 总线号
0xE700, // 总线地址
8, // 设备数
TRUE // 映像到系统空间(如果端口是内存映像的)
);
if(NT_SUCCESS(status)) //建立成功
---- 可以用KIoRange 的成员函数访问寄存器:
//寄存器偏移量
#define COMMAND 0
#define STATUS 1
#define WDATA 2
#define DDATA 3
//读状态寄存器
UCHAR DeviceStatus = DeviceIos.inb(STATUS);
//写命令寄存器
DeviceIos.outb(COMMAND,CMD_RESET);
//写20个字到端口
DeviceIos.outw(WDATA,buffer,20);
---- 另外也可以建立KIoRegister 的对象来访问设备:
KIoRegister CommandReg = DeviceIos[COMMAND];
KIoRegister StatusReg = DeviceIos[STATUS];
CommandRge=(UCHAR)RESET; //写 RESET命令
UCHAR status=StatusReg; //读状态寄存器
如果在同一函数中频繁访问寄存器用KioRegiser 比用KIoRange
的成员函数的性能好一些 。无论如何,数据类型必须正确
(UCHAR,USHORT,ULONG),这些决定了到总线上数据的实际大
小。
--
_______
伞 ノ____ノ\ ★ 伞 ┌───────┐
伞伞 | ∩ ▓ 伞伞 │ ◆◆KING◆◆ │
伞伞伞 ˉˉˉˉˉ -_ 伞伞伞 │ Icq:10689743 │
‖ ▇▇▇▇▇▇ -__-- ‖ └───────┘
_._.-*'"'*-._,_.-*'"'*-._,_.-*'"'*-._,_.-*'"'*-._,_.-*'"'*-._,_.-*'"'*-._,_.-*
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: rainy.hit.edu.cn]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:3.528毫秒