unsigned long put_page(unsigned long page,unsigned long address)
{
 unsigned long tmp, *page_table;
/* NOTE !!! This uses the fact that _pg_dir=0 */
 if (page <>= HIGH_MEMORY)
     printk("Trying to put page %p at %p\n",page,address);
 if (mem_map[(page-LOW_MEM)>>12] != 1) //this element should be marked as used before invoking this function
     printk("mem_map disagrees with %p at %p\n",page,address);
 page_table = (unsigned long *) ((address>>20) & 0xffc);
 /*address>>20: address>>22 locate the INDEX in directory table.the pointer of each entry equals to INDEX x 4, because each entry occupies 4 bytes. finally, simplify the expression to "address>>20", least but not last, the last 2 bits must be set to 0.*/ 
 if ((*page_table)&1)
     page_table = (unsigned long *) (0xfffff000 & *page_table);// *page_table is page table entry.
 else {
     if (!(tmp=get_free_page())) //get the physical address of a new page from main memory.
         return 0;
     *page_table = tmp|7;
     page_table = (unsigned long *) tmp;
 }
 page_table[(address>>12) & 0x3ff] = page | 7; /*save the pointer pointing to the begining of page to page table. 7 means:P=1. 
    R/W=1 read-and-write . U/S = 1 for application procedures and data. */ 
/* no need for invalidate */
 return page;
}
Subscribe to:
Post Comments (Atom)
 
 

No comments:
Post a Comment