reactos操作系统实现(26)

 在ReactOS内存管理里,有一块内存区是非分页内存,也就是这块内存始终保持在系统物理内存里面,不会换到磁盘上。那为什么需要这样做呢?全部使用分页内存不是更简单,更方便吗?肯定不行的,因为IA86的内存管理就决定它不能这样做了,当CPU缺页中断时,就需要操作系统把分页内存换到磁盘上,再把加载数据从磁盘读取回来。如果操作系统使用的内存都是分页内存,那么操作系统就没有办法运行了,因为所需要运行的代码都在磁盘上。在内核的驱动程序,也是有这样的要求。驱动程序在执行时可能需要动态分配内存空间,这时你要决定需要的是可分页还是不可分页的内存。如果你的驱动在运行中访问内存的时候能够经受页错误,那么尽量使用可分页内存。

注意:大多数低层磁盘和网络驱动通常不能使用可分页内存,因为他们的代码常常在较高的IRQL等级执行而不允许页错误。但是,文件系统(通常比磁盘驱动占用更大,更多资源)有时候可从可分页池中分配一些内存。非分页内存在整个系统中是一个有限的资源,其数量依赖于系统使用的类型,和系统可用的物理内存。NT提供下面的例程给内核驱动来分配内存:

ExAllocatePool

ExAllocatePoolWithQuota

ExAllocatePoolWithTag

ExAllocatePoolWithQuotaTag

调用这些函数来请求内存时,必须要指定请求的内存的类型:

NonPagedPool    请求分配一个不可分页的内存

PagedPool         请求分配一个可分页的内存

如果你在分配的内存里有任何同步结构的话,决不要分配分页内存。当你的应用访问内存时候可以处理页错误的时候,应该指定这个类型。

NonPagedPoolMustSucceed

在其它方式都失败时,而你又必须立即得到内存的时候可以使用这个标志类型。注意这种类型的内存是极度缺乏的资源,可能不足16K。注意,只有在其它途径都失败的时候才使用,如果分配失败,将会导致系统的bugcheck,错误代码是 MUST_SUCCEED_POOL_EMPTY

NonPagedPoolCacheAligned 这个标志分配使用数据缓存线的尺寸来在CPU特定的边界对齐的非分页内存。注意这个操作默认是在Intel平台上的 NonPagedPool 分配类型。

 

PagedPoolCacheAligned 这个标志分配使用数据缓存线的尺寸来在CPU特定的边界对齐的分页内存。

 

NonPagedPoolCacheAlignedMustSucceed

参考NonPagedPoolMustSucceed NonPagedPoolCacheAligned

内存池分配器初始化了一些列表,每个列表包含一种固定大小的块。当你使用上面的函数请求内存时,例程试图分配一个和你请求数量相近的或更大一点的固定大小的块。但是,如果你要求的数量超过一页时,或者超过列表中最大块的大小时,又或者

