linux内核函数解析(一)



1:int free_page_tables(unsigned long from,unsigned long size)
         这个函数的作用是用于释放一个以页目录项为单位的连续内存块,当然了这指的是虚拟地址,但是linux32位的虚拟地址又被分成三个部分,从第31~22位用于确定页目录表中的页目录项(可以从CR3寄存器获取页目录表的基地址,然后将此相对偏移地址加上基地址就可以得到页目录项的值,而页目录项的值就是用于确定某个页表的基地址),从第21~12位用于确定某个页表项在已知的页表基地址中的偏移值,第11~0位用于确定页内偏移值。因此可以从一个虚拟的地址加上对应的页表值(页目录表,页表)确定出物理地址。
        这个函数的作用就是释放一个页目录项所对应的内存物理块,因为一个页目录项所对应的是一个页表,一个页表是1024*4B,所以一个页表有1024个页(一个页表项有4B,用于记录一个页面的偏移值),所以总共的内存大小为4M。
  
          参数:unsigned long from 表示这个线性空间的起始地址,unsigned long size 表示要释放的范围大小。
          接下来是源码解析:
    
if(from&0x3fffff)
      panic("free_page_tables called with wrong alignment");
if(!from)
      panic("trying to free up swapper memory space");


         函数一开始要先对起始地址进行判断,因为要释放的地址是以4M为单位,所以线性地址必须要在4M的边界上,如果线性地址不在4M起始边界上,那么其低22位必不为0,则将其与0x3fffff相与之后必不为0,则可判断出错,还有一种错误就是要保证所释放的地址不能在内核空间上,因为我们之前已经确定了地址是以4M对其的,所以如果释放的是内核空间,则地址必须为0(至少在linux0.11版本中是这样的)。从而通过这连个if语句可以保证线性地址的正确。
          接下来是要计算出要释放的页目录项的数量
      size=(size+0x3fffff)>>22
         这里我也不懂为什么linus要这样写,我在想如果直接用传入的参数size进行下面的计算不行么?因为这个的结果不是和直接传入的size值一样么?(额,可能不一样,不过我现在理解是一样的,你看size加上0x3fffff后所得到的值再右移22位,就是size的么)希望哪位大牛能帮我解答下。。
          接下来是按照size的大小释放页表


      dir=(unsigned long *)((from>>20)&0xffc);
          这一行表示要确定起始的页目录项,因为from>>22就可以获得该线性地址下的页目录项的值(前提是页目录表的基地址是0,在linux0.11版本中是这样的),但是这样获得的只是页目录项的末地址,我们还要回退4b才能获得首地址,所以是from>>20.就可以知道起始线性地址所对应的项目项的值了,然后是将其与0xffc相与,这样做的好处是为了确保目录指针能在有效的范围内(我在想如果不要这个预防措施可能会发生什么错误呢。。)
        
for(;size-->0;dir++){
     if(!(1&*dir))
      continue;
     pg_table=(unsigned long *)(0xfffff000&*dir);//获取页目录项
     for(nr=0;nr<1024;nr++){//释放对应的页表
          if(1&*pg_table)
                  free_page(0xfffff000&*pg_table);//如果页表可用,释放
          *pg_table=0;//将当前页表项值置为空
            pg_table++;//移动指针,获取下一个页表项值
 }
     free_page(0xfffff000&*dir);
     *dir=0;
}
   这一段代码是这个函数的核心部分,外层的for循环是释放size个页目录项所对应的页表,dir是页目录项的起始地址,函数先判断页目录项是否可用,即P位是否为1。然后再获取该页目录项所对应的页表的基地址,再在第二层循环中释放该页表所对应的1024个页表项。在第二层循环中也要判断该页表项是否可用,如果P位为1,则调用free_page(unsigned long addr)函数释放一个页表的内存。最后还要将该页表项置为空,修改页表项指针。
  当释放完一个页表的内存后,将该页表也释放,并将其值置为空。      
   这个函数解析就写到这,主要是给自己做个笔记,当然也希望大家能互相讨论,看下我写的东西有哪些不足,共同进步.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值