copy_page_tables


 1 int copy_mem(int nr,struct task_struct * p)
 2 {
 3     unsigned long old_data_base,new_data_base,data_limit;
 4     unsigned long old_code_base,new_code_base,code_limit;
 5 
 6     code_limit=get_limit(0x0f);
 7     data_limit=get_limit(0x17);
 8     old_code_base = get_base(current->ldt[1]);
 9     old_data_base = get_base(current->ldt[2]);
10     if (old_data_base != old_code_base)
11         panic("We don't support separate I&D");
12     if (data_limit < code_limit)
13         panic("Bad data_limit");
14     new_data_base = new_code_base = nr * 0x4000000;
15     p->start_code = new_code_base;
16     set_base(p->ldt[1],new_code_base);
17     set_base(p->ldt[2],new_data_base);
18     if (copy_page_tables(old_data_base,new_data_base,data_limit)) {
19         free_page_tables(new_data_base,data_limit);
20         return -ENOMEM;
21     }
22     return 0;
23 }

 

 


1
/* 2 * Well, here is one of the most complicated functions in mm. It 3 * copies a range of linerar addresses by copying only the pages. 4 * Let's hope this is bug-free, 'cause this one I don't want to debug :-) 5 * 6 * Note! We don't copy just any chunks of memory - addresses have to 7 * be divisible by 4Mb (one page-directory entry), as this makes the 8 * function easier. It's used only by fork anyway. 9 * 10 * NOTE 2!! When from==0 we are copying kernel space for the first 11 * fork(). Then we DONT want to copy a full page-directory entry, as 12 * that would lead to some serious memory waste - we just copy the 13 * first 160 pages - 640kB. Even that is more than we need, but it 14 * doesn't take any more memory - we don't copy-on-write in the low 15 * 1 Mb-range, so the pages can be shared with the kernel. Thus the 16 * special case for nr=xxxx. 17 */ 18 int copy_page_tables(unsigned long from,unsigned long to,long size) /* from和to都是线性地址,数据段基址*/ 19 { 20 unsigned long * from_page_table; 21 unsigned long * to_page_table; 22 unsigned long this_page; 23 unsigned long * from_dir, * to_dir; 24 unsigned long nr; 25 26 if ((from&0x3fffff) || (to&0x3fffff)) 27 panic("copy_page_tables called with wrong alignment"); 28 from_dir = (unsigned long *) ((from>>20) & 0xffc); /* _pg_dir = 0 */  /* from_dir对应的页目录项物理地址,这样计算过来的话 */ 29 to_dir = (unsigned long *) ((to>>20) & 0xffc); /* to_dir也对应的是物理地址 */ 30 size = ((unsigned) (size+0x3fffff)) >> 22; 31 for( ; size-->0 ; from_dir++,to_dir++) { 32 if (1 & *to_dir) 33 panic("copy_page_tables: already exist"); 34 if (!(1 & *from_dir)) 35 continue; 36 from_page_table = (unsigned long *) (0xfffff000 & *from_dir); 37 if (!(to_page_table = (unsigned long *) get_free_page())) /* get_free_page 返回的是物理地址,后来经过处理赋值给了 *to_dir ,所以页目录表里面存的是物理地址*/
38             return -1;    /* Out of memory, see freeing */
39         *to_dir = ((unsigned long) to_page_table) | 7;
40         nr = (from==0)?0xA0:1024;
41         for ( ; nr-- > 0 ; from_page_table++,to_page_table++) {  /* 拷贝页表中的项,是物理地址*/
42             this_page = *from_page_table;
43             if (!(1 & this_page))
44                 continue;
45             this_page &= ~2;
46             *to_page_table = this_page;
47             if (this_page > LOW_MEM) {
48                 *from_page_table = this_page;
49                 this_page -= LOW_MEM;
50                 this_page >>= 12;
51                 mem_map[this_page]++;
52             }
53         }
54     }
55     invalidate();
56     return 0;
57 }

 

/* from_dir对应的页目录项物理地址 */
posted @ 2013-05-18 21:46  立春了  Views(327)  Comments(0)    收藏  举报