Kernel is now able to boot from mb2

This commit is contained in:
Alex
2023-05-08 00:27:12 +03:00
parent c4798a69b1
commit 7811c21971
10 changed files with 558 additions and 400 deletions

View File

@@ -146,6 +146,7 @@ NIF void MapFramebuffer(PageTable4 *PT, BootInfo *Info)
NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
{
debug("Mapping Kernel");
uintptr_t BootstrapStart = (uintptr_t)&_bootstrap_start;
uintptr_t KernelStart = (uintptr_t)&_kernel_start;
uintptr_t KernelTextEnd = (uintptr_t)&_kernel_text_end;
uintptr_t KernelDataEnd = (uintptr_t)&_kernel_data_end;
@@ -154,6 +155,9 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
uintptr_t KernelFileStart = (uintptr_t)Info->Kernel.FileBase;
uintptr_t KernelFileEnd = KernelFileStart + Info->Kernel.Size;
debug("Kernel physical address: %#lx - %#lx", Info->Kernel.PhysicalBase, (uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size);
debug("Kernel file base: %#lx - %#lx", KernelFileStart, KernelFileEnd);
debug("File size: %ld KB", TO_KB(Info->Kernel.Size));
debug(".text size: %ld KB", TO_KB(KernelTextEnd - KernelStart));
debug(".data size: %ld KB", TO_KB(KernelDataEnd - KernelTextEnd));
@@ -164,9 +168,23 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
uintptr_t k;
Virtual va = Virtual(PT);
/* Bootstrap section */
for (k = BootstrapStart; k < KernelStart - KERNEL_VMA_OFFSET; k += PAGE_SIZE)
{
#ifdef DEBUG /* vscode debugging */
void *BKMA = (void *)BaseKernelMapAddress, *K_ = (void *)k;
#endif
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE;
}
/* Text section */
for (k = KernelStart; k < KernelTextEnd; k += PAGE_SIZE)
{
#ifdef DEBUG /* vscode debugging */
void *BKMA = (void *)BaseKernelMapAddress, *K_ = (void *)k;
#endif
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE;
@@ -175,6 +193,9 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
/* Data section */
for (k = KernelTextEnd; k < KernelDataEnd; k += PAGE_SIZE)
{
#ifdef DEBUG /* vscode debugging */
void *BKMA = (void *)BaseKernelMapAddress, *K_ = (void *)k;
#endif
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE;
@@ -183,6 +204,9 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
/* Read only data section */
for (k = KernelDataEnd; k < KernelRoDataEnd; k += PAGE_SIZE)
{
#ifdef DEBUG /* vscode debugging */
void *BKMA = (void *)BaseKernelMapAddress, *K_ = (void *)k;
#endif
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::G);
KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE;
@@ -191,17 +215,23 @@ NIF void MapKernel(PageTable4 *PT, BootInfo *Info)
/* BSS section */
for (k = KernelRoDataEnd; k < KernelEnd; k += PAGE_SIZE)
{
#ifdef DEBUG /* vscode debugging */
void *BKMA = (void *)BaseKernelMapAddress, *K_ = (void *)k;
#endif
va.Map((void *)k, (void *)BaseKernelMapAddress, PTFlag::RW | PTFlag::G);
KernelAllocator.ReservePage((void *)BaseKernelMapAddress);
BaseKernelMapAddress += PAGE_SIZE;
}
debug("BaseKernelMapAddress: %#lx - %#lx", Info->Kernel.PhysicalBase, BaseKernelMapAddress);
/* Kernel file */
for (k = KernelFileStart; k < KernelFileEnd; k += PAGE_SIZE)
{
va.Map((void *)k, (void *)k, PTFlag::G);
KernelAllocator.ReservePage((void *)k);
}
if (KernelFileStart != 0)
for (k = KernelFileStart; k < KernelFileEnd; k += PAGE_SIZE)
{
va.Map((void *)k, (void *)k, PTFlag::G);
KernelAllocator.ReservePage((void *)k);
}
#ifdef DEBUG
if (EnableExternalMemoryTracer)
@@ -304,6 +334,7 @@ NIF void InitializeMemoryManagement(BootInfo *Info)
trace("Initializing Virtual Memory Manager");
KernelPageTable = (PageTable4 *)KernelAllocator.RequestPages(TO_PAGES(PAGE_SIZE + 1));
debug("Page table allocated at %#lx", KernelPageTable);
memset(KernelPageTable, 0, PAGE_SIZE);
if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0)

View File

@@ -22,6 +22,8 @@
#include <uart.hpp>
#endif
#include "../../Architecture/amd64/acpi.hpp"
#include "../../kernel.h"
extern "C" char BootPageTable[]; // 0x10000 in length
@@ -379,6 +381,7 @@ namespace Memory
TotalMemory = MemorySize;
FreeMemory = MemorySize;
size_t BitmapSize = (MemorySize / PAGE_SIZE) / 8 + 1;
void *LargestFreeMemorySegment = nullptr;
uint64_t LargestFreeMemorySegmentSize = 0;
@@ -395,39 +398,54 @@ namespace Memory
continue;
}
LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress;
LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length;
if (Info->Memory.Entry[i].Length > BitmapSize + 0x1000)
{
LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress;
LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length;
debug("Largest free memory segment: %llp (%lldMB)",
(void *)Info->Memory.Entry[i].BaseAddress,
TO_MB(Info->Memory.Entry[i].Length));
#define ROUND_UP(N, S) ((((N) + (S)-1) / (S)) * (S))
if (LargestFreeMemorySegment >= Info->Kernel.PhysicalBase &&
LargestFreeMemorySegment <= (void *)((uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size))
{
debug("Kernel range: %#lx-%#lx", Info->Kernel.PhysicalBase, (void *)((uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size));
void *NewLargestFreeMemorySegment = (void *)((uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size);
void *RoundNewLargestFreeMemorySegment = (void *)ROUND_UP((uintptr_t)NewLargestFreeMemorySegment, PAGE_SIZE);
RoundNewLargestFreeMemorySegment = (void *)((uintptr_t)RoundNewLargestFreeMemorySegment + PAGE_SIZE); /* Leave a page between the kernel and the bitmap */
debug("Rounding %p to %p", NewLargestFreeMemorySegment, RoundNewLargestFreeMemorySegment);
info("Memory bitmap's memory segment is in the kernel, moving it to %p", RoundNewLargestFreeMemorySegment);
LargestFreeMemorySegmentSize = (uintptr_t)LargestFreeMemorySegmentSize - ((uintptr_t)RoundNewLargestFreeMemorySegment - (uintptr_t)LargestFreeMemorySegment);
LargestFreeMemorySegment = RoundNewLargestFreeMemorySegment;
}
#undef ROUND_UP
if (LargestFreeMemorySegmentSize < BitmapSize + 0x1000)
{
trace("Largest free memory segment is too small (%lld bytes), skipping...",
LargestFreeMemorySegmentSize);
continue;
}
debug("Found a memory segment of %lld bytes (%lldMB) at %llp (out segment is %lld bytes (%lldKB)))",
LargestFreeMemorySegmentSize,
TO_MB(LargestFreeMemorySegmentSize),
LargestFreeMemorySegment,
BitmapSize,
TO_KB(BitmapSize));
break;
}
// LargestFreeMemorySegment = (void *)Info->Memory.Entry[i].BaseAddress;
// LargestFreeMemorySegmentSize = Info->Memory.Entry[i].Length;
// debug("Largest free memory segment: %llp (%lldMB)",
// (void *)Info->Memory.Entry[i].BaseAddress,
// TO_MB(Info->Memory.Entry[i].Length));
}
}
}
#define ROUND_UP(N, S) ((((N) + (S)-1) / (S)) * (S))
if (LargestFreeMemorySegment >= Info->Kernel.PhysicalBase &&
LargestFreeMemorySegment <= (void *)((uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size))
{
void *NewLargestFreeMemorySegment = (void *)((uintptr_t)Info->Kernel.PhysicalBase + Info->Kernel.Size);
void *RoundNewLargestFreeMemorySegment = (void *)ROUND_UP((uintptr_t)NewLargestFreeMemorySegment, PAGE_SIZE);
debug("Rounding %p to %p", NewLargestFreeMemorySegment, RoundNewLargestFreeMemorySegment);
info("Largest free memory segment is in the kernel, moving it to %p", RoundNewLargestFreeMemorySegment);
LargestFreeMemorySegment = RoundNewLargestFreeMemorySegment;
if (RoundNewLargestFreeMemorySegment >= &_bootstrap_start &&
RoundNewLargestFreeMemorySegment <= (void *)((uintptr_t)&_bootstrap_end + &_bootstrap_start))
{
void *NewNewLargestFreeMemorySegment = (void *)((uintptr_t)&_bootstrap_end + &_bootstrap_start);
void *RoundNewNewLargestFreeMemorySegment = (void *)ROUND_UP((uintptr_t)NewNewLargestFreeMemorySegment, PAGE_SIZE);
debug("Rounding %p to %p", NewNewLargestFreeMemorySegment, RoundNewNewLargestFreeMemorySegment);
info("Largest free memory segment is in the bootstrap, moving it to %p", RoundNewNewLargestFreeMemorySegment);
LargestFreeMemorySegment = RoundNewNewLargestFreeMemorySegment;
}
}
#undef ROUND_UP
if (LargestFreeMemorySegment == nullptr)
{
error("No free memory found!");
@@ -435,7 +453,6 @@ namespace Memory
}
/* TODO: Read swap config and make the configure the bitmap size correctly */
size_t BitmapSize = (MemorySize / PAGE_SIZE) / 8 + 1;
debug("Initializing Bitmap at %llp-%llp (%lld Bytes)",
LargestFreeMemorySegment,
(void *)((uintptr_t)LargestFreeMemorySegment + BitmapSize),
@@ -460,12 +477,63 @@ namespace Memory
this->ReservePage((void *)0x0); /* Trampoline stack, gdt, idt, etc... */
this->ReservePages((void *)0x2000, 4); /* TRAMPOLINE_START */
debug("Reserving bitmap pages...");
debug("Reserving bitmap region %#lx-%#lx...", PageBitmap.Buffer, (void *)((uintptr_t)PageBitmap.Buffer + PageBitmap.Size));
this->ReservePages(PageBitmap.Buffer, TO_PAGES(PageBitmap.Size));
debug("Reserving kernel...");
this->ReservePages(BootPageTable, TO_PAGES(0x10000));
// debug("Reserving page table...");
// this->ReservePages(BootPageTable, TO_PAGES(0x10000)); << in the bootstrap region
debug("Reserving kernel bootstrap region %#lx-%#lx...", &_bootstrap_start, &_bootstrap_end);
this->ReservePages(&_bootstrap_start, TO_PAGES((uintptr_t)&_bootstrap_end - (uintptr_t)&_bootstrap_start));
this->ReservePages(&_kernel_start, TO_PAGES((uintptr_t)&_kernel_end - (uintptr_t)&_kernel_start));
void *KernelPhysicalStart = (void *)(((uintptr_t)&_kernel_start - KERNEL_VMA_OFFSET));
void *KernelPhysicalEnd = (void *)(((uintptr_t)&_kernel_end - KERNEL_VMA_OFFSET));
debug("Reserving kernel region %#lx-%#lx...", KernelPhysicalStart, KernelPhysicalEnd);
this->ReservePages((void *)KernelPhysicalStart, TO_PAGES((uintptr_t)&_kernel_end - (uintptr_t)&_kernel_start));
ACPI::ACPI::ACPIHeader *hdr = nullptr;
bool XSDT = false;
if (Info->RSDP->Revision >= 2 && Info->RSDP->XSDTAddress)
{
hdr = (ACPI::ACPI::ACPIHeader *)(Info->RSDP->XSDTAddress);
XSDT = true;
}
else
{
hdr = (ACPI::ACPI::ACPIHeader *)(uintptr_t)Info->RSDP->RSDTAddress;
}
debug("Reserving RSDT...");
this->ReservePages((void*)Info->RSDP, TO_PAGES(sizeof(BootInfo::RSDPInfo)));
debug("Reserving ACPI tables...");
uint64_t TableSize = ((hdr->Length - sizeof(ACPI::ACPI::ACPIHeader)) / (XSDT ? 8 : 4));
debug("Table size: %lld", TableSize);
for (uint64_t t = 0; t < TableSize; t++)
{
// TODO: Should I be concerned about unaligned memory access?
ACPI::ACPI::ACPIHeader *SDTHdr = nullptr;
if (XSDT)
SDTHdr = (ACPI::ACPI::ACPIHeader *)(*(uint64_t *)((uint64_t)hdr + sizeof(ACPI::ACPI::ACPIHeader) + (t * 8)));
else
SDTHdr = (ACPI::ACPI::ACPIHeader *)(*(uint32_t *)((uint64_t)hdr + sizeof(ACPI::ACPI::ACPIHeader) + (t * 4)));
this->ReservePages(SDTHdr, TO_PAGES(SDTHdr->Length));
}
debug("Reserving kernel modules...");
for (uint64_t i = 0; i < MAX_MODULES; i++)
{
if (Info->Modules[i].Address == 0x0)
continue;
debug("Reserving module %s (%#lx-%#lx)...", Info->Modules[i].CommandLine,
Info->Modules[i].Address, (void *)((uintptr_t)Info->Modules[i].Address + Info->Modules[i].Size));
this->ReservePages((void *)Info->Modules[i].Address, TO_PAGES(Info->Modules[i].Size));
}
}
Physical::Physical() {}

View File

@@ -28,6 +28,13 @@ namespace SymbolResolver
Symbols::Symbols(uintptr_t ImageAddress)
{
debug("Solving symbols for address: %#llx", ImageAddress);
if (ImageAddress == 0)
{
error("Invalid image address");
return;
}
Elf64_Ehdr *Header = (Elf64_Ehdr *)ImageAddress;
if (Header->e_ident[0] != 0x7F &&
Header->e_ident[1] != 'E' &&