reactos:reactos操作系统实现(26)

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

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

  ExAllocatePool

  ExAllocatePoolWithQuota

  ExAllocatePoolWithTag

  ExAllocatePoolWithQuotaTag

  这些来请求内存时必须要指定请求内存类型:

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

  PagedPool         请求分配个可分页内存

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

  NonPagedPoolMustSucceed

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

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

  PagedPoolCacheAligned 这个标志分配使用数据缓存Cache线尺寸来在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 specied type and s a poer
#008   * to the allocated block. This routine is used for general purpose allocation
#009   * of memory
#010   * ARGUMENTS:
#011   *        PoolType
#012   *               Species 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   *               Species the number of s to allocate
#024   * RETURNS: The allocated block on success
#025   *          NULL on failure
#026   */
#027  {
#028     PVOID Block;
#029 
#030  # d(__GNUC__)
#031 
#032     Block = EiAllocatePool(PoolType,
#033                            NumberOfBytes,
#034                            TAG_NONE,
#035                            (PVOID)__builtin__address(0));
#036  #el d(_MSC_VER)
#037 
#038     Block = EiAllocatePool(PoolType,
#039                            NumberOfBytes,
#040                            TAG_NONE,
#041                            &ExAllocatePool);
#042  #
#043  #error Unknown compiler
#044  #end
#045 
#046     (Block);
#047  }




  上面这个就是实现内核里分配分页内存和非分页内存次再详细介绍如何样实现非分页内存



Tags:  reactos安装 reactos

延伸阅读

最新评论

发表评论