全部博文(43)
分类: LINUX
2007-08-17 16:43:58
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结构只与物理页相关,目的在于描述物理内存本身,而不是描述包含在其中的数据;系统中的每个物理页都要分配一个这样的结构体。
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 |
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)
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()分配出来的内存块
1.
以字节为单位进行分配,在
2. void *vmalloc(unsigned long size) 分配的内存虚拟地址上连续,物理地址不连续
3. 一般情况下,只有硬件设备才需要物理地址连续的内存,因为硬件设备往往存在于MMU之外,根本不了解虚拟地址;但为了性能上的考虑,内核中一般使用kmalloc(),而只有在需要获得大块内存时才使用vmalloc(),例如当模块被动态加载到内核当中时,就把模块装载到由vmalloc()分配的内存上。
4.void vfree(void *addr),这个函数可以睡眠,因此不能从中断上下文调用。