Fix paging on >143MB ram.

Add visual printf.
This commit is contained in:
Curle 2021-06-14 01:36:46 +01:00
parent 77933c3aa4
commit 5ffa467b7d
Signed by: TheCurle
GPG Key ID: 5942F13718443F79
9 changed files with 143 additions and 54 deletions

View File

@ -52,7 +52,8 @@ typedef struct {
size_t KernelAddr; size_t KernelAddr;
size_t KernelEnd; size_t KernelEnd;
size_t MemoryPages; size_t MemoryPages;
size_t MemorySize; size_t FreeMemorySize;
size_t FullMemorySize;
void DrawPixel(uint32_t x, uint32_t y, uint32_t color); void DrawPixel(uint32_t x, uint32_t y, uint32_t color);

View File

@ -73,6 +73,7 @@ void WriteSerialChar(const char);
void WriteSerialString(const char*, size_t); void WriteSerialString(const char*, size_t);
int SerialPrintf(const char* restrict format, ...); int SerialPrintf(const char* restrict format, ...);
int Printf(const char* restrict Format, ...);
void* memcpy(void* dest, void const* src, size_t len); void* memcpy(void* dest, void const* src, size_t len);
void* memset(void* dst, int src, size_t len); void* memset(void* dst, int src, size_t len);

View File

@ -43,6 +43,7 @@
#define IS_ALIGNED(addr) (((size_t) addr | 0xFFFFFFFFFFFFF000) == 0) #define IS_ALIGNED(addr) (((size_t) addr | 0xFFFFFFFFFFFFF000) == 0)
#define PAGE_ALIGN(addr) ((((size_t) addr) & 0xFFFFFFFFFFFFF000) + 0x1000) #define PAGE_ALIGN(addr) ((((size_t) addr) & 0xFFFFFFFFFFFFF000) + 0x1000)
#define PAGE_ALIGN_DOWN(addr) ((((size_t) addr) & 0xFFFFFFFFFFFFF000) - 0x1000)
#define SET_PGBIT(cr0) (cr0 = cr0 | 1 << 31) #define SET_PGBIT(cr0) (cr0 = cr0 | 1 << 31)
#define UNSET_PGBIT(cr0) (cr0 = cr0 ^ 1 << 31) #define UNSET_PGBIT(cr0) (cr0 = cr0 ^ 1 << 31)
@ -215,7 +216,7 @@ size_t AllocatorAllocateOverhead(void);
size_t AlignUpwards(size_t Pointer, size_t Alignment); size_t AlignUpwards(size_t Pointer, size_t Alignment);
size_t AlignDownwards(size_t Pointer, size_t Alignment); size_t AlignDownwards(size_t Pointer, size_t Alignment);
void* AlignPointer(const void* Pointer, size_t Alignment); void* AlignPointer(const void* Pointer, size_t Alignment);
/************************************************************ /************************************************************

View File

@ -47,15 +47,13 @@ int Main(void) {
InitMemoryManager(); InitMemoryManager();
//DrawSplash(); //DrawSplash();
InitPrint();
InitPaging(); InitPaging();
InitPrint(); Printf("Paging complete. System initialized.\r\n");
WriteString("Paging complete. System initialized."); for (;;) {}
for(;;) { }
return 0; return 0;

View File

@ -207,6 +207,8 @@ void EmptyIRQ(INTERRUPT_FRAME* frame) {
} }
} }
for(size_t i = 0; i < 100000; i++) {}
for(size_t y = 0; y < bootldr.fb_height; y++) { for(size_t y = 0; y < bootldr.fb_height; y++) {
for(size_t x = 0; x < 20; x++) { for(size_t x = 0; x < 20; x++) {
DrawPixel(x, y, 0x000000FF); DrawPixel(x, y, 0x000000FF);
@ -309,6 +311,7 @@ __attribute__((interrupt)) void ISR6Handler(INTERRUPT_FRAME* Frame) {
__asm__ __volatile__("popq %%rax\n\t" "pushq %%rax": "=a" (retAddr) : :); __asm__ __volatile__("popq %%rax\n\t" "pushq %%rax": "=a" (retAddr) : :);
SerialPrintf("[FAULT] Opcode is at 0x%x, called from 0x%p\r\n", opcodeAddr, retAddr); SerialPrintf("[FAULT] Opcode is at 0x%x, called from 0x%p\r\n", opcodeAddr, retAddr);
Printf("Invalid Opcode: 0x%p\n", opcodeAddr);
StackTrace(15); StackTrace(15);

View File

@ -44,9 +44,9 @@ void InitPaging() {
KernelLocation = DecodeVirtualAddressNoDirect(&BootloaderAddressSpace, AddressToFind); KernelLocation = DecodeVirtualAddressNoDirect(&BootloaderAddressSpace, AddressToFind);
SerialPrintf("[ Mem] Double check: Kernel physically starts at 0x%p (0x%p), ends at 0x%p.\r\n", KernelLocation, AddressToFind, KERNEL_END); SerialPrintf("[ Mem] Double check: Kernel physically starts at 0x%p (0x%p), ends at 0x%p.\r\n", KernelLocation, AddressToFind, KERNEL_END);
SerialPrintf("[ Mem] Identity mapping the entirety of physical memory\r\n"); SerialPrintf("[ Mem] Identity mapping the entire 0x%p bytes of physical memory to 0x%p\r\n", FullMemorySize, (size_t) KernelAddressSpace.PML4);
for(size_t i = 0; i < MemorySize / PAGE_SIZE; i++) { for(size_t i = 0; i < (FullMemorySize / 4096); i++) {
size_t Addr = i * 4096; size_t Addr = i * 4096;
MapVirtualPageNoDirect(&KernelAddressSpace, Addr, Addr, DEFAULT_PAGE_FLAGS); MapVirtualPageNoDirect(&KernelAddressSpace, Addr, Addr, DEFAULT_PAGE_FLAGS);
MapVirtualPageNoDirect(&KernelAddressSpace, Addr, TO_DIRECT(Addr), DEFAULT_PAGE_FLAGS); MapVirtualPageNoDirect(&KernelAddressSpace, Addr, TO_DIRECT(Addr), DEFAULT_PAGE_FLAGS);
@ -82,9 +82,6 @@ void InitPaging() {
SerialPrintf("[ Mem] Diagnostic: Existing pagetables put 0x%p at 0x%p + 0x%p.\r\n", AddressToFind, KERNEL_PHYSICAL, AddressToFind & ~STACK_TOP); SerialPrintf("[ Mem] Diagnostic: Existing pagetables put 0x%p at 0x%p + 0x%p.\r\n", AddressToFind, KERNEL_PHYSICAL, AddressToFind & ~STACK_TOP);
SerialPrintf("[ Mem] %s\r\n", KernelAddress == KERNEL_PHYSICAL ? "These match. Continuing." : "These do not match. Continuing with caution.."); SerialPrintf("[ Mem] %s\r\n", KernelAddress == KERNEL_PHYSICAL ? "These match. Continuing." : "These do not match. Continuing with caution..");
//if(BootloaderAddress != KernelDisoveredAddress)
//for(;;) {}
SerialPrintf("[ Mem] Attempting to jump into our new pagetables: 0x%p\r\n", (size_t) KernelAddressSpace.PML4); SerialPrintf("[ Mem] Attempting to jump into our new pagetables: 0x%p\r\n", (size_t) KernelAddressSpace.PML4);
WriteControlRegister(3, (size_t) KernelAddressSpace.PML4 & STACK_TOP); WriteControlRegister(3, (size_t) KernelAddressSpace.PML4 & STACK_TOP);
SerialPrintf("[ Mem] Worked\r\n"); SerialPrintf("[ Mem] Worked\r\n");
@ -266,6 +263,7 @@ void MapVirtualPageNoDirect(address_space_t* AddressSpace, size_t Physical, size
AddressSpace->PML4[PDPT] = (size_t) PDPT_T | DEFAULT_PAGE_FLAGS; AddressSpace->PML4[PDPT] = (size_t) PDPT_T | DEFAULT_PAGE_FLAGS;
} }
// The above repeats. // The above repeats.
if(PDPT_T[PDP] & PRESENT_BIT) if(PDPT_T[PDP] & PRESENT_BIT)
PDE_T = (size_t*) (PDPT_T[PDP] & STACK_TOP); PDE_T = (size_t*) (PDPT_T[PDP] & STACK_TOP);
@ -274,6 +272,7 @@ void MapVirtualPageNoDirect(address_space_t* AddressSpace, size_t Physical, size
PDPT_T[PDP] = (size_t) PDE_T | DEFAULT_PAGE_FLAGS; PDPT_T[PDP] = (size_t) PDE_T | DEFAULT_PAGE_FLAGS;
} }
if(PDE_T[PDE] & PRESENT_BIT) if(PDE_T[PDE] & PRESENT_BIT)
PT_T = (size_t*) (PDE_T[PDE] & STACK_TOP); PT_T = (size_t*) (PDE_T[PDE] & STACK_TOP);
else { else {
@ -281,8 +280,9 @@ void MapVirtualPageNoDirect(address_space_t* AddressSpace, size_t Physical, size
PDE_T[PDE] = (size_t) PT_T | DEFAULT_PAGE_FLAGS; PDE_T[PDE] = (size_t) PT_T | DEFAULT_PAGE_FLAGS;
} }
// Finally, set the last page table content to the physical page + the flags we specified. // Finally, set the last page table content to the physical page + the flags we specified.]
PT_T[PT] = (size_t) (Physical | PageFlags); *(PT_T + PT) = (size_t) (Physical | PageFlags);
} }
/** /**
@ -318,7 +318,6 @@ size_t* CreateNewPageTable(address_space_t* AddressSpace) {
MapVirtualPage(&TempAddressSpace, Addr, Addr, DEFAULT_PAGE_FLAGS); MapVirtualPage(&TempAddressSpace, Addr, Addr, DEFAULT_PAGE_FLAGS);
// Map higher half // Map higher half
MapVirtualPage(&TempAddressSpace, Addr, TO_DIRECT(Addr), DEFAULT_PAGE_FLAGS); MapVirtualPage(&TempAddressSpace, Addr, TO_DIRECT(Addr), DEFAULT_PAGE_FLAGS);
// TODO: Map into kernel space
} }
// Identity map the next 4gb // Identity map the next 4gb

View File

@ -166,24 +166,26 @@ void InitMemoryManager() {
SerialPrintf("[ Mem] Counting memory..\r\n"); SerialPrintf("[ Mem] Counting memory..\r\n");
MemorySize = 0; FreeMemorySize = 0;
FullMemorySize = 0;
size_t MemMapEntryCount = 0; size_t MemMapEntryCount = 0;
MMapEnt* MemMap = &bootldr.mmap; MMapEnt* MemMap = &bootldr.mmap;
while((size_t) MemMap < ((size_t) &bootldr) + bootldr.size) { while((size_t) MemMap < ((size_t) &bootldr) + bootldr.size) {
if(MMapEnt_IsFree(MemMap)) { if(MMapEnt_IsFree(MemMap)) {
MemorySize += MMapEnt_Size(MemMap); FreeMemorySize += MMapEnt_Size(MemMap);
} }
FullMemorySize += MMapEnt_Size(MemMap);
MemMapEntryCount++; MemMapEntryCount++;
MemMap++; MemMap++;
} }
SerialPrintf("[ Mem] Counted %d entries in the memory map..\r\n", MemMapEntryCount); SerialPrintf("[ Mem] Counted %d entries in the memory map..\r\n", MemMapEntryCount);
MemoryPages = MemorySize / PAGE_SIZE; MemoryPages = FreeMemorySize / PAGE_SIZE;
SerialPrintf("[ Mem] %u MB of memory detected.\r\n", (MemorySize / 1024) / 1024); SerialPrintf("[ Mem] %u MB of memory detected.\r\n", (FreeMemorySize / 1024) / 1024);
} }
@ -217,8 +219,14 @@ void ListMemoryMap() {
SerialPrintf("[ Mem] 0x%p-0x%p %s\r\n", entry_from, entry_to, EntryType); SerialPrintf("[ Mem] 0x%p-0x%p %s\r\n", entry_from, entry_to, EntryType);
if(MMapEnt_Type(MapEntry) == MMAP_FREE) { if(MMapEnt_Type(MapEntry) == MMAP_FREE) {
SerialPrintf("[ Mem] Adding this entry to the physical memory manager!\r\n"); // We need to page align the inputs to the buddy lists.
AddRangeToPhysMem((void*)((char*)(MMapEnt_Ptr(MapEntry) /* + DIRECT_REGION*/ )), MMapEnt_Size(MapEntry)); size_t page_from = AlignUpwards(entry_from, 0x1000);
size_t page_to = AlignDownwards(entry_to, 0x1000);
if(page_from != 0 && page_to != 0) {
SerialPrintf("[ Mem] Adding the range 0x%p-0x%p to the physical memory manager!\r\n", page_from, page_to);
AddRangeToPhysMem((void*)((char*)(page_from)), page_to - page_from);
}
} }
} }

