linux中的get_page函数,Linux-0.11内核源码分析系列:内存管理get_empty_page()与put_page()函数分析...

Linux-0.11内核源码分析系列:内存管理get_empty_page()与put_page()函数分析

/*

*Author  : DavidLin

*Date    : 2014-11-22pm

*Email   : linpeng1577@163.com or linpeng1577@gmail.com

*world   : the city of SZ, in China

*Ver     : 000.000.001

*history :     editor      time            do

*          1)LinPeng       2014-11-22      created this file!

*          2)

*/

/*

* This function puts a page in memory at the wanted address.

* It returns the physical address of the page gotten, 0 if

* out of memory (either when trying to access page-table or

* page.)

*/

unsigned long put_page(unsigned long page,unsigned long address)

{

unsigned long tmp, *page_table;

/* NOTE !!! This uses the fact that _pg_dir=0 */

//页目录表从0地址开始是先决条件

if (page = HIGH_MEMORY)

printk("Trying to put page %p at %p\n",page,address);

//物理地址是主内存地址?否则发出警告

if (mem_map[(page-LOW_MEM)>>12] != 1)

printk("mem_map disagrees with %p at %p\n",page,address);

//检查主内存管理数组相应物理页索引值

//如果不是已经被申请次数为1

//的物理地址,发出警告

page_table = (unsigned long *) ((address>>20) & 0xffc);

//获取页目录项

//此处page_table代表页目录项

//页表是保存在页目录项中

//一个页目录项管理一个页表

//一个页表有1024个页表项

if ((*page_table)&1)     //检查页表有效位P是否在内存中

page_table = (unsigned long *) (0xfffff000 & *page_table);

//页目录项所保存的页表有效

//获取页表

//将页表值存入页目录项,所以31-21位不清零

//此处page_table代表页表

else {                                      //页目录项所保存的页表无效

if (!(tmp=get_free_page()))         //申请一块空闲物理页保存页表

return 0;                   //如果失败,返回0

*page_table = tmp|7;                //将页表地址保存到页目录项

page_table = (unsigned long *) tmp; //页表指针指向新申请的物理页

//此处page_table只用于

//页表项在页表中偏移地址计算

}                                           //一个页表管理1024个页表项

//一个页表项对应4K物理地址

page_table[(address>>12) & 0x3ff] = page | 7;

//(addree>>12) & 0x3ff可以获取物理页(页表项)在页表中的偏移地址

//因为与0x3ff相与,即011,1111,1111B可以清除address中保存的页目录项的值

//page | 7表示用户级,可读写,页最低位P有效

/* no need for invalidate */

//因为只是更新页表,没有实际物理内容更新,不需要更新换高速缓存

return page;   //返回物理页地址

}

//用于将线性地址address映射到实际物理页

void get_empty_page(unsigned long address)

{

unsigned long tmp;

if (!(tmp=get_free_page()) || !put_page(tmp,address)) {

//如果没有空闲物理页,die

//如果无法将申请的物理页挂载到线性地址中,die

free_page(tmp);/* 0 is ok - ignored */

//释放该物理页

oom();

//内存溢出,报错,死机

}

}

©著作权归作者所有:来自51CTO博客作者linpeng1577的原创作品,如需转载,请注明出处,否则将追究法律责任

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值