windows驱动开发-32位和64位

这部分其实是过时的知识点,毕竟win 11之已经不支持32位系统了,但是还是列出来吧。

32位主要是指x86体系,在早期,32位的应用程序和系统只支持4GB的内存地址寻址,这也是最大的特色之一,在那个时代,由于对内存限制导致出现了许多精巧的设计,这个体系也称为一个经典的体系,然而时代变了,64位出现之后,内存不再是一个问题,这也导致了后续很多编程都开始向64位转移,这篇文档主要侧重点也是讲32位驱动如何升级到64位驱动。

32位和64位的区别

32位和64位的本质区别就是指针长度的不一样,32位的指针是4字节,64位指针是8字节,大部分和指针长度无关的程序都能直接在64位下编译成功,唯一的例外是,用32位无符号整数和指针进行互相转换,这种情况下需要将32位无符号整数换成64位无符号整数。

对于用户模式应用程序,64 位 Windows 包括 Windows 上的 Windows (WOW64) thunking 层 ,使 32 位应用程序能够在 64 位版本的 Windows 上执行,虽然会有一定的性能下降。 它通过截获 32 位函数调用,并在转换到 64 位内核之前根据需要将指针精度参数类型转换为固定精度类型来执行此操作。 此转换过程称为 thunking。注意 此 thunking 仅适用于 32 位 应用程序;64 位版本的 Windows 不支持 32 位 驱动程序 。

在 32 位 Windows 上,整型、长整型和指针数据类型的大小都相同,即 32 位。 这种便捷的数据类型大小统一性对聪明的 C 程序员来说是一个福音,他们中的许多人都将其视为理所当然。

但是,在 64 位 Windows 上,这种统一性假设不再有效。 指针的长度现在为 64 位,但整数和长数据类型的大小仍与之前相同32 位。 这是因为,虽然需要 64 位指针来容纳具有多达 16 TB 虚拟内存的系统,但大多数数据仍然适合 32 位整数。 对于大多数应用程序,将默认整数大小更改为 64 位只会浪费空间。

在 32 位 Windows 平台上,操作系统会自动修复内核模式内存对齐错误,并使它们对应用程序不可见。 它对调用进程和任何后代进程执行此操作。 此功能通常会大幅降低性能,但尚未在 64 位 Windows 中实现。 因此,如果 32 位驱动程序包含不对齐 bug,则需要在移植到 64 位 Windows 时修复它们。

在 64 位 Windows 中执行 DMA

向驱动程序添加 64 位寻址支持可以显著提高整体系统性能。 对于 DMA这样执行直接内存访问的设备驱动程序来说,这一点尤其重要。 在 64 位 Microsoft Windows 中,执行 DMA 但不支持 64 位寻址的设备驱动程序是双缓冲的,这会导致相对性能降低。

尽管双缓冲通常 在8 GB 系统上),造成的单个百分点的影响相对较小,但这足以影响 I/O 密集型任务,例如数据库活动。 随着物理内存量的增加,这种负面的性能影响也会增加。

若要支持 64 位 DMA,驱动程序应遵循以下准则:

  • 使用 PHYSICAL_ADDRESS 结构进行物理地址计算;
  • 将整个 64 位地址视为有效的物理地址。 例如,驱动程序不应在锁定的缓冲区上调用 MmGetPhysicalAddress 、放弃高 32 位,并将截断的地址传递给 32 位组件适配器。 这会导致内存损坏、I/O 丢失和系统故障;
  • 使用在 Windows 2000 中添加 (GetScatterGatherList 和 PutScatterGatherList) 的高性能Scatter/Gather例程;
  • 检查 Mm64BitPhysicalAddress 全局系统变量的值。 如果为 TRUE,则系统支持 64 位物理寻址;
  • 将 DEVICE_DESCRIPTION 结构的 Dma64BitAddresses 成员设置为 TRUE 以指示驱动程序支持 64 位 DMA 地址;

32 位 Windows 中的 DMA 例程是 64 位就绪的。 如果设备驱动程序正确使用这些例程,则 DMA 代码应在 64 位 Windows 上无需修改即可正常工作。

在 64 位驱动程序中支持 32 位 I/O

Windows 上的 Windows (WOW64) 使 Microsoft Win32 用户模式应用程序能够在 64 位 Windows 上运行。 在转换到 64 位内核之前,它通过截获 Win32 函数调用并将参数从 32 位指针类型转换为 64 位指针类型来执行此操作。 对于所有 Win32 函数,此转换称为 thunking,它会自动完成,但有一个重要例外:传递给 DeviceIoControl 的数据缓冲区。 这些缓冲区的内容(由 InputBuffer 和 OutputBuffer 参数指向)不会被处理,因为它们的结构特定于驱动程序。

注意 尽管缓冲区内容未受到限制,但缓冲区指针将转换为 64 位指针。

