Я пытаюсь преобразовать адрес виртуальной памяти в физический, но не могу заставить его работать. В настоящее время я выполняю операционную систему в качестве задания, и теперь мне нужно реализовать функцию printf для пользовательского режима, поэтому, когда вы вызываете системный вызов записи, система должна печатать содержимое массива в пользовательском режиме на последовательный порт (на данный момент ), и для этого мне нужно преобразовать адрес из виртуального в физический.
Вот мой код из обработчика системного вызова:
Pcb* pcb = getCR3(); // contains the page directory for usermode
setCR3(kernelPageDir); // set the CR3 register to the kernel page directory
uint32_t tableNum = (vAddr >> 22) & 0x3ffUL; // get the upper 10 bits
uint32_t pageIndex = (vAddr >> 12) & 0x3ffUL // get the middle 10 bits
uint32_t offset = vAddr & 0xfffUL; // get the 12 lower bits
uint32_t* topTable = pcb->pageDirectory[tableNum]; // Access the top level table
uint32_t lowTable = topTable[pageIndex]; // Entry to the 2nd table
uint32_t* addr = lowTable + offset; // Should be the physical address
serialPrintf("Structure: tableNum=%08x pageIndex=%08x offset=%08x\n", tableNum, pageIndex, offset);
serialPrintf("Address: topTable=%08x lowTable=%08x addr=%08x\n",topTable, lowTable, addr);
serialPrintf("Char:%c", (char*)addr[0]);
Когда я запускаю код, он дает мне ошибку страницы при попытке получить доступ к его значению:
Structure: tableNum=00000020 pageIndex=00000048 offset=00000378
Address: topTable=00000000 lowTable=0015d000 addr=0015d378
Page fault! errcode=00000000 addr=0015d378
Вот часть из книги, которая объясняет структуру страниц:
*((char *)vAddr)
(хотя на практике код ядра получает доступ к виртуальным адресам пользователей только через специальные функции, которые обеспечивают соблюдение ограничений адресации пользовательского режима, а ошибки страниц правильно обрабатываются и поэтому далее). - person Gil Hamilton   schedule 25.09.2018