Skip to content
This repository has been archived by the owner on Sep 18, 2024. It is now read-only.

Commit

Permalink
So close to paging working!
Browse files Browse the repository at this point in the history
  • Loading branch information
jakeSteinburger committed Aug 19, 2024
1 parent 8d75005 commit 6d3644a
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 43 deletions.
2 changes: 1 addition & 1 deletion compile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ du -h bin/SpecOS

# if image could be built, run it in qemu
if test -f "bin/SpecOS"; then
qemu-system-x86_64 disk.img -d int -serial stdio --no-reboot --no-shutdown -accel kvm
qemu-system-x86_64 disk.img -d int -serial stdio --no-reboot --no-shutdown
fi

# delete old stuff
Expand Down
31 changes: 15 additions & 16 deletions kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -74,29 +74,28 @@ void initKernelData() {
void _start() {
initKernelData();
init_serial();
initVGA();
// Just send output to a serial port to test
writestring("Trying to initialise GDT...\n");
initGDT();
writestring("\n\nTrying to initialise IDT & everything related...\n");
initIDT();
writestring("\nStarting physical memory manager...");
writeserial("\nStarting physical memory manager...\n");
initPMM();
// this is commented out cos paging doesn't work yet and it's still in progress.
writestring("\nInitiating paging...\n");
writeserial("\nInitiating paging...\n");
uint64_t* pml4Address = initPaging();
printf("Pages mapped, trying to reload cr3...");
writeserial("Pages mapped, trying to reload cr3...\n");
// load a pointer to pml4 into cr3 and change the stack to point elsewhere
/* __asm__ volatile (
"movq %1, %%cr3;"
// "movq %0, %%rsp;"
// "movq %1, %%rbp"
__asm__ volatile (
"mov %1, %%cr3;"
"mov %0, %%rsp;"
"mov %1, %%rbp"
: : "r" ((uint64_t) 0xfffffffffffff000),
"r" ((uint64_t) pml4Address)
);*/
asm volatile("mov %0, %%cr3" : : "r" ((uint64_t)pml4Address));
);
for (;;); // so that it doesn't try do stuff that requires a stack, thus crashing it
printf("\nPaging successfully enabled! CR3: 0x%x\n", (uint64_t)pml4Address);
writeserial("\nPaging successfully enabled!\n");
initVGA();
// Just send output to a serial port to test
writestring("Trying to initialise GDT...\n");
initGDT();
writestring("\n\nTrying to initialise IDT & everything related...\n");
initIDT();
test_userspace();
for (;;);
}
8 changes: 1 addition & 7 deletions mem/mapKernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

#include "include/mapKernel.h"
#include "../include/kernel.h"
#include "../drivers/include/serial.h"
#include "../utils/include/printf.h"
#include "include/paging.h"
#include "../limine.h"
Expand All @@ -29,17 +30,10 @@ uint64_t writeallowed_end = (uint64_t)p_writeallowed_end;
// void mapPages(uint64_t pml4[], uint64_t virtAddr, uint64_t physAddr, uint64_t flags, uint64_t numPages)

