日期:2014-05-16 浏览次数:20851 次
“倒着看” 先看memory management,很明显,前面各种阻力,都是因为涉及内存管理。不先看这个,我估计前面看了也是白看
我估算着理论打基础砸了差不多一个星期的时间在memory management上面了。。。感觉很有收获,是时候用实践(code)印证理论了!
《modern operating system》讲内存管理那一章
http://blog.csdn.net/cinmyheart/article/details/24888847
free_page
http://blog.csdn.net/cinmyheart/article/details/24940731
get_free_page
http://blog.csdn.net/cinmyheart/article/details/24967455
上面两个函数单独拿出来笔记了,几乎这章memory.c 里后面的函数都会用到get_free_page,所以很重要
由于swap page部分和块设备有关系。。。偶还木有看,swap牵扯的比较多,这章暂且不做印证,待以后更新吧
int free_page_tables(unsigned long from,unsigned long size)//size是页表的数目
{
unsigned long *pg_table;
unsigned long * dir, nr;
if (from & 0x3fffff)//检测开始释放页的地址是否4M对齐
panic("free_page_tables called with wrong alignment");
if (!from)//如果 from为0 即空指针,则不允许释放。。。。很明显
panic("Trying to free up swapper memory space");
size = (size + 0x3fffff) >> 22;//对size进行取整的一个小技巧
dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */ //戳这个link http://blog.csdn.net/cinmyheart/article/details/24964363
// 下面这个循环是对页目录page directory的循环
for ( ; size-->0 ; dir++) {
if (!(1 & *dir))//检测该目录项是否已经被使用,对应<注释> 743页 页目录和页表项结构最低位P的检测
continue;//如果没有使用,就不用释放,直接跳过,进行下一个页目录的检索
pg_table = (unsigned long *) (0xfffff000 & *dir);//对dir进行解引用,得到页表项的首地址,并且强制转换成指针,赋值给pg_table,
//此时pg_table指向该表项的首地址
//下面这个循环是对页表 page table的循环
for (nr=0 ; nr<1024 ; nr++) {
if (*pg_table) { //对表项地址解引用,得到物理地址,如果得到的物理地址不是RAM首地址0x00,那么则可以进行下一步,
//否则pg_table++移动指针,进行下一个页的释放检测
if (1 & *pg_table)//检测该页表项指向的物理内存页是否已经被使用,如果是,释放,否则swap 释放交换设备中的对应页
free_page(0xfffff000 & *pg_table);
else
swap_free(*pg_table >> 1);
*pg_table = 0;
}
pg_table++;
}
free_page(0xfffff000 & *dir);//释放掉页表本身占用的内存
*dir = 0;//所有位置0,移除该页目录项!换而言之,*dir 不指向任何页表
}
invalidate();//刷新BTL
return 0;
}
理论和实践得到了很好的印证
Linus说下面的copy_page_tables,这是他认为内存管理里面最难的代码,其实。。。纠结完上面的两个函数之后,暂且抛开swap不说(但是心里要明白,理论上要清楚是个什么过程),这个最难的代码也会思路很清晰的
这段代码的主要思想就是把页目录项里面从某一个page(from)起始到某一个page(to)结束的之间所有的memory page释放掉
抛开《注释》 自己写注释写理解,这样我想,对于代码的理解会更好
copy_page_tables