47、Windows驱动程序模型笔记(五),内存管理

简介: 内存管理 1)内核模式与用户模式地址 图示 地址空间中用户模式部分和内核模式部分     每个用户模式进程都有自己的地址上下文,它把用户模式的虚拟地址映射成一组唯一的物理页帧。这意味着,当Windows NT调度器把控制从一个进程的当前线程切换到另一个进程的某个线程时,与进程相对应的虚拟地址空间也被更换。

内存管理<?xml:namespace prefix = o />

1)内核模式与用户模式地址

wps_clip_image-4593

图示 地址空间中用户模式部分和内核模式部分

    每个用户模式进程都有自己的地址上下文,它把用户模式的虚拟地址映射成一组唯一的物理页帧。这意味着,当Windows NT调度器把控制从一个进程的当前线程切换到另一个进程的某个线程时,与进程相对应的虚拟地址空间也被更换。线程切换的一个步骤就是改变处理器当前使用的页表,以便它能引用新线程的进程上下文。

    在编写驱动程序时我们要遵守下面原则:

    决不(或几乎从不)直接引用用户模式的内存地址,无论何时我们需要访问计算机内存,都要使用内核模式的虚拟地址。

2)页大小

    在虚拟内存系统中,操作系统以固定大小的页帧组织物理内存和交换文件。在WDM驱动程序中,常量PAGE_SIZE指出页的大小。在某些Windows NT计算机中,一页有4096字节;在另一些计算机中,一页有8192字节。有一个相关常量PAGE_SHIFT,你可以从下面语句中看出它的值:

PAGE_SIZE == 1 << PAGE_SHIFT

下面预处理宏可以简化页大小的使用:

•ROUND_TO_PAGES 把指定值舍入为下一个页边界。例如,在4KB页的计算机上,ROUND_TO_PAGES(1)的结果为4096,ROUND_TO_PAGES(4097)的结果为8192。

•BYTES_TO_PAGES 得出给定的字节量需要多少页来保存。例如,BYTES_TO_PAGES(42)在所有平台上都等于1,而BYTES_TO_PAGES(5000)在4KB页的平台上为2,在8KB页的平台上为1。

•BYTE_OFFSET 返回虚拟地址的字节偏移部分。例如,在4KB页的计算机上,BYTE_OFFSET(0x12345678)的结果为0x678。

•PAGE_ALIGN 把虚拟地址舍向上一个页边界。例如,在4KB页的计算机上,PAGE_ALIGN(0x12345678)的结果为0x12345000。

•ADDRESS_AND_SIZE_TO_SPAN_PAGES 返回从指定虚拟地址开始的指定字节数所跨过的页数。例如,在4KB的计算机上, ADDRESS_AND_SIZE_TO_SPAN_PAGES(0x12345FFF,2)的结果为2,因为这两个字节跨过了页边界。

3)Windows NT把内核模式地址空间分成分页内存池和非分页内存池。(用户模式地址空间总是分页的) 必须驻留的代码和数据放在非分页池;不必常驻的代码和数据放在分页池中。

执行在高于或等于DISPATCH_LEVEL级的代码不可以引发页故障。

#ifdef ALLOC_DATA_PRAGMA

#pragma data_seg("PAGE")

#endif

data_seg编译指示使所有在其后声明的静态数据变量进入分页池。这个编译指示与alloc_text完全不同。一个分页段可以从#pragma data_seg("PAGE")出现的地方开始到#pragma data_seg()出现的地方结束。而Alloc_text仅应用于单个函数。

    为了检测编译器是否是Microsoft的编译器,可以测试预定义宏_MSC_VER是否存在。

掉电期间是释放锁定内存页的最佳时期。

服务函数

描述

MmLockPagableCodeSection

锁定含有给定地址的代码段

MmLockPagableDataSection

锁定含有给定地址的数据段

MmLockPagableSectionByHandle

用MmLockPagableCodeSection返回的句柄锁定代码段(仅用于Windows 2000)

MmPageEntireDriver

解锁所有属于某驱动程序的页

MmResetDriverPaging

恢复整个驱动程序的编译时分页属性

MmUnlockPagableImageSection

为一个锁定代码段或数据段解锁

服务函数或宏

描述

PushEntryList

向链表顶加入元素

PopEntryList

删除最上面的元素

4)把C/C++编程规范引入驱动编程中

如RemoveHeadList是一个宏,如果if语句中不用{},则出问题。

5)图示显示了 lookaside链表的概念。假设有一个可以在水池中直上直下平衡的玻璃杯子。这个杯子就代表lookaside链表对象。当初始化该对象时,你告诉系 统需要多大的内存块(杯中的水滴)。在早期版本的Windows NT中,你还要指出杯子的容量,但现在的操作系统可以自动适应。为了满足一个内存分配请求,系统首先尝试着从链表中取出(删除)一块内存(从杯子中取出一 滴水)。如果连一块内存也没有,系统就从外面内存池中取。相反,释放内存时,系统首先尝试着放到链表上(向杯子中加入一滴水)。但是,如果链表满了,那么 这个内存块就返回到外界的内存池中(杯子中的水溢出到水池)。

