- 论坛徽章:
- 0
|
在内核中可以以页面为单位进行内存的分配,相关的接口定义在include/linux/gfp.h中。
最核心的分配页面函数为:
struct page * alloc_pages(unsigned
int gfp_mask, unsigned int order)
在NUMA开启的情况下,是一个static inline的函数,而在其他情况下,是一个宏。这个函数分配2的order次方个连续的物理页面,返回指向第一个页的page结构体。
如果只想分配一个页面,则可以使用alloc_page(),其实是这样一个宏:
#define alloc_page(gfp_mask)
alloc_pages(gfp_mask, 0)
得到struct page后,怎么知道页的逻辑地址呢:
void
* page_address(struct page * page)
返回一个指向给定物理页当前所在的逻辑地址。
当只需要逻辑地址,而无须struct page时,可以使用下列函数进行分配:
unsigned
long __get_free_pages(unsigned int gfp_mask, unsigned int order)
申请连续的2的order次方个连续页面,返回第一个页的逻辑地址
unsigned
long __get_free_page(unsigned int gfp_mask)
申请一个页面并返回其逻辑地址。
而想释放一个页面的时候,与分配对应如下:
void
_free_pages(struct page * page, unsigned int order)
释放page结构体指向的连续2的order次方个页面。
void
free_pages(unsigned long addr, unsigned int order)
释放从地址addr开始的,连续2的order次方个页面。
void
free_page(unsigned long addr)
释放地址addr的一个页。
如果想得到初始化为0的页面,可以使用:
unsigned
long get_zeroed_page(unsigned int gfp_mask)
第一次用这样的函数,比较晕…下面记下一个关于如何映射到结构体数组来操作样例吧(主要是为了配合原有的带struct list_head的数据结构来使用)。
struct abc
{
struct list_head my_list;
int a;
}
// Allocate a zeroed page.
struct abc * aaa = (struct abc *) get_zeroed_page(GFP_KERNEL);
//Free that page.
free_page((unsigned long)(aaa));
后记:这次算是第一次修改内核,读代码和改代码的差异随着一次次的panic不慌不忙地展现出来,我似乎是第一次认识到了处在kernel空间的危险性...
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u/12325/showart_490957.html |
|