void mapKernel() {
printf("kernel_start: %x\n"
"nxe_enabled_start: %x\n"
"nxe_enabled_end: %x\n"
"writeallowed_start: %x\n"
"writeallowed_end: %x\n",
kernel_start, nxe_enabled_start, nxe_enabled_end, writeallowed_start, writeallowed_end);
uint64_t lengthBuffer;
uint64_t physBuffer;
/* map from kernel_start to nxe_enabled_start with nothing but `present` (.text section) */
lengthBuffer = PAGE_ALIGN_UP(nxe_enabled_start) - PAGE_ALIGN_DOWN(kernel_start);
printf("kernel_start - 0xffff80000000 = %x\n", kernel_start - 0xffffffff80000000);
physBuffer = kernel.kernelAddress.physical_base + (kernel_start - 0xffffffff80000000);
mapPages(kernel.pml4, PAGE_ALIGN_DOWN(kernel_start), physBuffer, KERNEL_PFLAG_PRESENT, lengthBuffer / 4096);
/* map from nxe_enabled_start to writeallowed_start with `present` and `pxd` */
Expand Down
20 changes: 3 additions & 17 deletions mem/paging.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <stdbool.h>
#include "include/mapKernel.h"
#include "include/pmm.h" // for dynamically allocating phys mem
#include "../drivers/include/serial.h"
#include "include/mapKernel.h"
#include "../utils/include/string.h"
#include "../utils/include/printf.h" // my bestie, printf debugging!
Expand Down Expand Up @@ -39,7 +40,6 @@ void debugPml4() {
// this will require getting the pml indexes to use based on the virtual address to map
// idk how else to explain it really lol, sorry
void mapPages(uint64_t pml4[], uint64_t virtAddr, uint64_t physAddr, uint64_t flags, uint64_t numPages) {
writestring(" [DEBUG] Trying to map a new set of pages...\n");
virtAddr &= ~0xFFFF000000000000;
// get the indexes of each page directory level (aka pml)
uint64_t pml1Index = (virtAddr >> 12) & 511;
Expand All @@ -50,7 +50,6 @@ void mapPages(uint64_t pml4[], uint64_t virtAddr, uint64_t physAddr, uint64_t fl
uint64_t *pml3Addr = NULL;
if (pml4[pml4Index] == 0) {
pml4[pml4Index] = (uint64_t)kmalloc();
printf("Address pml4 value will be at: %x\n", pml4[pml4Index]);
pml3Addr = (uint64_t*)(pml4[pml4Index] + kernel.hhdm);
memset((uint8_t*)pml3Addr, 0, 8 * 512);
pml4[pml4Index] |= flags | KERNEL_PFLAG_PRESENT | KERNEL_PFLAG_WRITE;
Expand Down Expand Up @@ -85,7 +84,6 @@ void mapPages(uint64_t pml4[], uint64_t virtAddr, uint64_t physAddr, uint64_t fl
numPages--;
physAddr += 4096;
if (numPages == 0) {
writestring(" [DEBUG] Finished mapping pages.\n");
return;
}
}
Expand All @@ -98,24 +96,12 @@ void mapPages(uint64_t pml4[], uint64_t virtAddr, uint64_t physAddr, uint64_t fl
}

uint64_t* initPaging() {
/* page entries will be defined later when filling pml1
* and so will the pdpt when loading it into cr3
* fill up pml1 with mappings
* this initially sets up only kernelspace paging, and currently maps only the kernel memory
* kernel (including the headers) starts at 0xffffffff80000000 in vmem (-kernel.hhdm for physical memory)
* aCcorDiNG TO My caLcuLatIoNS, the kernel's size is about 108 kilobytes, which is 110592 bytes.
* That's 27 page frames. Just to be safe however, I'll give it one extra page frame in case the kernel grows.
* So, it must map the kernel from 0xffffffff80000000 for 28 page frames in vmem.
*/
uint64_t startingPageFrame = 0xffffffff80000000 / 4096;
uint64_t endPageFrame = startingPageFrame + 28;
printf("\nMapping pages...\n");
uint64_t* pml4Phys = kernel.kernelAddress.physical_base + (kernel.pml4 - 0xffffffff80000000);
mapKernel();
printf("Pages mapped successfully\n");
//printf("pml4 contents: \n");
//debugPml4();
// return some stuff so the entry point function of the kernel can reload cr3
return kernel.pml4 + kernel.hhdm;
return pml4Phys;
// no need to enable paging, limine already enables it :D
}

Expand Down
5 changes: 3 additions & 2 deletions mem/pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "../limine.h"
#include "../utils/include/string.h"
#include "include/pmm.h"
#include "../drivers/include/serial.h"
#include "include/detect.h"
#include "../utils/include/binop.h"
#include "../include/kernel.h"
Expand Down Expand Up @@ -76,7 +77,7 @@ void initPMM() {
uint64_to_hex_string(maxBegin, b1);
uint64_to_hex_string(maxLength, b2);
uint64_to_hex_string(bitmapReserved, b3);
printf("\nChosen segment starts at 0x%s, has a size of 0x%s, and reserves 0x%s bytes for the bitmap.\n", b1, b2, b3);
writeserial("Successfully initialised physical memory allocator.\n");
}

// just a basic utility
Expand Down Expand Up @@ -109,7 +110,7 @@ void* kmalloc() {
// if it got to this point, no memory address is avaliable.
// print an error message and halt the computer
kernel.colourOut = 0xFF0000;
writestring("KERNEL ERROR: Not enough physical memory space to allocate.\nHalting device.");
writeserial("KERNEL ERROR: Not enough physical memory space to allocate.\nHalting device.");
asm("cli; hlt");
// and make the compiler happy by returning an arbitrary value
return (void*) 0x00;
Expand Down

0 comments on commit 6d3644a

Please sign in to comment.