wps_clip_image-21083

图示. Lookaside链表

4、字符串

String Manipulation

http://msdn.microsoft.com/en-us/library/ee479680.aspx

Buffer Manipulation

http://msdn.microsoft.com/en-us/library/ee479504.aspx

P89串处理函数

操作

ANSI串函数

Unicode串函数

Length

strlen

wcslen

Concatenate

strcat, strncat

wcscat, wcsncat,

RtlAppendUnicodeStringToString,

RtlAppendUnicodeToString

Copy

strcpy, strncpy,

RtlCopyString

wcscpy, wcsncpy,

RtlCopyUnicodeString

Reverse

_strrev

_wcsrev

Compare

strcmp, strncmp,

_stricmp, _strnicmp,

RtlCompareString,

RtlEqualString

wcscmp, wcsncmp, _wcsicmp,

_wcsnicmp,

RtlCompareUnicodeString,

RtlEqualUnicodeString,

RtlPrefixUnicodeString

Initialize

_strset, _strnset,

RtlInitAnsiString,

RtlInitString

_wcsnset, RtlInitUnicodeString

Search

strchr, strrchr, strspn,

strstr

wcschr, wcsrchr, wcsspn, wcsstr

Upper/lowercase

_strlwr, _strupr,

RtlUpperString

_wcslwr, _wcsupr,

RtlUpcaseUnicodeString

Character

isdigit, islower, isprint,

isspace, isupper, isxdigit,

tolower, toupper,

RtlUpperChar

towlower, towupper,

RtlUpcaseUnicodeChar

Format

sprintf, vsprintf, _snprintf,

_vsnprintf

swprintf, _snwprintf

String conversion

atoi, atol, _itoa

_itow, RtlIntegerToUnicodeString,

RtlUnicodeStringToInteger

Type conversion

RtlAnsiStringToUnicodeS

ize, RtlAnsiStringToUnicodeS

tring

RtlUnicodeStringToAnsiString

Memory release

RtlFreeAnsiString

RtlFreeUnicodeString

1)处理blob数据的服务函数

. 处理blob数据的服务函数

服务函数或宏

描述

memchr

blob中寻找一个字节

memcpy, RtlCopyBytes, RtlCopyMemory

复制字节,不允许重叠

memmove, RtlMoveMemory

复制字节,允许重叠

memset, RtlFillBytes, RtlFillMemory

用给定的值填充blob

memcmp, RtlCompareMemory, RtlEqualMemory

比较两个blob

memset, RtlZeroBytes, RtlZeroMemory

blob清零

•内存的“copy”和“move”操作之间的区别在于可否容忍源和目的相重叠。move操作不管源和目的是否重叠。而copy操作在源和目的有任何重叠时不工作。

•“byte” 操作和“memory”操作的区别是操作的间隔尺寸。byte操作保证按字节为单位执行。而memory操作可以在内部使用更大的块,所有这些块的和等于 指定的字节数。这个区别会根据平台的不同而改变,在32位Intel计算机上,byte操作实际上是对应memory操作的宏。但在Alpha平台 上,RtlCopyBytes与RtlCopyMemory是完全不同的函数。

5、注册表

服务函数

描述

IoOpenDeviceRegistryKey

打开PDO专用键

IoOpenDeviceInterfaceRegistryKey

打开与注册设备接口相连的键

RtlDeleteRegistryValue

删除一个注册表值

RtlQueryRegistryValues

从注册表中读取多个值

RtlWriteRegistryValue

向注册表写一个值

ZwClose

关闭注册表键句柄

ZwCreateKey

创建一个注册表键

ZwDeleteKey

删除一个注册表键

ZwEnumerateKey

枚举子键

ZwEnumerateValueKey

枚举某注册表键中的值

ZwFlushKey

把注册表更改提交到磁盘

ZwOpenKey

打开一个注册表键

ZwQueryKey

取关于某注册表键的信息

ZwQueryValueKey

取某个注册表键中的值

ZwSetValueKey

置某个注册表键中的值

表示. 注册表访问函数

6、浮点数

    在Intel处理器上,浮点协处理器还可以执行MMX指令。在历史上,驱动程序在执行浮点运算上有两个问题。对于没有浮点协处理器的计算机,操作系统将用 软件仿真一个,但是仿真的浮点协处理器会消耗很大的CPU处理能力,并且需要一个处理器异常来捕捉浮点指令。在内核模式中处理异常,尤其是在提升的 IRQL级上,是困难的。另外,在有浮点协处理器的计算机上,由于CPU结构上的原因,当线程上下文切换时,需要一个耗时的操作来保存和恢复浮点协处理器 的状态。所以,通常的做法是禁止在内核模式驱动程序中使用浮点运算。

    Microsoft建议,除非必要,应避免在内核模式驱动程序中使用浮点运算。

