【驱动学习】4.1-内存操作及内存属性
概述:
内存属性
在了解自旋锁之前需要先了解下内核的内存分配相关内容,相关的 API 可以参考 内存相关 一文。 这里补充下 ExAllocatePool
的参数1,也就是申请的页属性参数 POOL_TYPE
:
微软官方说明:_POOL_TYPE (wdm.h) - Windows drivers | Microsoft Learn
这里主要就常用的三个进行简单说明:
-
NonPagedPool
非分页池,这是不可分页的系统内存。 可以从任何 IRQL 访问非分页池,但它是一种稀缺资源,驱动程序应仅在必要时进行分配。该内存不会被交换到磁盘上,并且可以直接被内核访问,适用于需要快速访问的内存,例如驱动程序的代码、中断处理程序、系统调用等。 -
PagePool
分页池,它是可分页的系统内存。 只能在 IRQL < DISPATCH_LEVEL分配和访问分页池。 -
NonPagedPoolExecute
带有执行权限的非分页内存。如果是使用
NonPagedPoolExecute
申请的内存则需要留意,避免被利用。 从 Windows 8 开始,NonPagedPoolExecute
是NonPagedPool
值的备用名称。 此值指示分配的内存是非分页且可执行的,即在此内存中启用指令执行。 若要从早期版本的 Windows 移植驱动程序,通常应将驱动程序源代码中 NonPagedPool 名称的所有或大多数实例替换为NonPagedPoolNx
。 避免将NonPagedPool
名称的实例替换为NonPagedPoolExecute
,除非显式需要可执行内存。 有关详细信息,请参阅 No-Execute (NX) Nonpaged Pool。
内存操作
ExAllocatePool 内存申请
RtlZeroMemory 内存初始化
RtlCopyMemory 内存拷贝
ExFreePool 内存释放
Demo
1 |
|
输出
1 |
|
双向链表
双向链表的结构体如下所示:
1 |
|
需要注意的是:FLink 指向后一个节点,Blink 指向前一个结点。
多线程访问
需要注意的是,多线程访问同一数据结构时会存在线程同步问题,常见的使用方式就是使用锁机制进程同步。自旋锁是一种常用的锁机制,它是一种高 IRQL 锁,用于同步和独占地访问某个资源。
**自旋锁的基本思想:**当一个线程尝试获取锁时,如果锁已经被占用,则该线程不断循环(即自旋),直到锁被释放。自旋锁适用于锁的持有时间较短,且竞争者较少的情况下,可以避免进程上下文的切换和调度开销。在下一章将详细记录和说明。
Demo
1 |
|
驱动输出:
1 |
|