前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >驱动开发(WDM)

驱动开发(WDM)

作者头像
sofu456
发布2020-10-26 15:19:35
1.3K0
发布2020-10-26 15:19:35
举报
文章被收录于专栏:sofu456sofu456

windows

设备对象名称(内核对象必须命名才能被用户层访问产生句柄)

  • \Driver\ 内核模式下访问
  • \.\ 用户模式下访问

winObj(symbollink设备名称的别名,各个节点查看)和devicetree等工具可查看,下载地址:http://www.osronline.com/

  • 设备节点driverNode,对应不同的设备资源PCI、USB等
  • 设备树,pnp管理的设备内部维护一个动态树
  • 设备堆栈driverStack,fdo、pdo、do组成设备栈(devtree的单个分支),irp从设备栈的顶层向底层传递,iocompelete从底层向顶层返回状态
  • 设备对象driverdeObject,一个设备至少一个设备对象,设备对象用户io请求响应,IoCreateDevice创建(需要指定devicetype,例如 FILE_DEVICE_UNKNOWN ),IoAttachDeviceToDeviceStack加入堆栈,DEVICE_EXTENSION用户自定义

分层模型

  • driver_object(结构未开放)和device_object,driver包含多个device对象的链表
  • device包含多个文件对象file_object
  • file_object接收多个irp数据包(内核和应用层隔离通过磁盘交互,需要文件对象)

不同设备的驱动使用不同结构,显卡设备函数地址存储在VIDEO_HW_INITIALIZATION_DATA中,修改函数地址即可自定义设备驱动

三种驱动程序

  • 总线驱动程序(负责和具体的硬件设备交互),单个 I/O 总线设备,并提供与设备无关的单槽功能,创建设备对象=>PDO
  • 功能驱动程序(设备功能的具体实现),驱动单个设备,创建设备对象=>FDO
  • 筛选器驱动,筛选设备的 I/O 请求、设备类或总线(使用ObReferenceObjectByHandle打开设备修改驱动关联的函数),创建设备对象=>DO

API

  • Io,IO管理
  • Ex,内存分配
  • Ke,内核对象调用函数,不能分页
  • Rtl,字符串内存操作
  • Zw、NT,文件和注册表操作
  • Ps,进程、线程

内核用户层数据交换

  • DO_BUFFERED_IO,内存小,效率低
  • DO_DIRECT_IO,内存大(浪费多),效率高

内核执行级别

  • CPU有0~3级的4个执行级别,ring0和ring3是操作系统使用的级别
  • wdm里面的代码不都是Kernel、有的运行在管理模块Executive中,内核代码不支持分页,管理成的代码都应加上PAGED_CODE
  • PAGED_CODE()只有check版本有效,当前函数执行级别>=DISPATCH_LEVAL只能使用非分页内存,使用分页内存assert中断,避免free版本蓝屏
  • #pragma alloc_text()允许函数页面回退

内核对象

  • 对象名称
  • 对象管理器ObReferenceObject引用+1

IRP

  • irp的目标是driverObject的成员FileObject,指向各个设备文件
  • startio(设备忙排队等待)和多线程
  • irp状态决定了io状态,同步io、异步io、延迟io,IoCompleteRequest调用IoComplete函数
  • 内存指针MdlAddress 、AssociatedIrp、SystemBuffer
  • IoStartPacket、IoStartNextPacket遍历irp调用startio
  • fastio,文件系统专用
  • 用户层请求通过服务管理器做api映射后,传入io管理器,查询指定设备

工具:https://github.com/MartinDrab/IRPMon/releases/tag/v1.0-rc

注释

  • 静态分析工具使用,提高分析的准确度

参考:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/devtest/sal-2-annotations-for-windows-drivers

  • 自旋锁,线程不睡眠高效,占用CPU一般用于代码量较少情况
  • 删除锁,避免处理过程中设备被删除,IoAcquireRemoveLock、IoReleaseRemoveLock释放

内核交互

  • mmap(linux的方式,内核物理内存,应用层虚拟内存,通过共享内存映射内核到文件上(磁盘交互的方式),实现应用层对内核的快速访问),windows可以参考wdm安装包sample中的video,mirror模块disp
  • deviceIoControl
  • createfile、deletefile、openfile、createdc(参考video的mirror示例)

其他

  • CONTAINING_RECORD已知成员地址,求首地址,(&(struct *)0)->member不会报错
  • isr中断服务函数,irql level中断处理级别

  • irql中断最高级别dirql处理中断
  • DISPATCH_LEVEL级别处理dpc队列
  • APC_LEVEL处理回调apc
  • PASSIVE_LEVEL处理driverentry等分发函数
  • umdf的接口IDriverEntry
  • hardware id 标识inf文件
  • 每个线程都有一个APC队列,用户线程在唤醒和睡眠前(可警醒状态未真正睡眠)都会先执行apc队列中的函数
  • 驱动安装setupapi或者cmapi(pnp安装)

WDM

WDM、WDF(WDM基础上架构的开发框架)

  • NT驱动通过服务安装(服务通过sc命令查询)
  • WDM驱动inf、cat、cer文件安装

windows ssdt hook技术

InstallSysServiceHook函数在driverentry中替换原有的函数地址 https://www.cnblogs.com/BoyXiao/archive/2011/09/04/2166596.html

linux

  • 设备文件:/dev目录下,设备分为

  • 字符设备,能够像字节流(类似文件)一样被访问的设备
  • 块设备,设备每次只能传输一个或多个完整的块,而每块包含512字节
  • 网络设备
  • driver注册和注销,int driver_register(struct device_driver *drv)
  • bus注册和注销,bus_register(struct bus_type *bus)
  • device注册和注销,int device_register(struct device *dev)

驱动安装

  • 静态加载,把驱动程序直接编译进内核,系统启动后可以直接调用,重新下载(源码下载地址:https://www.kernel.org/)和编译内核,效率较低
  • 动态加载,下载linux内核源码,使用内核工具编译成模块,系统启动后用insmod命令添加模块(.ko),在不需要的时候用rmmod命令卸载模块

linux的三个基本构件是:引导系统(boot loader), linux内核,根文件系统,包含3个基本构件可以生成镜像img文件,busybox可以生成最小文件系统

参考

micosoft:https://docs.microsoft.com/zh-cn/windows-hardware/drivers/kernel/ linux:https://www.cnblogs.com/Bright-Ho/p/5497481.html

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020-10-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • windows
  • 内核交互
  • WDM
  • windows ssdt hook技术
  • linux
  • 参考
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档