Linux的ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM及分配页释放页函数的简单介绍

Linux的ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM及分配页释放页函数的简单介绍

简单介绍一下页:

内核把物理页作为内存管理的基本单位。 尽管处理器的最小可寻址单位通常为字(甚至字节),但是,内存管理单元(MMU,管理内存并把虚拟地址转换为物理地址的硬件)通常以页为单位进行处理。正因为如此,MMU以页(page)大小为单位来管理系统中的页表(这也是页表名的来由)。从虚拟内存的角度来看,页就是最小单位。

内核用struct page结构表示系统中的每个物理页,该结构位于<linux/mm.h>中。

在这里插入图片描述
让我们看一下其中比较重要的域
flag域 :用来存放页的状态。这些状态包括页是不是脏的,是不是被锁定在内存中等等。flag的每一位单独表示一种状态,所以它至少可以同时表示出32种不同的状态。这些标志定义在<linux/page-flags.h>中。

_count域:存放页的引用计数——也就是这一页被引用了多少次。当计数值变为0时,就说明当前内核并没有引用这一页,于是,在新的分配中就可以使用它。

virtual域:是页的虚拟地址。通常情况下,它就是页在虚拟内存中的地址。有些内存(即所谓的高端内存)并不永久地映射到内核地址空间上。在这种情况下,这个域的值为NULL,需要的时候,必须动态地映射这些页。

Linux 区:

由于硬件的限制,内核并不能对所有的页一视同仁。有些页位于内存中特定的物理地址上,所以不能将其用于一些特定的任务。由于存在这种限制,所以内核把页划分为不同的区(zone)。内核使用区对具有相似特性的页进行分组。Linux必须处理如下两种由于硬件存在缺陷而引起的内存寻址问题:

  1. 一些硬件只能用某些特定的内存地址来执行DMA(直接内存访问)。
  2. 一些体系结构其内存的物理寻址范围比虚拟寻址范围大得多。这样,就有一些内存不能永久地映射到内核空间上。
    因为这些原因:所以Linux使用了三种区:(注意,区的划分没有任何物理意义﹔这只不过是内核为了管理页而采取的一种逻辑上的分组。)

ZONE_DMA——这个区包含的页能用来执行DMA操作。ZONE_NORMAL–—这个区包含的都是能正常映射的页。
ZONE_HIGHMEM一一这个区包含“高端内存”,其中的页并能不永久地映射到内核地址空间。

描述物理内存
ZONE_DMADMA使用的页小于16MB
ZONE_NORMAL正常可寻址的页16~896MB
ZONE_HIGHMEM动态映射的页大于 896MB

Linux把系统的页划分为区,形成不同的内存池,这样就可以根据用途进行分配了。例如,ZONE_DMA内存池让内核有能力为DMA分配所需的内存。如果需要这样的内存,那么,内核就可以从ZONE_DMA中按照请求的数目取出页。

尽管某些分配可能需要从特定的区中获取页,但是,某种用途的内存不一定要从对应的区获取。
尽管用于DMA的内存必须从ZONE_DMA中进行分配,但是一般用途的内存却既能从ZONE_DMA分配,也能从ZONE_NORMAL分配。当然,内核更希望般用途的内存从常规区分配,这样能节省ZONE_DMA中的页,保证满足DMA的使用需求。但是,如果可供分配的资源不够用了(如果内存已经变得很少了),那么,内核就会去占用其他可用区的内存。
每个区都用struct zone表示,定义在<linux/mmzone.h>中。
在这里插入图片描述
在这里插入图片描述

分配页系统调用

 struct page * alloc_pages(unsigned int gfp_mask,unsigned int order)

该函数分配2^order(即1<<order)个连续的物理页,并返回一个指针,该指针指向第一个页的page结构体;如果出错,就返回NULL。

unsigned long__get_free_pages(unsigned int gfp_mask,unsigned int order)

这个函数与alloc_pages()作用相同,不过它返回的是所请求的第一个页的逻辑地址。因为页是连续的,因此其他页也会紧随其后。

unsigned longget_zeroed_page(unsigned int gfp_mask)

这个函数与_get_free_page()工作方式相同,只不过把分配好的页都填充成了0

释放页系统调用

void _free_pages(struct page *page, unsigned int order)
void free_pages (unsigned long addr,unsigned int order)
void free page ( unsigned long addr)

使用时一定要注意,如果传递了错误的struct page或地址,用了错误的order值,这些都可能导致系统崩溃。因为这些函数都是运行在内核空间的系统调用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值