00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "pager.h"
00014
00015 pageDirectory *sysPageDir;
00016
00017 void pagerInit(void) {
00018 pageTable *pTable;
00019 long i, addr;
00020
00021
00022 sysPageDir = (pageDirectory *)0x00090000;
00023
00024
00025 pTable = (pageTable *)0x00091000;
00026
00027
00028 sysPageDir->pageTable[0] = (long)pTable | PAGE_PRESENT
00029 | PAGE_READ_WRITE
00030 | PAGE_P3_ACCESS;
00031
00032
00033 sysPageDir->pageTable[1023] = (long)sysPageDir | PAGE_PRESENT
00034 | PAGE_READ_WRITE
00035 | PAGE_P3_ACCESS;
00036
00037
00038 for(i = 1; i < 1023; i++)
00039 sysPageDir->pageTable[i] = 0;
00040
00041
00042
00043
00044
00045 for(i = 0; i < 1024; i++) {
00046 pTable->pageAddr[i] = (i * 4096) | PAGE_PRESENT
00047 | PAGE_READ_WRITE
00048 | PAGE_P3_ACCESS;
00049
00050 }
00051
00052
00053 consoleOut("setting CR3: (0x%8x)\n", sysPageDir);
00054 setCR3( ((getCR3() & 0xfff) | (long)sysPageDir) );
00055 consoleOut("CR3: 0x%x\n", getCR3() );
00056
00057
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
00077 pageTable = (long *)memoryAllocUnmappedPage();
00078 consoleOut("received page 0x%8x\n", pageTable);
00079
00080 consoleOut("Adding to directory\n");
00081
00082 pageDirectory[tableNum] = (long)pageTable | PAGE_PRESENT
00083 | PAGE_READ_WRITE
00084 | PAGE_P3_ACCESS;;
00085
00086
00087 consoleOut("And clearing\n");
00088 for(i = 0; i < 1024; i++) pages[tableNum*1024+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
00097 pointer = allocPageOffset;
00098 while(pages[pointer++] != 0) ;
00099
00100
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
00116 bottom4k = linAddr & 4095;
00117 linAddr -= bottom4k;
00118
00119
00120 consoleOut("page aligned linAddr: 0x%8x\n", linAddr);
00121
00122
00123 pageTableNum = (unsigned long)linAddr / (4096*1024);
00124
00125
00126 if(!pagerTableExists(pageTableNum)) {
00127 consoleOut("Page table doesn't exist for linear address 0x%8x\n", linAddr);
00128 return 0;
00129 }
00130
00131
00132 pageIndex = (unsigned long)linAddr >> 12;
00133 physAddr = pages[(unsigned long)pageIndex] & 0xfffff000;
00134
00135
00136 physAddr += bottom4k;
00137
00138 return (void *)physAddr;
00139 }