/* *author : Davidlin *date : 2014-11-22pm *email : [email protected] or [email protected] *world : The city of SZ, in China *ver : 000.000.001 *history: editor time do * 1) Linpeng 2014-11-22 created this file! * 2)
/* * Well, here are one of the most complicated functions in mm. It * Copies a range of Linerar addresses by copying only the pages. * Let's hope this was bug-free, ' cause this one I don ' t want to debug:-) * * note! We don ' t copy just any chunks of memory-addresses has to * is divisible by 4Mb (one page-directory entry) s the * function easier. It ' s used only by fork anyway. * * NOTE 2!! When from==0 we is copying kernel space for the first * fork (). Then we DONT want to copy a full page-directory entry, as * that would leads to some serious memory waste-we just copy th E * First pages-640kb. Even that's more than we need, but it's * doesn ' t take any more memory-we don ' t copy-on-write in the low * 1 mb-range, so The pages can be shared with the kernel. Thus the * special case for nr=xxxx. *//* Linus that the following copy_page_tables () function is one of the hardest parts of memory management * The Copy_page_tables () function is only called by the fork function * Copy just copy a page table, page table is to manage 4M address, so follow the 4M alignment * Does not copy the physical page content, when a write-time copy will copy the page table managed physical page content * for processes 0 and 1, only copy the first 160 pages 640Kb, forRate Considerations * 0-1m as the kernel Resident address area, prohibit write overwrite * parameter from,to is 0-4g linear address, size is the byte unit */int copy_page_tables (unsigned long from,unsigned long to, Long size) {unsigned long * from_page_table; Used to manage Source page table unsigned long * to_page_table; For Management purposes page table unsigned long this_page; Used to save page table unsigned long * from_dir, * TO_DIR; Used to manage source page catalog entries, destination page directory entries unsigned long nr; The number of page table entries to save if ((FROM&0X3FFFFF) | | (TO&0X3FFFFF)) 4M alignment detection, otherwise diepanic ("Copy_page_tables called with wrong alignment"); From_dir = (unsigned long *) ((FROM>>20) & 0XFFC); /* _pg_dir = 0 *//////Source page directory Entry To_dir = (unsigned long *) ((to>>2 0) & 0XFFC); Destination Page directory Entry size = ((unsigned) (SIZE+0X3FFFFF)) >> 22; The number of page table entries is the number of bytes divided by 4Mfor (; size-->0; from_dir++,to_dir++) {if (1 & *to_dir)//If the destination page The recording has been used, diepanic ("copy_page_tables:already exist"); 1 & *from_dir))//If the source page directory entry is unused, skip, do not copy ContiNue;from_page_table = (unsigned long *) (0xfffff000 & *from_dir);//source page Table if ( To_page_table = (unsigned long *) get_free_page ())) //Fetch FREE physical page for To_page_ Table Assignment return-1; /* out of memory, see Freeing */ //If there is no free physical page,die *to_dir = ((unsigned long) to_page_table) | 7; The page table is stored in the corresponding page directory entry, 7 is read write //Think about the common chmod 777 anyfile  NR = (from==0)?0xa0:1024; //If it is 0 address, copy only 160 pages, otherwise copy 1024 pages //Page Catalog Table management 1024 page Catalog Items // One page Table management 1024 page table Items //One page table Item management has 4 K physical Address for (; nr--> 0; from_page_table++,to_page_table++) { this_p Age = *from_page_table; //Fetching source page table entries from the source page table if (! ( 1 & this_page)) //If the source page table entry is not being used, skip continue; this_page &= ~2; //Destination page table entry read-write bit set to read-only *to_page_table = this_page; //Save the Source page table entry in the destination page table entry if (This_page > Low_mem) { //If the main memory area *from_page_table = This_ page; //Source page table entries are also set to read-only This_page-= low_mem; //Take offset address of relative main memory this_page >>= 12; //Fetch Master Memory Management array index mem_map[this_page]++; //physical page citations plus 1 } } } invalidate (); //Refresh cache return 0; //Return 0 = success}
Linux-0.11 Kernel Source Analysis series: Memory management Copy_page_tables () function analysis