Main Page | Modules | File List | File Members

pager.c

00001 /* ndk - [ pager.c ]
00002  *
00003  * Contains code to initialize the pager, and
00004  * to convert to and from linear and physical
00005  * address spaces.
00006  *
00007  * Please see:
00008  *   /src/memory.c
00009  *
00010  * (c)2002 dcipher / neuraldk
00011  *           www.neuraldk.org
00012  */
00013 #include "pager.h"
00014 
00015 pageDirectory *sysPageDir;
00016 
00017 void pagerInit(void) {
00018   pageTable *pTable;
00019   long i, addr;
00020 
00021   // find 4kb aligned address for page directory
00022   sysPageDir = (pageDirectory *)0x00090000;
00023 
00024   // find 4kb aligned address for 1 page table
00025   pTable = (pageTable *)0x00091000;
00026 
00027   // assign 1st page directory entry to page table
00028   sysPageDir->pageTable[0] = (long)pTable | PAGE_PRESENT
00029                                           | PAGE_READ_WRITE
00030                                           | PAGE_P3_ACCESS;
00031   // assign the last page table to the page directory!
00032   // This will aid in memory management (doc/memoryManagement.kwd)
00033   sysPageDir->pageTable[1023] = (long)sysPageDir | PAGE_PRESENT
00034                                                  | PAGE_READ_WRITE
00035                                                  | PAGE_P3_ACCESS;
00036 
00037   // clear the rest of the page directory
00038   for(i = 1; i < 1023; i++)
00039     sysPageDir->pageTable[i] = 0;
00040 
00041   // assign the page table simple linear address for the
00042   // first 4MBs of memory (later this should be changed to
00043   // map only used memory)
00044   //addr = 0;
00045   for(i = 0; i < 1024; i++) {
00046     pTable->pageAddr[i] = (i * 4096) | PAGE_PRESENT
00047                                      | PAGE_READ_WRITE
00048                                      | PAGE_P3_ACCESS;
00049     //consoleOut("pTable[%d] = 0x%8x\n", i, pTable->pageAddr[i]);
00050   }
00051 
00052   // load CR3 with the address of our page directory
00053   consoleOut("setting CR3: (0x%8x)\n", sysPageDir);
00054   setCR3( ((getCR3() & 0xfff) | (long)sysPageDir) );
00055   consoleOut("CR3: 0x%x\n", getCR3() );
00056 
00057   // and enable the paging bit in CR0
00058   consoleOut("setting CR0: (0x%8x)\n", getCR0() | CR0_PAGING_ENABLE);
00059   setCR0( (getCR0() | CR0_PAGING_ENABLE) );
00060   consoleOut("CR0: 0x%x\n", getCR0() );
00061 }
00062 
00063 long pagerTableExists(unsigned long tableNum) {
00064   long *pgDir = (long *)0xfffff000;
00065 
00066   return pgDir[(unsigned long)tableNum];
00067 }
00068 
00069 void pagerCreateTable(unsigned long tableNum) {
00070   long *pageDirectory = (long *)0xfffff000;
00071   long *pages = (long *)0xffc00000;
00072   long *pageTable;
00073   long  i;
00074 
00075   consoleOut("pager: creating new table #%d\n", tableNum);
00076   // get a page from the kernel
00077   pageTable = (long *)memoryAllocUnmappedPage();
00078   consoleOut("received page 0x%8x\n", pageTable);
00079 
00080   consoleOut("Adding to directory\n");
00081   // and assign it to our page directory (must do before we write to it)
00082   pageDirectory[tableNum] = (long)pageTable  | PAGE_PRESENT
00083                                              | PAGE_READ_WRITE
00084                                              | PAGE_P3_ACCESS;;
00085 
00086   // zero it out
00087   consoleOut("And clearing\n");
00088   for(i = 0; i < 1024; i++) pages[tableNum*1024+i] = 0;//pageTable[i] = 0;
00089 }
00090 
00091 long pagerMapPage(unsigned long physAddr) {
00092   long *pages = (long *)0xffc00000;
00093   long  allocPageOffset = (4*1024*1024)/4096;
00094   long  pointer;
00095 
00096   // simple way to find available slot
00097   pointer = allocPageOffset;
00098   while(pages[pointer++] != 0) ;
00099 
00100   // put physical page into linear space
00101   pages[pointer] = physAddr | PAGE_PRESENT
00102                             | PAGE_READ_WRITE
00103                             | PAGE_P3_ACCESS;
00104   return pointer*1024;
00105 }
00106 
00107 void *pagerLinToPhys(void *linearAddr) {
00108   long *pages = (long *)0xffc00000;
00109   long  linAddr = (long)linearAddr;
00110   long  physAddr;
00111   long  bottom4k;
00112   unsigned long pageTableNum;
00113   unsigned long pageIndex;
00114 
00115   // save the bottom 4k, and remove it from the linear address
00116   bottom4k = linAddr & 4095;
00117   linAddr -= bottom4k;
00118 
00119   // debugging info...
00120   consoleOut("page aligned linAddr: 0x%8x\n", linAddr);
00121 
00122   // calculate which page table to look into
00123   pageTableNum   = (unsigned long)linAddr / (4096*1024);
00124   //consoleOut("table %d, index %d\n", pageTableNum, pageTableIndex);
00125   // Check if this page table exists!
00126   if(!pagerTableExists(pageTableNum)) {
00127     consoleOut("Page table doesn't exist for linear address 0x%8x\n", linAddr);
00128     return 0;
00129   }
00130 
00131   // calculate the offset into the page tables, and get our physical address
00132   pageIndex = (unsigned long)linAddr >> 12;
00133   physAddr = pages[(unsigned long)pageIndex] & 0xfffff000;
00134 
00135   // add the bottom 4k
00136   physAddr += bottom4k;
00137 
00138   return (void *)physAddr;
00139 }

Generated on Sun Nov 21 18:26:11 2004 for ndk by doxygen 1.3.2