在预先分配的列表中没有可用的块的时候,VMM就会从任何适当类型的系统可用的内存中分配你请求的数量内存给你。当预先分配的列表空了的时候,VMM会分配至少一页的内存,切分,然后把剩下的数据放进适当的块列表中。但是,当你请求的非分页内存的数量超过PAGE_SIZE时候,内存池分配例程不会切分未使用的部分,这会浪费宝贵的非分页内存。也可以使用 MmAllocateNonCachedMemory MmAllocateContiguousMemory来分配非分页或物理连续内存。它们通常不使用在文件系统或者过滤驱动中,而是用于执行池例程或者其它结构。内核驱动如果重复的分配和释放小块的内存(小于一个PAGE_SIZE, 可能导致系统的可用物理内存碎片化。这会给系统带来各种问题,包括降低系统的性能等。有一个方法可以避免系统碎片化,就是预先分配一块合理大小的内存,然后自已管理,在这个预先分配的块中分配和释放小块的内存,但这种方法有可能会浪费核心内存。

 

ReactOS的文件/ntoskrnl/mm/pool.c里看到下面的代码:

#001  /*

#002   * @implemented

#003   */

#004  PVOID NTAPI

#005  ExAllocatePool (POOL_TYPE PoolType, ULONG NumberOfBytes)

#006  /*

#007   * FUNCTION: Allocates pool memory of a specified type and returns a pointer

#008   * to the allocated block. This routine is used for general purpose allocation

#009   * of memory

#010   * ARGUMENTS:

#011   *        PoolType

#012   *               Specifies the type of memory to allocate which can be one

#013   *               of the following:

#014   *

#015   *               NonPagedPool

#016   *               NonPagedPoolMustSucceed

#017   *               NonPagedPoolCacheAligned

#018   *               NonPagedPoolCacheAlignedMustS

#019   *               PagedPool

#020   *               PagedPoolCacheAligned

#021   *

#022   *        NumberOfBytes

#023   *               Specifies the number of bytes to allocate

#024   * RETURNS: The allocated block on success

#025   *          NULL on failure

#026   */

#027  {

#028     PVOID Block;

#029 

#030  #if defined(__GNUC__)

#031 

#032     Block = EiAllocatePool(PoolType,

#033                            NumberOfBytes,

#034                            TAG_NONE,

#035                            (PVOID)__builtin_return_address(0));

#036  #elif defined(_MSC_VER)

#037 

#038     Block = EiAllocatePool(PoolType,

#039                            NumberOfBytes,

#040                            TAG_NONE,

#041                            &ExAllocatePool);

#042  #else

#043  #error Unknown compiler

#044  #endif

#045 

#046     return(Block);

#047  }

 

上面这个函数就是实现内核里分配分页内存和非分页内存。下一次再详细介绍怎么样实现非分页内存。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
上册共分为10部分,这是第1部分 Windows内核情景分析(上册).part01.rar 基本信息 作者: 毛德操 出版社:电子工业出版社 ISBN:9787121081149 上架时间:2009-5-25 出版日期:2009 年5月 开本:16开 页码:1465 版次:1-1 所属分类:计算机 > 操作系统 > Windows 内容简介回到顶部↑ 本书通过分析ReactOS的源代码介绍了Windows内核各个方面的结构、功能、算法与具体实现。全书从“内存管理”、“进程”、“进程间通信”、“设备驱动”等多个方面进行分析介绍,所有的分析都有ReactOS的源代码(以及部分由微软公开的源代码)作为依据,使读者能深入理解Windows内核的方方面面,也可以使读者的软件开发能力和水平得到提高。. 本书可供大学有关专业的高年级学生和研究生用做教学参考,也可供广大的软件工程师,特别是从事系统软件研发的工程师用于工作参考或用做进修教材。... 目录回到顶部↑ 上 册. 第1章 概述 1 1.1 Windows操作系统发展简史 1 1.2 用户空间和系统空间 3 1.3 Windows内核 4 1.4 开源项目ReactOS及其代码 9 1.5 Windows内核函数的命名 10 第2章 系统调用 12 2.1 内核与系统调用 12 2.2 系统调用的内核入口KiSystemService() 22 2.3 系统调用的函数跳转 29 2.4 系统调用的返回 32 2.5 快速系统调用 35 2.6 从内核中发起系统调用 42 第3章 内存管理 44 3.1 内存区间的动态分配 47 3.1.1 内核对用户空间的管理 48 3.1.2 内核对于物理页面的管理 60 3.1.3 虚存页面的映射 67 3.1.4 Hyperspace的临时映射 78 .3.1.5 系统空间的映射 86 3.1.6 系统调用NtAllocateVirtualMemory() 90 3.2 页面异常 97 3.3 页面的换出 107 3.4 共享映射区(Section) 115 3.5 系统空间的缓冲区管理 133 第4章 对象管理 136 4.1 对象与对象目录 136 4.2 对象类型 148 4.3 句柄和句柄表 162 4.4 对象的创建 169 4.5 几个常用的内核函数 179 4.5.1 ObReferenceObjectByHandle() 179 4.5.2 ObReferenceObjectByPointer() 187 4.5.3 ObpLookupEntryDirectory() 188 4.5.4 ObpLookupObjectName() 192 4.5.5 ObOpenObjectByName() 209 4.5.6 ObReferenceObjectByName() 213 4.5.7 ObDereferenceObject() 214 4.6 对象的访问控制 218 4.7 句柄的遗传和继承 218 4.8 系统调用NtDuplicateObject() 223 4.9 系统调用NtClose() 233 第5章 进程与线程 241 5.1 概述 241 5.2 Windows进程的用户空间 253 5.3 系统调用NtCreateProcess() 273 5.4 系统调用NtCreateThread() 284 5.5 Windows的可执行程序映像 300 5.6 Windows的进程创建和映像装入 305 5.7 Windows DLL的装入和连接 329 5.8 Windows的APC机制 358 5.9 Windows线程的调度和切换 381 5.9.1 x86系统结构与线程切换 382 5.9.2 几个重要的数据结构 385 5.9.3 线程的切换 388 5.9.4 线程的调度 395 5.10 线程和进程的优先级 409 5.11 线程本地存储TLS 421 5.12 进程挂靠 434 5.13 Windows的跨进程操作 442 5.14 Windows线程间的相互作用 450 第6章 进程间通信 467 6.1 概述 467 6.2 共享内存区(Section).. 469 6.3 线程的等待/唤醒机制 470 6.4 信号量(Semaphore) 499 6.5 互斥门(Mutant) 505 6.6 事件(Event) 512 6.7 命名管道(Named Pipe)和信插(Mailslot) 516 6.8 本地过程调用(LPC) 521 6.9 视窗报文

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

caimouse

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值