Friday, March 27, 2009

linux-0.11-mm-2

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;
}

No comments: