linux free函数 源码,Linux-0.11内核源码分析系列:内存管理free_page()与free_page_tables()函数分析...

/*

*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)

*/

/*

*释放addr对应的物理地址

*free_page函数被free_page_tables()函数调用

*/

/*

* Free a page of memory at physical address 'addr'. Used by

* 'free_page_tables()'

*/

void free_page(unsigned long addr)

{

if(addr 

return;                         //LOW_MEM = 1M,0-640KB是内核驻留区域

}

if(addr >= HIGH_MEMORY) {           //如果是最大物理地址之外,die

panic("trying to free nonexistent page");

}

addr -= LOW_MEM;                    //获取主内存地址(以LOW_MEM处为起始0地址)

addr >>= 12;                        //获取主内存管理数组偏移索引

//mem_map是全局数组,用于管理主内存

if(mem_map[addr]--) {               //首先执行if(mem_map[addr])判断,接着mem_map[addr]--

return;                         //如果mem_map[addr] > 0,退出,表示物理页共享减一

}

mem_map[addr] = 0;                  //如果mem_map[addr] = 0,die

panic("trying to free free page");

}

/*

* 释放连续块,块必须4M对齐

* exit()函数调用,相对的函数是copy_page_tables()

*/

/*

* This function frees a continuos block of page tables, as needed

* by 'exit()'. As does copy_page_tables(), this handles only 4Mb blocks.

*/

int free_page_tables(unsigned long from, unsigned long size)

{

unsigned long *pg_table;

unsigned long *dir, nr;

if(from & 0x3fffff) {               //4M对齐检测

panic("free_page_tables called with wrong alignment");

}

if(!from) {                         //0地址是内核驻留地址,不允许释放

panic("Trying to free up swapper memory space");

}

size = (size + 0x3fffff)>>22;       //如果是4.1M,size取整为2。

dir  = (unsigned long *)((from>>20) & 0xffc); /* _pg_dir = 0 */

//dir是页目录项,取线性地址高10位,

//右移22位,因为每个目录项占4个字节,

//所以>>22之后<<2

//等于>>20

for(; size-->0 ; dir++) {

if(!(1 & *dir)) {               //如果页目录项未使用,跳过

continue;

}

pg_table = (unsigned long *)(0xfffff000 & *dir);        //取页表项

for(nr = 0; nr 

if(1 & *pg_table) {                                 //位0等于1表示物理页有效

free_page(0xfffff000 & *pg_table);              //释放物理页

}

*pg_table = 0;                                      //页表项内容清零

pg_table++;                                         //指向下一个页表

}

free_page(0xfffff000 & *dir);                           //释放页表项

*dir = 0;                                               //页目录项内容清零

}

invalidate();                                               //刷新高速缓存

return 0;                                                   //返回0表示操作成功

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值