Added tlb & bitmap commands

This commit is contained in:
Alex 2022-12-05 00:47:15 +02:00
parent 58dfc9c407
commit f34278891b
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
3 changed files with 142 additions and 20 deletions

View File

@ -2,6 +2,7 @@
#include "chfcts.hpp"
#include <display.hpp>
#include <bitmap.hpp>
#include <convert.h>
#include <printf.h>
#include <lock.hpp>
@ -20,6 +21,22 @@
NewLock(UserInputLock);
#define TRACE_PAGE_TABLE(x, itr, depth) \
EHPrint("\e888888#%s\eAABBCC%03d\e4500F5: P:%s RW:%s US:%s PWT:%s PCB:%s A:%s D:%s PS:%s G:%s Address:\e888888%#lx\n", \
depth, \
itr, \
x.Value.Present ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \
x.Value.ReadWrite ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \
x.Value.UserSupervisor ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \
x.Value.WriteThrough ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \
x.Value.CacheDisable ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \
x.Value.Accessed ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \
x.Value.Dirty ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \
x.Value.PageSize ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \
x.Value.Global ? "\e00AA00Yes\e4500F5" : "\eAA0000No \e4500F5", \
x.GetAddress() << 12); \
Display->SetBuffer(SBIdx);
namespace CrashHandler
{
void *EHIntFrames[INT_FRAMES_MAX];
@ -211,6 +228,8 @@ namespace CrashHandler
EHPrint(" - A sleep timer will be enabled. This will cause the OS to sleep for an unknown amount of time.\n");
EHPrint(" - \eFF4400WARNING: This can crash the system if a wrong buffer is selected.\eFAFAFA\n");
EHPrint("ifr <COUNT> - Show interrupt frames.\n");
EHPrint("tlb <ADDRESS> - Print the page table entries\n");
EHPrint("bitmap - Print the memory bitmap\n");
EHPrint("main - Show the main screen.\n");
EHPrint("details - Show the details screen.\n");
EHPrint("frames - Show the stack frame screen.\n");
@ -285,6 +304,83 @@ namespace CrashHandler
}
}
}
else if (strncmp(Input, "tlb", 3) == 0)
{
char *arg = TrimWhiteSpace(Input + 3);
uint64_t Address = NULL;
Address = strtol(arg, NULL, 16);
debug("Converted %s to %#lx", arg, Address);
Memory::PageTable *BasePageTable = (Memory::PageTable *)Address;
if (Memory::Virtual().Check(BasePageTable))
for (int Index = 0; Index < 512; Index++)
{
if (BasePageTable->Entries[Index].Value.raw == 0)
continue;
TRACE_PAGE_TABLE(BasePageTable->Entries[Index], Index, "");
for (int i = 0; i < 10000; i++)
inb(0x80);
if (BasePageTable->Entries[Index].GetFlag(Memory::PTFlag::P))
{
Memory::PageTable *PDP = (Memory::PageTable *)((uint64_t)BasePageTable->Entries[Index].GetAddress() << 12);
for (int PDPIndex = 0; PDPIndex < 512; PDPIndex++)
{
if (PDP->Entries[PDPIndex].Value.raw == 0)
continue;
TRACE_PAGE_TABLE(PDP->Entries[PDPIndex], PDPIndex, " ");
for (int i = 0; i < 10000; i++)
inb(0x80);
if (PDP->Entries[PDPIndex].GetFlag(Memory::PTFlag::P))
{
Memory::PageTable *PD = (Memory::PageTable *)((uint64_t)PDP->Entries[PDPIndex].GetAddress() << 12);
for (int PDIndex = 0; PDIndex < 512; PDIndex++)
{
if (PD->Entries[PDIndex].Value.raw == 0)
continue;
TRACE_PAGE_TABLE(PD->Entries[PDIndex], PDIndex, " ");
for (int i = 0; i < 10000; i++)
inb(0x80);
if (PD->Entries[PDIndex].GetFlag(Memory::PTFlag::P))
{
Memory::PageTable *PT = (Memory::PageTable *)((uint64_t)PD->Entries[PDIndex].GetAddress() << 12);
for (int PIndex = 0; PIndex < 512; PIndex++)
{
if (PT->Entries[PIndex].Value.raw == 0)
continue;
TRACE_PAGE_TABLE(PT->Entries[PIndex], PIndex, " ");
for (int i = 0; i < 10000; i++)
inb(0x80);
}
}
}
}
}
}
}
}
else if (strncmp(Input, "bitmap", 6) == 0)
{
Bitmap bm = KernelAllocator.GetPageBitmap();
EHPrint("\n\eFAFAFA%08ld: ", 0);
for (uint64_t i = 0; i < bm.Size; i++)
{
if (bm.Get(i))
EHPrint("\eFF00001");
else
EHPrint("\e00FF000");
if (i % 128 == 127)
{
EHPrint("\n\eFAFAFA%08ld: ", i);
Display->SetBuffer(SBIdx);
}
}
EHPrint("\n\e22AA44--- END OF BITMAP ---\nBitmap size: %ld\n", bm.Size);
Display->SetBuffer(SBIdx);
}
else if (strcmp(Input, "main") == 0)
{
SBIdx = 255;

View File

@ -15,7 +15,7 @@
#include "../../kernel.h"
static const char *PagefaultDescriptions[8] = {
static const char *PageFaultDescriptions[8] = {
"Supervisory process tried to read a non-present page entry\n",
"Supervisory process tried to read a page and caused a protection fault\n",
"Supervisory process tried to write to a non-present page entry\n",
@ -177,14 +177,6 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame)
}
case CPU::x64::PageFault:
{
if (CurCPU)
if (CurCPU->CurrentThread->Stack->Expand(CPU::x64::readcr2().raw))
{
debug("Stack expanded");
TaskManager->GetCurrentThread()->Status = Tasking::TaskStatus::Ready;
return;
}
CPU::x64::PageFaultErrorCode params = {.raw = (uint32_t)Frame->ErrorCode};
#if defined(__amd64__)
error("An exception occurred at %#lx by %#lx", CPU::x64::readcr2().PFLA, Frame->rip);
@ -203,7 +195,48 @@ SafeFunction void UserModeExceptionHandler(CHArchTrapFrame *Frame)
if (Frame->ErrorCode & 0x00000008)
error("One or more page directory entries contain reserved bits which are set to 1.");
else
error(PagefaultDescriptions[Frame->ErrorCode & 0b111]);
error(PageFaultDescriptions[Frame->ErrorCode & 0b111]);
#ifdef DEBUG
if (CurCPU)
{
Memory::Virtual vma = Memory::Virtual(CurCPU->CurrentProcess->PageTable);
bool PageAvailable = vma.Check((void *)CPU::x64::readcr2().PFLA);
debug("Page available (Check(...)): %s. %s",
PageAvailable ? "Yes" : "No",
(params.P && !PageAvailable) ? "CR2 == Present; Check() != Present??????" : "CR2 confirms Check() result.");
if (PageAvailable)
{
bool Present = vma.Check((void *)CPU::x64::readcr2().PFLA);
bool ReadWrite = vma.Check((void *)CPU::x64::readcr2().PFLA, Memory::PTFlag::RW);
bool User = vma.Check((void *)CPU::x64::readcr2().PFLA, Memory::PTFlag::US);
bool WriteThrough = vma.Check((void *)CPU::x64::readcr2().PFLA, Memory::PTFlag::PWT);
bool CacheDisabled = vma.Check((void *)CPU::x64::readcr2().PFLA, Memory::PTFlag::PCD);
bool Accessed = vma.Check((void *)CPU::x64::readcr2().PFLA, Memory::PTFlag::A);
bool Dirty = vma.Check((void *)CPU::x64::readcr2().PFLA, Memory::PTFlag::D);
bool Global = vma.Check((void *)CPU::x64::readcr2().PFLA, Memory::PTFlag::G);
/* ... */
debug("Page available: %s", Present ? "Yes" : "No");
debug("Page read/write: %s", ReadWrite ? "Yes" : "No");
debug("Page user/kernel: %s", User ? "User" : "Kernel");
debug("Page write-through: %s", WriteThrough ? "Yes" : "No");
debug("Page cache disabled: %s", CacheDisabled ? "Yes" : "No");
debug("Page accessed: %s", Accessed ? "Yes" : "No");
debug("Page dirty: %s", Dirty ? "Yes" : "No");
debug("Page global: %s", Global ? "Yes" : "No");
}
}
#endif
if (CurCPU)
if (CurCPU->CurrentThread->Stack->Expand(CPU::x64::readcr2().raw))
{
debug("Stack expanded");
TaskManager->GetCurrentThread()->Status = Tasking::TaskStatus::Ready;
return;
}
break;
}
case CPU::x64::x87FloatingPoint:

View File

@ -18,9 +18,8 @@ void KernelMainThread()
{
TaskManager->InitIPC();
TaskManager->GetCurrentThread()->SetPriority(100);
Vector<AuxiliaryVector> auxv;
CPU::Interrupts(CPU::Disable);
Tasking::TCB *CurrentWorker = nullptr;
KPrint("Kernel Compiled at: %s %s with C++ Standard: %d", __DATE__, __TIME__, CPP_LANGUAGE_STANDARD);
KPrint("C++ Language Version (__cplusplus): %ld", __cplusplus);
@ -56,22 +55,16 @@ void KernelMainThread()
"--critical",
nullptr};
bool ien = CPU::Interrupts(CPU::Check);
CPU::Interrupts(CPU::Disable);
Execute::SpawnData ret = Execute::Spawn(Config.InitPath, argv, envp);
if (ret.Status != Execute::ExStatus::OK)
{
KPrint("\eE85230Failed to start %s! Code: %d", Config.InitPath, ret.Status);
if (ien)
CPU::Interrupts(CPU::Enable);
CPU::Interrupts(CPU::Enable);
goto Exit;
}
ret.Thread->SetCritical(true);
debug("%s interrupts", ien ? "Enabling" : "Disabling");
if (ien)
CPU::Interrupts(CPU::Enable);
debug("After interrupts boolean");
KPrint("Waiting for \e22AAFF%s\eCCCCCC to start...", Config.InitPath);
CPU::Interrupts(CPU::Enable);
TaskManager->GetCurrentThread()->SetPriority(1);
TaskManager->WaitForThread(ret.Thread);
KPrint("\eE85230Userspace process exited with code %d", ret.Thread->GetExitCode());