Chinaunix首页 | 论坛 | 博客
  • 博客访问: 279440
  • 博文数量: 43
  • 博客积分: 2515
  • 博客等级: 少校
  • 技术积分: 510
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-10 16:15
文章存档

2009年(2)

2008年(12)

2007年(29)

我的朋友

分类: LINUX

2007-08-17 16:43:58

--《Linux内核设计与实现》笔记


11 内存管理

11.1 页(page

1. 内核把物理页作为内存管理的基本单位;MMU以页为单位来管理页表。

2. 大多数32位体系结构支持4KB的页,64位体系结构支持8KB的页。

3. 内核用struct page结构来表示系统中的每个物理页,该结构位于

       struct page{

              page_flags_t          flags;      //dirty? locked in mem? See

              atomic_t                _count;          //referenced count

              atomic_t                _mapcout;     

              unsigned long         private;

              struct address_space     *mapping;

              pgoff_t                  index;

              struct list_head       lru;

              void                      *virtual;          //virtual address of the page

};

4. struct page结构只与物理页相关,目的在于描述物理内存本身,而不是描述包含在其中的数据;系统中的每个物理页都要分配一个这样的结构体。

11.2 zone

       1. 内核使用区对具有相似特性的页进行分组。

       2. Linux必须处理如下两种由于硬件存在的缺陷而引起的内存寻址问题

              1)一些硬件只能用某些特定的内存地址来执行DMA (详请查总线地址)

              2)一些体系结构其内存的物理寻址范围比虚拟寻址范围大得多,这样就有一些内存不能永久地映射到内核空间上。

       3. Linux使用了三种区:

              ZONE-DMA:这个区包含的页能用来执行DMA操作

              ZONE-NORMAL:这个区包含的都是能正常映射的页

              ZONE-HIGHMEM:这个去包含“高端内存”,其中的页并不能永久地映射到内核地址空间。

              这些区定义在

       4. 区的实际使用和分布是体系结构相关的,对X86,见下表,其余大部分体系结构的物理内存都属于ZONE-NORMAL.

             

描述

物理内存

ZONE-DMA

DMA使用的页

< 16MB

ZONE-NORMAL

正常可寻址的页

16-896MB

ZONE-HIGHMEM

动态映射的页

>896MB

11.3 获得页

       1. 定义在中:

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

              分配2(order)幂次方个连续的页,返回指向第一个页的指针

       void *page_address(struct page *page)

              返回给定物理页的逻辑地址

       unsigned long __get_free_pages(unsigned int gfp_mask, unsigned int order)

              alloc_pages作用相同,不过它直接返回所请求的第一个页的逻辑地址

       struct page *alloc_page(unsigned int gfp_mask);

       unsigned long __get_free_page(unsigned int gfp_mask);

              这两个函数只分配一个页。(相当于前面的函数参数order = 0

       unsigned long get _zeroed_page(unsigned int gfp_mask)

              只分配一页,内容为0,返回逻辑地址,常用于给用户空间分配内存(安全)

       相应的释放页的函数是

       void __free_pages(stuct page *page, unsigned int order)

       void free_pages(unsigned long addr, unsigned int order)

       void free_page(unsigned long addr)

11.4 kmalloc()

       1. 以字节为单位进行分配,在

       2. void *kmalloc(size_t size, int flags) 分配的内存物理地址上连续,虚拟地址上自然连续

       3. gfp_mask标志:什么时候使用哪种标志?如下:

              ----------------------------------------------------------------------------------------------

              情形                                                        相应标志

              ----------------------------------------------------------------------------------------------

              进程上下文,可以睡眠                     GFP_KERNEL

              进程上下文,不可以睡眠                  GFP_ATOMIC

              中断处理程序                                   GFP_ATOMIC

              软中断                                              GFP_ATOMIC

              Tasklet                                              GFP_ATOMIC

              用于DMA的内存,可以睡眠            GFP_DMA | GFP_KERNEL

              用于DMA的内存,不可以睡眠        GFP_DMA | GFP_ATOMIC

              ----------------------------------------------------------------------------------------------

       4. void kfree(const void *ptr)

              释放由kmalloc()分配出来的内存块

11.5 vmalloc()

       1. 以字节为单位进行分配,在

       2. void *vmalloc(unsigned long size) 分配的内存虚拟地址上连续,物理地址不连续

       3. 一般情况下,只有硬件设备才需要物理地址连续的内存,因为硬件设备往往存在于MMU之外,根本不了解虚拟地址;但为了性能上的考虑,内核中一般使用kmalloc(),而只有在需要获得大块内存时才使用vmalloc(),例如当模块被动态加载到内核当中时,就把模块装载到由vmalloc()分配的内存上。

       4.void vfree(void *addr),这个函数可以睡眠,因此不能从中断上下文调用。

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