feat: introduce bootloader-agnostic Boot Contract, add btlist command to list connected Bluetooth devices

This commit is contained in:
2026-06-20 21:25:24 +02:00
parent de871ac402
commit 772eaee9f4
20 changed files with 904 additions and 213 deletions
+49 -14
View File
@@ -23,7 +23,8 @@ namespace Memory::VMM {
PML4 = (PageTable*)SubHHDM((PageTable*)Memory::g_pfa->AllocateZeroed());
}
void Paging::Init(std::uint64_t kernelBaseVirt, std::uint64_t kernelSize, limine_memmap_response* memMap) {
void Paging::Init(std::uint64_t kernelBaseVirt, std::uint64_t kernelSize, const montauk::boot::MemoryMap& memMap,
const montauk::boot::Framebuffer& framebuffer) {
// Map kernel
Kt::KernelLogStream(Kt::DEBUG, "VMM") << "Paging::Init called with kernelBaseVirt as 0x" << base::hex << kernelBaseVirt;
@@ -31,15 +32,31 @@ namespace Memory::VMM {
Map(GetPhysKernelAddress(pageAddr), pageAddr);
}
// Map HHDM: find the highest physical address and map everything
// from 0 to that point. This covers gaps between memory map entries
// (e.g. BIOS ROM at 0xE0000) that firmware may not list but the
// kernel still needs to access via HHDM.
// Map HHDM: map physical memory contiguously from 0 up to the top of
// real backing store, so the kernel can reach any RAM/firmware byte at
// phys+hhdmBase. Mapping from 0 (rather than per-region) also covers
// unlisted low gaps -- BIOS ROM at 0xE0000, the EBDA, etc. -- that the
// kernel still touches through the HHDM.
//
// The upper bound is computed over real backing store ONLY: RAM, ACPI
// tables, modules, the framebuffer, and so on. Reserved/Unknown
// regions are deliberately EXCLUDED from the bound. Firmware commonly
// reports the 64-bit PCI MMIO aperture as a Reserved region hundreds of
// GiB above RAM (its base scales with the CPU's physical-address width);
// letting that inflate maxPhysAddr would make this loop allocate
// gigabytes of 4 KiB page tables and exhaust the frame allocator (OOM).
// Such MMIO is mapped on demand via MapMMIO with the right cache
// attributes -- never through the HHDM -- so it is correct to leave it
// out here. Reserved regions that sit *below* the bound (e.g. low BIOS
// areas) are still mapped by the contiguous fill.
uint64_t maxPhysAddr = 0;
for (size_t i = 0; i < memMap->entry_count; i++) {
auto entry = memMap->entries[i];
uint64_t entryEnd = entry->base + entry->length;
for (size_t i = 0; i < memMap.count; i++) {
const auto& entry = memMap.regions[i];
if (entry.kind == montauk::boot::MemoryKind::Reserved
|| entry.kind == montauk::boot::MemoryKind::Unknown) {
continue;
}
uint64_t entryEnd = entry.base + entry.length;
if (entryEnd > maxPhysAddr) maxPhysAddr = entryEnd;
}
maxPhysAddr = (maxPhysAddr + 0xFFF) & ~0xFFFULL;
@@ -48,6 +65,24 @@ namespace Memory::VMM {
Map(pageAddr, HHDM(pageAddr));
}
// The linear framebuffer can sit in a PCI BAR above the RAM bound we
// just mapped (e.g. in the 32-bit MMIO hole), and it is not guaranteed
// to appear as a memory-map region. It MUST be reachable through the
// HHDM before we switch to these page tables, because the very next log
// line (and PAT setup, and Cursor init) renders to it via phys+hhdmBase.
// Map its pages explicitly (write-back for now; Cursor upgrades them to
// write-combining once PAT is reprogrammed).
if (framebuffer.address != 0) {
uint64_t fbPhys = Memory::SubHHDM(framebuffer.address);
uint64_t fbBytes = framebuffer.height * framebuffer.pitch;
uint64_t fbPages = (fbBytes + 0xFFF) / 0x1000;
fbPhys &= ~0xFFFULL;
for (uint64_t p = 0; p < fbPages; p++) {
uint64_t phys = fbPhys + p * 0x1000;
Map(phys, HHDM(phys));
}
}
LoadCR3(PML4);
Kt::KernelLogStream(Kt::OK, "VMM") << "Switched CR3";
}
@@ -455,12 +490,12 @@ namespace Memory::VMM {
return GetPhysAddr((std::uint64_t)PML4, virtualAddress, false);
}
void Paging::MapEfiRuntime(limine_efi_memmap_response* efiMemmap) {
if (!efiMemmap) return;
void Paging::MapEfiRuntime(const montauk::boot::EfiInfo& efi) {
if (efi.memoryMap == nullptr || efi.descriptorSize == 0) return;
auto* base = (uint8_t*)efiMemmap->memmap;
uint64_t descSize = efiMemmap->desc_size;
uint64_t count = efiMemmap->memmap_size / descSize;
auto* base = (uint8_t*)efi.memoryMap;
uint64_t descSize = efi.descriptorSize;
uint64_t count = efi.memoryMapSize / descSize;
struct EfiMemDesc {
uint32_t Type;