View File

@ -54,18 +54,20 @@ void InitPrint() {
PrintInfo.charHLColor = 0x00000000; PrintInfo.charHLColor = 0x00000000;
PrintInfo.charBGColor = 0x00000000; PrintInfo.charBGColor = 0x00000000;
PrintInfo.charScale = 2; PrintInfo.charScale = 1;
PrintInfo.charPosX = 0; PrintInfo.charPosX = 1;
PrintInfo.charPosY = 1; PrintInfo.charPosY = 2;
PrintInfo.scrlMode = 0; PrintInfo.scrlMode = 0;
PrintInfo.charsPerRow = bootldr.fb_width / (PrintInfo.charScale * PrintInfo.charWidth) - 5; PrintInfo.charsPerRow = bootldr.fb_width / (PrintInfo.charScale * PrintInfo.charWidth) - 4;
PrintInfo.rowsPerScrn = bootldr.fb_height / (PrintInfo.charScale * PrintInfo.charHeight); PrintInfo.rowsPerScrn = bootldr.fb_height / (PrintInfo.charScale * PrintInfo.charHeight);
SerialPrintf("[Print] A single character is %ux%u pixels.\r\n", PrintInfo.charScale * PrintInfo.charWidth, PrintInfo.charScale * PrintInfo.charHeight); SerialPrintf("[Print] A single character is %ux%u pixels.\r\n", PrintInfo.charScale * PrintInfo.charWidth, PrintInfo.charScale * PrintInfo.charHeight);
SerialPrintf("[Print] The screen is %ux%u, meaning you can fit %ux%u characters on screen.\r\n", bootldr.fb_width, bootldr.fb_height, PrintInfo.charsPerRow, PrintInfo.rowsPerScrn); SerialPrintf("[Print] The screen is %ux%u, meaning you can fit %ux%u characters on screen.\r\n", bootldr.fb_width, bootldr.fb_height, PrintInfo.charsPerRow, PrintInfo.rowsPerScrn);
WriteString("Testing print\n");
} }
static void DrawChar(const char character, size_t x, size_t y) { static void DrawChar(const char character, size_t x, size_t y) {
@ -91,12 +93,10 @@ static void DrawChar(const char character, size_t x, size_t y) {
if((FONT[(int)character][Row * Y + X] >> (Bit & 0x7)) & 1) { // Check the bit in the bitmap, if it's solid.. if((FONT[(int)character][Row * Y + X] >> (Bit & 0x7)) & 1) { // Check the bit in the bitmap, if it's solid..
for(uint32_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) { // Take care of the scale height for(uint32_t ScaleY = 0; ScaleY < PrintInfo.charScale; ScaleY++) { // Take care of the scale height
for(uint32_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) { // And the scale width for(uint32_t ScaleX = 0; ScaleX < PrintInfo.charScale; ScaleX++) { // And the scale width
size_t offset = ((y * bootldr.fb_width + x) + // Calculate the offset from the framebuffer size_t offset = ((y * bootldr.fb_width + x) + // Calculate the offset from the framebuffer
PrintInfo.charScale * (Row * bootldr.fb_width + Bit) + // With the appropriate scale PrintInfo.charScale * (Row * bootldr.fb_width + Bit) + // With the appropriate scale
(ScaleY * bootldr.fb_width + ScaleX) + // In X and Y (ScaleY * bootldr.fb_width + ScaleX) + // In X and Y
PrintInfo.charScale * 1 * PrintInfo.charWidth) - 10; // With some offset to start at 0 PrintInfo.charScale * 1 * PrintInfo.charWidth) - 10; // With some offset to start at 0
*(uint32_t* )(&fb + offset * 4) // And use it to set the correct pixel on the screen *(uint32_t* )(&fb + offset * 4) // And use it to set the correct pixel on the screen
= PrintInfo.charFGColor; // In the set foreground color = PrintInfo.charFGColor; // In the set foreground color
} }
@ -277,7 +277,6 @@ void WriteChar(const char character) {
break; break;
default: default:
DrawChar(character, PrintInfo.charPosX, PrintInfo.charPosY); DrawChar(character, PrintInfo.charPosX, PrintInfo.charPosY);
ProgressCursor(); ProgressCursor();
break; break;
} }
@ -302,8 +301,8 @@ void WriteStringWithFont(const char *inChar)
unsigned char *glyph = unsigned char *glyph =
(unsigned char*) &_binary_font_psf_start (unsigned char*) &_binary_font_psf_start
+ font->headerSize + font->headerSize
+ (*inChar > 0 && *inChar < (int)font->numGlyphs ? *inChar : 0) * + (*inChar > 0 && *inChar < (int)font->numGlyphs ? *inChar : 0)
font->glyphSize; * font->glyphSize;
offset = (kx * (font->glyphWidth + 1) * 4); offset = (kx * (font->glyphWidth + 1) * 4);

View File

@ -120,3 +120,82 @@ int SerialPrintf(const char* restrict Format, ...) {
return CharsWritten; return CharsWritten;
} }
int Printf(const char* restrict Format, ...) {
va_list Parameters;
va_start(Parameters, Format);
int CharsWritten = 0;
size_t Base, Num;
char BufferStr[512] = {0};
while(*Format != '\0') {
size_t Limit = UINT64_MAX - CharsWritten;
if(*Format == '%') {
if(*(++Format) == '%')
Format++;
switch(*Format) {
case 'c':
Format++;
char c = (char) va_arg(Parameters, int);
WriteString(&c);
CharsWritten++;
break;
case 's':
Format++;
const char* Str = va_arg(Parameters, char*);
size_t Len = strlen(Str);
if(Limit < Len)
return -1;
WriteString(Str);
CharsWritten += Len;
break;
case 'd':
case 'u':
case 'p':
case 'x':
Num = va_arg(Parameters, size_t);
Base = 0;
if(*Format == 'd' || *Format == 'u') {
Base = 10; // Decimal & Unsigned are base 10
} else {
Base = 16; // Hex and Ptr are base 16
}
Format++;
NumToStr(BufferStr, Num, Base);
Len = strlen(BufferStr);
WriteString(BufferStr);
CharsWritten += Len;
break;
//case 'p':
//uint8_t Base = 16;
//size_t Dest = (uintptr_t) va_arg(Parameters, void*);
default:
WriteString("%u");
break;
}
} else {
WriteChar(*Format);
Format++;
}
}
va_end(Parameters);
return CharsWritten;
}