linux0.11内存管理——try_to_share()
0
00293 { 00294 unsigned long from; 00295 unsigned long to; 00296 unsigned long from_page; 00297 unsigned long to_page; 00298 unsigned long phys_addr; 00299 00300 from_page = to_page = ((address>>20) & 0xffc); 00301 from_page += ((p->start_code>>20) & 0xffc); //找到p进程address所对应的页目录项 00302 to_page += ((current->start_code>>20) & 0xffc); //找到当前进程address所对应的页目录项 00303 /* is there a page-directory at from? */ 00304 from = *(unsigned long *) from_page; 00305 if (!(from & 1)) 00306 return 0; 00307 from &= 0xfffff000; 00308 from_page = from + ((address>>10) & 0xffc); 00309 phys_addr = *(unsigned long *) from_page; 00310 /* is the page clean and present? */ 00311 if ((phys_addr & 0x41) != 0x01) 00312 return 0; 00313 phys_addr &= 0xfffff000; 00314 if (phys_addr >= HIGH_MEMORY || phys_addr < LOW_MEM) 00315 return 0; 00316 to = *(unsigned long *) to_page; 00317 if (!(to & 1)) { 00318 if ((to = get_free_page())) 00319 *(unsigned long *) to_page = to | 7; 00320 else 00321 oom(); 00322 } 00323 to &= 0xfffff000; 00324 to_page = to + ((address>>10) & 0xffc); 00325 if (1 & *(unsigned long *) to_page) 00326 panic("try_to_share: to_page already exists"); 00327 /* share them: write-protect */ 00328 *(unsigned long *) from_page &= ~2; 00329 *(unsigned long *) to_page = *(unsigned long *) from_page; 00330 invalidate(); 00331 phys_addr -= LOW_MEM; 00332 phys_addr >>= 12; 00333 mem_map[phys_addr]++; 00334 return 1; 00335 } |