




已阅读5页,还剩6页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
文件系统驱动编程基础篇之7端口读写 关键字:文件系统驱动编程,端口读写 作者:wskjuf 更新:2008-10-06 22:14:58 浏览:10976文件系统驱动编程基础篇之七端口读写 一、前略 本系列文章为业余编程爱好者而写,仅仅作为初学者的一个借鉴,真正的精华存在于参考资料*中。知识的积累将经历从薄到厚,再从厚到薄的反复过程,为了打下牢固的基础,请读者务必在阅读本文的基础上花费必要的时间完成参考资料。笔者的实践环境为:硬件:P35 Motherboard & ICH9 chip,Pentium Dual Cpu E2160 1.8g, DDR2 1g软件:Windows XP2、VS 2005、Visual AssistX、DriverStudio 3.2、MICROSOFT.WINDOWS.SERVER.V2003.IFS.DDK、Windbg 6.8.0004.0,请安装好用于调试的虚拟机并配置好调试环境。参考资料*:1Programming the Microsoft Windows driver model第一版(当前阶段主要阅读资料,在先前的基础上,本次需要完成前八章)2Windows NT File System Internals - A Developers Guide(资料1理解后可阅读,为后续章节做准备)3OSR White Papers4、Intel 64 and IA-32 Architectures Software Developer s Manual Volume 3A/B System Programming Guide5WinXXX部分源代码6Kernel Debugging with WinDbg(随WinDbg软件附带的文档)阅读基础:了解计算机结构体系、掌握用户模式下常用API调用、了解常用汇编指令。请从现在开始的一年时间里阅读50万字以上的驱动编程外文资料,彻底突破外文关。本章目的:初步掌握硬件驱动编程的基础知识,学习使用Windbg调试。初次阅读代码量在一万行以上的驱动程序。二、问题的提出 xp下直接读写端口会发生什么事情呢?一个简单的测试程序如下:int main(int argc, char* argv)char result;asm mov al, 0x10out 0x70, alin al, 0x71mov result, alprintf(%X, result);return 0;运行后发现程序弹出了异常,无法执行out指令,给出的提示为:这是早已预料的结果。笔者搜索了一下,找到了Direct Port IO and Windows NT,欣欣然之下禁不住想让大家知道原来“不需要”写驱动也可以访问端口了。它究竟是何方神圣?原来这是一种称之为iopm的方法,它涉及了 CPU硬件理论里关于TS段的基础知识:通过修改I/O映射表,用户模式下的进程就具有了存取端口的权限。问题是如何修改I/O映射表?阅读了porttalk和winio的源代码后,发现所谓的iopm还是需要通过驱动代码修改映射表,此外你还需要修改当前进程的映射表偏移地址。当我们费力的写好近千行代码,换来的好处就是真的可以在用户模式下以较快的速度存取端口了。欣欣然的你不妨用文初给出的测试程序来检查一下成果:如果把驱动编程想得这么的简单,那你就有些过于乐观了。现在尝试另一个端口,比如串口的0x3f8,看看有什么奇怪的事情发生?这次读出了0xff,那么0x3f9呢,还是0xff,一直读完串口的所有端口,结果都是0xff。假如我们首先用CreateFile来打开串口,怎么读出的值不再是0xff了,如果关闭了串口再来读一读,结果又是0xff了。Google或baidu后,发现串口原理的资料很少,换个思路来查,查询串口的主要芯片从8250一直搜索到16550A,这下果然搜出了有价值的资料,如Interfacing the Serial RS232 Port,串行输入输出接口,常用的输入输出接口芯片,UART 内部寄存器对应端口及用途等。但这些资料只说明了一个问题很久很久以前,在DOS下是如何发送串口指令的却还是没有解决Windows下的问题。让我们再换一下思路。从DevView里看到串口驱动的基本情况,原来串口的PDO是ACPI。阅读Advanced Configuration and Power Interface Specification,可知ACPI是微软和几个厂家制定的协议,不由得想起使用WINPE启动的时候选择了ACPI,结果机子一次次的重启,本杂牌机无论从外观还是认证标签上看极象兼容ACPI,但假货毕竟是假货。折腾了半天后,因我们的目的不在于如何写ACPI驱动,故这个问题的答案即使和它有关,也请暂时绕过(实践会证明,很多问题都是冤家路窄,避是避不过的_。对ACPI调用IoCallDriver后,激活了串口)。 三、串口代码之实践 本篇最终目的是阅读并调试串口程序,因笔者使用的DDK版本是3790的,源代码位在WINDDK3790srckernelserial下。首先我们要做的是完善串口的调试输出信息函数,修改位于log.c下的SerialDbgPrintEx如下: ULONGSerialDbgPrintEx(IN ULONG Level, PCHAR Format, .) / 级别,格式,不定的参数va_list arglist;ULONG rval;ULONG Mask = 0;ULONG cb;UCHAR bufferSERIAL_DBGPRINT_BUFSIZE;RTL_QUERY_REGISTRY_TABLE paramTable4;ULONG zero = 0;if (KeGetCurrentIrql() = PASSIVE_LEVEL)RtlZeroMemory (mTable0, sizeof(paramTable);paramTable0.Flags = RTL_QUERY_REGISTRY_DIRECT;paramTable0.Name = LSerialDebugLevelBegin;paramTable0.EntryContext = &SerialDebugLevel; / 保存查询结果paramTable0.DefaultType = REG_DWORD;paramTable0.DefaultData = &zero;paramTable0.DefaultLength = sizeof(ULONG);paramTable1.Flags = RTL_QUERY_REGISTRY_DIRECT;paramTable1.Name = LSerialDebugLevelEnd;paramTable1.EntryContext = &SerialDebugLevelEnd; / 保存查询结果paramTable1.DefaultType = REG_DWORD;paramTable1.DefaultData = &zero;paramTable1.DefaultLength = sizeof(ULONG);paramTable2.Flags = RTL_QUERY_REGISTRY_DIRECT;paramTable2.Name = LSerialDebugLevelCloseHigh;paramTable2.EntryContext = &SerialDebugLevelCloseHigh; / 保存查询结果paramTable2.DefaultType = REG_DWORD;paramTable2.DefaultData = &zero;paramTable2.DefaultLength = sizeof(ULONG);RtlQueryRegistryValues( RTL_REGISTRY_ABSOLUTE | RTL_REGISTRY_OPTIONAL,SerialGlobals.RegistryPath.Buffer, / HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServicesSerialmTable0, / 以全0的结尾表结束,这样一次就可以查询多个值了NULL,NULL);Mask = Level;else if (SerialDebugLevelCloseHigh = 1) / 不显示高irql信息return STATUS_SUCCESS;if (Mask SerialDebugLevelEnd) return STATUS_SUCCESS;va_start(arglist, Format); / arglist越过了格式串,指向了参数cb = _vsnprintf(buffer, sizeof(buffer), Format, arglist);if (cb = -1) / 串长于bufferbuffersizeof(buffer) - 2 = n;DbgPrint(IRQL %d, SERIAL: %s, KeGetCurrentIrql(), buffer);/rval = vDbgPrintEx(DPFLTR_SERIAL_ID, Level, Format, arglist);va_end(arglist);rval = STATUS_SUCCESS;return rval;往注册表里添加SerialDebugLevelBegin,SerialDebugLevelEnd,SerialDebugLevelCloseHigh三键,我们可以更灵活的动态控制调试信息。 编译好Checked模式的串口驱动程序后,接下来需要替换掉系统自带的串口驱动WINDOWSsystem32drivers serial.sys(大小为59KB)。希望你首先按照自己的思路来尝试替换,如果失败了再来尝试如下的方法: 1. 关闭系统还原 2. 改名WINDOWSsystem32dllcacheserial.sys3. 将WINDOWSsystem32CatRoot目录改名为其他名字 4. 将你编译好的checked模式的串口驱动程序覆盖WINDOWSsystem32driversserial.sys5. 在硬件管理器里删除掉串口驱动,再重新扫描硬件变更,重新安装驱动时可能出现“是否替换”的提示,选择否,直到你发现驱动目录下的串口驱动程序确实是你自己编译过的程序 6. 运行Dbgview后在硬件管理器里停止串口驱动,再启动驱动,此时可以看见在Dbgview里看见调试信息(前提是注册表已设好上述三键的值) 为了方便阅读代码,简单说明一下串口寄存器。端口0x3f8-0x3fe 用于微机上COM1 串行口,0x2f8-0x2fe 对应COM2 端口。DLAB(Divisor Latch Access Bit)是除数锁存访问位,是指线路控制寄存器的最高位7。表 UART 内部寄存器对应端口及用途序号 端口读/写条件用途00x3f8 (0x2f8)写DLAB=0发送保持寄存器。含有将发送的字符。TRANSMIT_HOLDING_REGISTER读DLAB=0接收缓存寄存器。含有收到的字符。RECEIVE_BUFFER_REGISTER读/写DLAB=1波特率因子低字节(LSB)。DIVISOR_LATCH_LSB10x3f9 (0x2f9)读/写DLAB=1波特率因子高字节(MSB)。DIVISOR_LATCH_MSB读/写DLAB=0中断允许寄存器。INTERRUPT_ENABLE_REGISTER位7-4 全0 保留不用;位3=1 modem 状态中断允许;位2=1 接收器线路状态中断允许;位1=1 发送保持寄存器空中断允许;位0=1 已接收到数据中断允许。20x3fa (0x2fa)读中断标识寄存器。中断处理程序用以判断此次中断是4种中的那一种。INTERRUPT_IDENT_REGISTER位7-3 全0(8250不用,16550:7-6=11 允许fifo, =00 不允许fifo);位2-1 确定中断的优先级;= 11 接收状态有错中断,优先级最高;= 10 已接收到数据中断,优先级第2;= 01 发送保持寄存器空中断,优先级第3;= 00 modem 状态改变中断,优先级第4。位0=0 有待处理中断;=1 无中断。30x3fb (0x2fb)写线路控制寄存器。LINE_CONTROL_REGISTER位7=1 除数锁存访问位(DLAB)。 =0 访问发送保持寄存器、接收缓存寄存器器或中断允许寄存器;位6=1 强迫SOUT送出空闲状态;0 禁止间断;保持奇偶位 位5=1 偶校验时,校验位=0 奇校验时,校验位=1;0 无数位4,3=11 偶校验;=01 奇校验;x0 不加校验位位2=1 (5位数据位时)1.5位停止位,(6,7,8位数据位时)2位停止位;=0 1位停止位;位1-0 数据位长度:= 00 5位数据位;= 01 6位数据位;= 10 7位数据位;= 11 8位数据位。40x3fc (0x2fc)写modem 控制寄存器。MODEM_CONTROL_REGISTER位7-5 全0 保留;位4=1 芯片处于循环反馈诊断操作模式;(自测试循环)SERIAL_MCR_LOOP位3=1 辅助用户指定输出2,允许INTRPT 到系统;SERIAL_MCR_OUT2位2=1 辅助用户指定输出1,PC 机未用;SERIAL_MCR_OUT1位1=1 使请求发送RTS 有效;SERIAL_MCR_RTS位0=1 使数据终端就绪DTR 有效。SERIAL_MCR_DTR50x3fd (0x2fd)读线路状态寄存器。LINE_STATUS_REGISTER位7=0 保留;位6=1 发送移位寄存器为空;位5=1 发送保持寄存器为空,可以取字符发送;位4=1 接收到满足间断条件的位序列;位3=1 帧格式错误;位2=1 奇偶校验错误;位1=1 超越覆盖错误;位0=1 接收器数据准备好,系统可读取。60x3fe (0x2fe)读modem 状态寄存器。 表示信号发生变化。MODEM_STATUS_REGISTER位7=1 载波检测(CD)有效;位6=1 响铃指示(RI)有效;位5=1 数据设备就绪(DSR)有效;位4=1 清除发送(CTS)有效;位3=1 检测到 载波;位2=1 检测到响铃信号边沿;位1=1 数据设备就绪(DSR);位0=1 清除发送(CTS)。#define RECEIVE_BUFFER_REGISTER? (ULONG)(0x00)*SERIAL_REGISTER_STRIDE)/ 本文转自 C+Builder研究 - /article.asp?i=1060&d=fu044r#define TRANSMIT_HOLDING_REGISTER? (ULONG)(0x00)*SERIAL_
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025重庆丰都县中医院招聘4人考试含答案
- 企业多元化人才管理和优化方案
- 企业网络安全数据挖掘与防范规定
- 酒店客房送餐菜单规定
- 制定品牌故事传播策略增强品牌亲和力
- 信息泄露实验总结
- 果园管理的健康树干处理技巧
- 2025咸阳市秦都区丝路花城小学教师招聘笔试备考试题及答案解析
- 2025年精神科学科抑郁症患者自杀风险评估考试答案及解析
- 地产销售经营规程
- 模具移交协议书范本
- 荨麻疹的护理查房课件
- 【课件】2024新课标Ⅱ卷语法填空说课 课件-2025届高三上学期英语一轮复习专项
- 第二单元第二节元素说课稿-2024-2025学年九年级化学鲁教版上册
- 无土栽培技术方案推广指南
- 公租房申请未婚承诺书范本
- 工行授权委托书模板
- 分心驾驶培训课件
- 新人教版高一语文必修1第一单元测试试卷及答案
- 《电化学储能电站消防验收规范》
- 2024秋新人教版物理8年级上册教学课件 1.1 长度和时间的测量
评论
0/150
提交评论