用户模式应用程序调用 DeviceIoControl 以将 I/O 请求直接发送到指定的内核模式驱动程序。 此请求包含 I/O 控制代码 (IOCTL) 或文件系统控制代码 (FSCTL) 和指向输入和输出数据缓冲区的指针。 这些数据缓冲区的格式特定于 IOCTL 或 FSCTL,后者又由内核模式驱动程序定义。 由于缓冲区格式是任意的,并且驱动程序知道它,而不是 WOW64,因此将数据转换的任务留给驱动程序。

如果满足以下所有条件,则 64 位驱动程序必须支持 32 位 I/O:

  • 驱动程序向用户模式应用程序公开 IOCTL (或 FSCTL) ;
  • IOCTL 使用的至少一个 I/O 缓冲区包含指针精度数据类型;
  • 无法轻松重写 IOCTL 代码,以消除指针精度缓冲区数据类型的使用;
驱动程序如何识别 32 位调用方

驱动程序可通过两种方式来确定 IOCTL 或 FSCTL 请求的发起方是 32 位还是 64 位应用程序。 第一种是让应用程序标识自身。 第二种是让驱动程序自行确定应用程序是 32 位还是 64 位。

第一种方法涉及在 IOCTL 或 FSCTL 控制代码中定义“64 位”字段。 此字段包含仅为 64 位调用方设置的单个位。 因此,64 位调用方通过使用设置此位的一组单独的 64 位控制代码来标识自己。 32 位调用方使用一组类似的控制代码,其中未设置此位。

第二种方法允许 32 位和 64 位应用程序继续使用相同的 IOCTL 或 FSCTL 代码。 相反,驱动程序通过调用 IoIs32bitProcess 来确定用户模式进程是 32 位还是 64 位。

第一种方法更有效,因为驱动程序会检查位标志,而不是调用内核模式例程。 但是,第二种方法不需要更改用户模式代码。 应使用哪种技术取决于驱动程序的要求以及向其发送 I/O 请求的应用程序。

x64 驱动程序的限制

在基于 x64 的系统上,内核代码和某些内核数据结构受到保护,防止修改。 任何尝试修改此类代码或数据的驱动程序都将导致系统检查 (CRITICAL_STRUCTURE_CORRUPTION) 。

基于 x64 的系统驱动程序必须避免可能触发此 bug 的操作检查。 具体而言,驱动程序不得:

  • 尝试在运行时修改内核代码;
  • 实现和使用自己的堆栈;
  • 修改硬件调度表,例如中断调度表 (IDT) 或全局描述符表 (GDT) ;
  • 修改未记录的内核数据结构;

即使上述操作不会在基于 x86 或基于 Itanium 的系统上触发 bug 检查,驱动程序也不应在任何平台上执行这些操作。 这些操作在 Microsoft Windows 操作系统的未来版本中可能不起作用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/8761.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

嵌入式开发八:STM32启动过程分析

本次给大家分析 STM32F4 的启动过程,这里的启动过程是指从 STM32 芯片上电复位执行的第一条指令开始,到执行用户编写的 main 函数这之间的过程。我们编写程序,基本都是用 C 语言编写,并且以 main 函数作为程序的入口。但是事实上&…

1.使用uniapp搭建微信小程序项目并引入前端组件资源

文章目录 1. 项目配置1.1. 新建vue3项目1.2. 关联云空间1.3. 运行到微信开发者工具 2. 前端组件2.1. uniCloud的内置组件和扩展组件2.2. uView3.02.3. 在uniapp项目引入uview3 1. 项目配置 1.1. 新建vue3项目 由于我们要使用vue3而不是vue2,所以要选好版本&#x…

CMakeLists.txt语法规则:条件判断中表达式说明四

一. 简介 前面学习了 CMakeLists.txt语法中的 部分常用命令,常量变量,双引号的使用。 前面几篇文章也简单了解了 CMakeLists.txt语法中的条件判断,文章如下: CMakeLists.txt语法规则:条件判断说明一-CSDN博客 CMa…

【GPT调用】本地使用python调用GPT接口

python调用GPT接口 环境变量设置主调用方法执行结果 环境变量设置 .env文件中配置GPT环境变量 api_key"你的GPT-API-KEY" urlhttps://ai-proxy.ksord.com/wps.openai.azure.com/openai/deployments/gpt-4-32k/chat/completions?api-version2023-09-01-preview主调…

中国结(科普)

中国结是一种手工编织工艺品,它身上所显示的情致与智慧正是汉族古老文明中的一个侧面。 [1]它原本是由旧石器时代的缝衣打结,后推展至汉朝的仪礼记事,再演变成今日的装饰手艺。周朝人随身的佩戴玉常以中国结为装饰,而战国时代的铜…

1756jsp农产品销售管理系统Myeclipse开发mysql数据库C2C模式java编程计算机网页项目沙箱支付

一、源码特点 java 农产品销售管理系统 是一套完善的web设计系统,对理解JSP java编程开发语言有帮助,系统具有完整的源代码和数据库,系统采用web模式,系统主要采用B/S模式开发。开发环境为TOMCAT7.0,Myeclipse8.5开发&#xff0…

