2007-4-13 20:46:00 linux0.11之copy_page_tables()函数见解

好常时间没更新了,今天看了一个函数,是linux0.11的内存管理的一个重要的函数,本来该写在笔记上的,但一时兴起,就写到博客上了。
00150 int copy_page_tables (unsigned long from,unsigned long to,long size)
00151 {
00152     unsigned long * from_page_table;
00153     unsigned long * to_page_table;
00154     unsigned long this_page;
00155     unsigned long * from_dir, * to_dir;
00156     unsigned long nr;
00157 //下面是判断from 和to 是否在4M的边界处
00158     if ((from&0x3fffff) || (to&0x3fffff))
00159        
panic ("copy_page_tables called with wrong alignment");
    //赋給from_dir 页目录表的源目录起始号 (from>>20)&oxfffc =(from>>22)<<2
00160     from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */
               //赋給to_dir 页目录表的目的目录起始号 (to>>20)&oxfffc =(to>>22)<<2
00161     to_dir = (unsigned long *) ((to>>20) & 0xffc);
              //赋給size要复制的目录表项的个数
00162     size = ((unsigned) (size+0x3fffff)) >> 22;
    //下面两个for循环是复制的开始。外层循环控制目录表项的移动,内层  
               //循环控制二级页表项移动,复制的内容是复制目录项和页表项
00163     for( ; size-->0 ; from_dir++,to_dir++) {
00164         if (1 & *to_dir)
00165            
panic ("copy_page_tables: already exist");
00166         if (!(1 & *from_dir))
00167             continue;
    //得到目录项指向的二级页表的起始地址
00168         from_page_table = (unsigned long *) (0xfffff000 & *from_dir);
    //利用get _free_page()申请一个内存页
00169         if (!(to_page_table = (unsigned long *)
get_free_page ()))
00170             return -1;  /* Out of memory, see freeing */
     //设置目录表项的标志位赋給to_dir
00171         *to_dir = ((unsigned long) to_page_table) | 7;
                   //判断from是否是从0 开始,若是,则只需复制0xA0个页面
00172         nr = (from==0)?0xA0:1024;
     //复制每一个页表项
00173         for ( ; nr-- > 0 ; from_page_table++,to_page_table++) {
00174             this_page = *from_page_table;
00175             if (!(1 & this_page))
00176                 continue;
00177             this_page &= ~2;
00178             *to_page_table = this_page;
     //在fork()函数中会用到,就是把每个页都设置成只读,父进程和
     //子进程共享页面,当进程想写页面时,产生缺页中断,利用写时复
                    //制技术   
00179             if (this_page >
LOW_MEM ) {
00180                 *from_page_table = this_page;
00181                 this_page -=
LOW_MEM ;
00182                 this_page >>= 12;
00183                
mem_map [this_page]++;  
00184             }
00185         }
00186     }
00187    
invalidate ();
00188     return 0;
00189 }
这段代码复制了页表,使得一个物理内存页被两个页表项所指.
本来想做个flash的,可是无奈技术不够啊 

你可能感兴趣的:(linux)