Chinaunix首页 | 论坛 | 博客
  • 博客访问: 190841
  • 博文数量: 46
  • 博客积分: 1355
  • 博客等级: 中尉
  • 技术积分: 336
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-02 16:20
文章分类

全部博文(46)

文章存档

2017年(2)

2014年(12)

2012年(1)

2011年(5)

2010年(26)

我的朋友

分类: LINUX

2010-08-31 20:43:19

内存管理:

1、页:内核把物理页作为内存管理的基本单位,尽管处理器的最小可寻址的单位通常为字,但是MMU通常以页为单位进行处理。体系结构不同,支持的页的大小也不同,在大多的32位平台上支持4KB的页,而64位的平台一般会支持8KB的页。支持4KB并有1G物理内存的机器上,物理内存会被划分为262144个页。内核用struct page 结构表示系统中的每一个物理页,这个结构定义在中。

2、区:由于硬件的限制,内核并不能对所有的页一视同仁,有些页位于内存中特定的物理地址,不能将其用于一些特定的任务。所以内核把页划分为不同的区(zones)

Linux中使用了三种区:

ZONE_DMA——这个区包含的页能用来执行DAM操作, X86<16MB

ZONE_NORMAL——这个区包含的页都是能正常映射的页,x8616MB-896MB

ZONE_HIGHEM——“高端内存“,其中的页并不能永久地映射到内核地址空间。X86上高于896MB的内存属于高端内存了。

每一个区都用 struct zone 表示,在中定义了此结构。

3、获得与释放页

内核提供了对页申请的底层机制,相关的API如下:

alloc_page(gfp_mask)——只分配一页,返回指向页结构的指针

alloc_pages(gfp_mask,order)——分配2order个页,返回指向第一页页结构的指针

get_free_page(gfp_mask)——只分配一页,返回指向其逻辑地址的指针

__get_free_pages(gfp_mask,order)——分配2order个页,返回指向第一页逻辑地址的指针

get_zeroed_page(gfp_mask)——只分配一页,内容填充为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)

注意:释放时不能把别人申请的也给释放了,这样做会导致内核崩溃,所以实参要写对。

4kmalloc()与kfree(),在中定义。

Void *kmalloc(size_t size ,int flags)

Void kfree(const void *ptr)

在内核中我们分配空间一般都会用到这个两个函数,这两个函数相对于前面的页分配函数来说要高级一点啦,呵呵,而且,分配内存空间最好是在程序的最开头的时候。我写过的一个程序就是因为没有为设备结构体cdev分配存储空间而导致了Ooop的错误。纪念一下!!!!

5gfp_mask标志

在分配内存的时候我们要指定标志是怎么样的。也就是说kmalloc的第二个参数。

这个标志算起来有三类:行为修饰符、区修饰符及类型修饰符。这些标志在文件中声明。

1)行为修饰符:

表示内核应当如何分配所需的内存,主要有:

__GFP_WAIT    分配器可以休眠

__GFP_HIGH    分配器可以访问紧急事件缓冲池

__GFP_IO       分配器可以启动磁盘I/O

__GFP_FS       分配器可以启动文件系统I/O

2)区修饰符:

表示从哪里分配内存:可用于DMA的内存(__GFP_DMA)、常规内存以及高端内存(__GFP_HIGHMEM)

3)类型标志:

它是组合了行为修饰符和区修饰符,将各种可能用到的组合归纳为不同类型,简化了修饰符的使用。因此,最常使用的flags参数为GFP_KERNELGFP_ATOMIC。后者用在中断处理程序或其它运行于进程上下文之外的代码中,这时kmalloc方法不会休眠。

#include

#define GFP_KERNEL         (__GFP_WAIT | __GFP_IO | __GFP_FS)

#define GFP_ATOMIC         (__GFP_HIGH)




阅读(1749) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~