关于如何使用及更多信息,可以参见《Windows驱动程序模型设计》,P99

目录
相关文章
|
15天前
|
Java 大数据 Go
从混沌到秩序:Java共享内存模型如何通过显式约束驯服并发?
并发编程旨在混乱中建立秩序。本文对比Java共享内存模型与Golang消息传递模型,剖析显式同步与隐式因果的哲学差异,揭示happens-before等机制如何保障内存可见性与数据一致性,展现两大范式的深层分野。(238字)
35 4
|
2月前
|
并行计算 数据格式 异构计算
完整教程:从0到1在Windows下训练YOLOv8模型
本文详细介绍在Windows系统下使用YOLOv8训练目标检测模型的完整步骤,涵盖环境配置、数据集准备、模型训练与测试、常见问题解决及GPU加速技巧。提供详细命令与代码示例,并推荐现成数据集与工具,助您高效完成模型训练。
884 13
完整教程:从0到1在Windows下训练YOLOv8模型
|
3月前
|
人工智能 边缘计算 自然语言处理
普通电脑也能跑AI:10个8GB内存的小型本地LLM模型推荐
随着模型量化技术的发展,大语言模型(LLM)如今可在低配置设备上高效运行。本文介绍本地部署LLM的核心技术、主流工具及十大轻量级模型,探讨如何在8GB内存环境下实现高性能AI推理,涵盖数据隐私、成本控制与部署灵活性等优势。
1292 0
普通电脑也能跑AI:10个8GB内存的小型本地LLM模型推荐
|
12月前
|
存储 前端开发 Java
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
Kotlin教程笔记 - MVVM架构怎样避免内存泄漏
155 2
|
8月前
|
存储 人工智能 编解码
TripoSF:3D建模内存暴降80%!VAST AI新一代模型细节狂飙82%
TripoSF 是 VAST AI 推出的新一代 3D 基础模型,采用创新的 SparseFlex 表示方法,支持 1024³ 高分辨率建模,内存占用降低 82%,在细节捕捉和复杂结构处理上表现优异。
235 10
TripoSF:3D建模内存暴降80%!VAST AI新一代模型细节狂飙82%
|
6月前
|
Web App开发 人工智能 JSON
Windows版来啦!Qwen3+MCPs,用AI自动发布小红书图文/视频笔记!
上一篇用 Qwen3+MCPs实现AI自动发小红书的最佳实践 有超多小伙伴关注,同时也排队在蹲Windows版本的教程。
831 1
|
程序员 编译器 C++
【C++核心】C++内存分区模型分析
这篇文章详细解释了C++程序执行时内存的四个区域:代码区、全局区、栈区和堆区,以及如何在这些区域中分配和释放内存。
167 2
|
8月前
|
算法 关系型数据库 测试技术
WHQL微软驱动签名方案,让驱动程序在Windows系统流畅运行
WHQL认证(Windows徽标认证)是微软设立的严格测试标准,旨在确保驱动程序的兼容性、稳定性和互通性。本文介绍了三种WHQL微软驱动签名方案:单系统签名、多系统签名和硬件兼容性测试方案,分别满足不同开发商的需求。通过WHQL认证,不仅能消除Windows安装警告,提升用户体验,还能获得“Designed for Windows”徽标授权,入列全球Windows Catalog及HCL产品表,提升品牌权威性和采购优先权。此外,访问微软OCA可获取错误反馈,助力产品质量改进。选择合适的签名方案,让驱动在Windows系统中流畅运行!
|
11月前
|
人工智能 物联网 C语言
SVDQuant:MIT 推出的扩散模型后训练的量化技术,能够将模型的权重和激活值量化至4位,减少内存占用并加速推理过程
SVDQuant是由MIT研究团队推出的扩散模型后训练量化技术,通过将模型的权重和激活值量化至4位,显著减少了内存占用并加速了推理过程。该技术引入了高精度的低秩分支来吸收量化过程中的异常值,支持多种架构,并能无缝集成低秩适配器(LoRAs),为资源受限设备上的大型扩散模型部署提供了有效的解决方案。
591 5
SVDQuant:MIT 推出的扩散模型后训练的量化技术,能够将模型的权重和激活值量化至4位,减少内存占用并加速推理过程
|
监控 Ubuntu Linux
视频监控笔记(五):Ubuntu和windows时区同步问题-your clock is behind
这篇文章介绍了如何在Ubuntu和Windows系统中通过设置相同的时区并使用ntp服务来解决时间同步问题。
264 4
视频监控笔记(五):Ubuntu和windows时区同步问题-your clock is behind

热门文章

最新文章

下一篇
开通oss服务