qiangqiang290
驱动牛犊
驱动牛犊
  • 注册日期2011-06-27
  • 最后登录2020-09-15
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望41点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
阅读:1780回复:3

物理地址如何释放内存?

楼主#
更多 发布于:2013-01-08 17:13
我现在面临的问题是这样的。
 在两个IOCTL中,一个是分配内存,我调用ExAllocatePoolWithTag分配了不分页的一段内存,虚拟地址为V1,然后MmGetPhysicalAddress得到对应的物理地址P1,将P1传给用户。另一个是释放内存,用户将P1传回来,但是这个时候我底层已经不保存V1值啦,如何能够获得虚拟地址V1,同时调用ExFreePool将其释放掉呢?
co63oc
驱动牛犊
驱动牛犊
  • 注册日期2011-09-01
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分35分
  • 威望291点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2013-01-10 10:40
保存到全局变量
ITSailor
驱动牛犊
驱动牛犊
  • 注册日期2010-12-08
  • 最后登录2014-05-05
  • 粉丝2
  • 关注0
  • 积分29分
  • 威望291点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分1分
板凳#
发布于:2013-01-11 10:29
了解一下虚拟地址和物理地址的关系,你就知道怎么做了,这里按x86处理器来说明。CPU有个页表,这个页表是操作系统构造的,格式是CPU定义的,页表的基地址在CR3寄存器里。当系统访问V1的时候,处理器把V1(就是地址值)拆成几个部分,用作页表的索引从页表里找出物理地址。也就是说,页表是从虚拟地址到物理地址的映射表,系统提供的MmGetPhysicalAddress就实现了这个查找流程。知道P1,不知道V1,那就有点麻烦,页表不是双向的,是单向的,如果反过来,那你就需要搜索页表了。

另外,ExFreePool不仅仅是释放了物理内存,而且还释放了虚拟内存空间,一个虚拟地址,同一时间,肯定只能对应一个物理地址(可以没有物理地址,但不会有多个物理地址),但一个物理地址,可能有多个虚拟地址对应,所以就算你从页表把P1的虚拟地址搜出来,如果不止一个,那你也无法判断你之前用ExAllocatePoolWithTag申请到的虚拟地址是哪个,所以为了安全起见,虚拟地址必须保存,物理地址可以需要的时候,用MmGetPhysicalAddress获得。
qiangqiang290
驱动牛犊
驱动牛犊
  • 注册日期2011-06-27
  • 最后登录2020-09-15
  • 粉丝0
  • 关注0
  • 积分6分
  • 威望41点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
  • 社区居民
地板#
发布于:2013-01-15 11:05
我现在面临的情况是,因为是两个IOCTL,所以应用可以多次调用分配内存,然后再最后在同一释放。
我现在的解决办法是在驱动里面维护了一个链表,将分配的内存虚拟地址V1和物理地址P1以及内存大小S1,都记录下来,然后在释放的时候,逐一查找,取得相应虚拟地址进行释放的。可以实现功能,但不知道是不是最佳。
游客

返回顶部