天龙怀旧游戏python脚本

设置图: 游戏窗口最大化。 海贼洞这里定位你要回点的定位。 运行bat就行,脚本出错了还是会重新运行脚本,运行自动启动,end暂停脚本,home重新启动脚本 1. 我常用的是内挂回点脚本, 下面都是前台脚本&…

Java - 分布式逻辑事务的一些轻操作

前提条件 可控业务在不可控业务前不可控业务自己保证数据回滚一致性 设计思路 若可控业务A失败,则不发送给不可控业务B,直接回滚;若可控业务A成功,发送给不可控业务B,B处理完返回标记,B成功,则…

Python-100-Days: Day09 Object-oriented programming(OOP) Upgrade

1.property装饰器 之前有讨论过, Python中属性和方法访问权限的问题,不建议将属性设置为私有的,倘若直接将属性暴露给外界也是存在问题的。例如,我们没有办法检查赋给属性的值是否有效。之前的建议是将属性命名以单下划线开头&am…

C#贪吃蛇

C#贪吃蛇 文章目录 Program.csText1Game.csISceneUpdate.csText2BeginScene.csBegionOrEndScene.csEndScene.csGameScene.csText3GameObject.csIDraw.csPosition.csText4Food.csSnakeBody.csWall.csText5Map.csText6Snake.csProgram.cs using 贪吃蛇.Text1;Game game = new Ga…

Chapter 1-19. Introduction to Congestion in Storage Networks

Q: What effects does NVMe over Fabrics have on network congestion? All environments are different; hence a general answer is not possible. 所有的环境都是不同的,因此不可能给出一个笼统的答案。 The high amount of parallelism of NVMe may increase network u…

java语言数据结构(单链表)

前言 不得承认java应用的广泛,所以毅然决定java版本的数据结构和算法专题还是要坚决更新。每日更新2题,希望学习的小伙伴可以关注一波跟上,评论区欢迎讨论交流。 实现原理 节点(Node):链表的基本构建单元…

mybatis使用及配置相关,仅做个人记录

在spring-boot项目中mybatis的配置文件在yml文件中,并没有mybatisconfig.xml文件 yml文件中配置:(来源:https://blog.51cto.com/u_16213723/8747999) mybatis:# XML文件路径,可配置多个,逗号分…

ElementUI Select选择器多选获取选中对象

html <el-form-item label"账户标签&#xff1a;" prop"tags"><el-selectstyle"width: 500px"value-key"tagId"v-model"form.tags"clearablefilterablemultipleplaceholder"请搜索选择账户标签"><…

网络基础-ARP协议

ARP&#xff08;Address Resolution Protocol&#xff0c;地址解析协议&#xff09;是一种用于将IP地址映射到物理MAC地址的协议&#xff1b;在计算机网络中&#xff0c;每个设备都有一个唯一的MAC地址&#xff0c;用于在局域网内进行数据通信。而IP地址则是用于在更大范围的网…

每日一题——力扣面试题 17.04. 消失的数字

题目链接&#xff1a;https://leetcode.cn/problems/missing-number-lcci/description/ 菜鸡做法&#xff1a; #include <stdlib.h> // 包含标准库头文件&#xff0c;用于内存分配等功能// 函数定义&#xff1a;寻找缺失的数字 int missingNumber(int* nums, int numsSi…

基于二维CS-SCHT变换和扩频方法的彩色图像水印嵌入和提取算法matlab仿真

目录 1.算法运行效果图预览 2.算法运行软件版本 3.部分核心程序 4.算法理论概述 5.算法完整程序工程 1.算法运行效果图预览 2.算法运行软件版本 matlab2022a 3.部分核心程序 ............................................................. % figure; % subplot(121);…

Visual Studio C++ 2019进行安装

Visual Studio C 2019进行下载安装 链接&#xff1a;https://my.visualstudio.com/Downloads?qvisual%20studio%202017&wt.mc_idomsftvscom~older-downloads

SwiGLU激活函数

SwiGLU激活函数已经成为LLM的标配了。它是GLU的变体&#xff0c;公式如下&#xff1a; SwiGLU ⁡ ( x , W , V , b , c , β ) Swish ⁡ β ( x W b ) ⊗ ( x V c ) \operatorname{SwiGLU}(x, W, V, b, c, \beta)\operatorname{Swish}_\beta(x Wb) \otimes(x Vc) SwiGLU(x,…

开源免费的发票识别OCR应用:Invoice

Invoice&#xff1a;轻松识别&#xff0c;发票电子化扫描烦恼消- 精选真开源&#xff0c;释放新价值。 概览 Invoice 是github社区上一个采用开源许可协议发布的增值税发票光学字符识别&#xff08;OCR&#xff09;解决方案项目。该项目不仅集成了预训练的高级模型&#xff0c…