Merge pull request #14 from 0xKSor/feat/pmm

PMM
This commit is contained in:
hwachakarter
2026-04-26 20:18:40 +09:00
committed by GitHub
8 changed files with 178 additions and 14 deletions
+2 -1
View File
@@ -1,6 +1,7 @@
#pragma once #pragma once
#include <Types.h> #include <Types.h>
#include <VM/PMM.h>
typedef struct FDTHeader { typedef struct FDTHeader {
UInt32 magic; // 0xd00dfeed UInt32 magic; // 0xd00dfeed
@@ -32,4 +33,4 @@ enum {
kFDTHeaderMagic = 0xd00dfeed, kFDTHeaderMagic = 0xd00dfeed,
}; };
void DTBParse(Pointer dtb); void DTBParse(Pointer dtb, VMBootMemoryMap* bootMap);
+4
View File
@@ -0,0 +1,4 @@
#pragma once
#include <Types.h>
void* memset(void* destination, int value, Size count);
+23
View File
@@ -0,0 +1,23 @@
#pragma once
#include <Types.h>
enum {
kVMPageSize = 4096,
kVMBlocksPerByte = 8,
kVMMaxReservedRegions = 128,
};
typedef struct {
UInt64 base;
Size size;
} VMMemoryRegion;
typedef struct {
VMMemoryRegion totalRAM;
VMMemoryRegion reserved[kVMMaxReservedRegions];
UInt32 reservedCount;
} VMBootMemoryMap;
void PMMInitialize(VMBootMemoryMap* bootMap);
Pointer PMMAllocatePage();
void PMMFreePage(Address address);
+46 -11
View File
@@ -1,22 +1,33 @@
#include "Types.h"
#include <Arch/DTB.h> #include <Arch/DTB.h>
#include <OS/Panic.h> #include <OS/Panic.h>
#include <OS/Log.h> #include <OS/Log.h>
#include <Lib/Bytes.h> #include <Lib/Bytes.h>
#include <Lib/Align.h> #include <Lib/Align.h>
#include <Lib/String.h> #include <Lib/String.h>
#include <VM/PMM.h>
void DTBParse(Pointer dtb) { void DTBParse(Pointer dtb, VMBootMemoryMap* bootMap) {
FDTHeader* header = (FDTHeader*)dtb; FDTHeader* header = (FDTHeader*)dtb;
if (BytesSwap32(header->magic) != kFDTHeaderMagic) { if (BytesSwap32(header->magic) != kFDTHeaderMagic) {
OSPanic("Invalid DTB magic"); OSPanic("Invalid DTB magic");
} }
UInt32 index = bootMap->reservedCount;
bootMap->reserved[index].base = (Address)dtb;
bootMap->reserved[index].size = BytesSwap32(header->totalSize);
bootMap->reservedCount++;
UInt32 offStruct = BytesSwap32(header->offDtStruct); UInt32 offStruct = BytesSwap32(header->offDtStruct);
UInt32 offStrings = BytesSwap32(header->offDtStrings); UInt32 offStrings = BytesSwap32(header->offDtStrings);
BytePointer structs = (BytePointer)dtb + offStruct; BytePointer structs = (BytePointer)dtb + offStruct;
ASCII* strings = (ASCII*)dtb + offStrings; ASCII* strings = (ASCII*)dtb + offStrings;
ASCII* currentNode = ""; ASCII* currentNode = "";
UInt32 currentDepth = 0;
UInt32 reservedMemoryDepth = 0;
bool inReservedMemory = false;
while (true) { while (true) {
UInt32 token = BytesSwap32(*(UInt32*)structs); UInt32 token = BytesSwap32(*(UInt32*)structs);
@@ -24,35 +35,59 @@ void DTBParse(Pointer dtb) {
switch (token) { switch (token) {
case FDTTokenBeginNode: { case FDTTokenBeginNode: {
currentDepth++;
currentNode = (ASCII*)structs; currentNode = (ASCII*)structs;
if (StringStartsWith(currentNode, "reserved-memory")) {
inReservedMemory = true;
reservedMemoryDepth = currentDepth;
}
UInt32 nameLength = StringGetLength(currentNode); UInt32 nameLength = StringGetLength(currentNode);
structs += (nameLength + 1); structs += (nameLength + 1);
structs = (BytePointer)AlignUp64((Address)structs, 4); structs = (BytePointer)AlignUp64((Address)structs, 4);
break; break;
} }
case FDTTokenProperty: { case FDTTokenProperty: {
UInt32 propertyLength = BytesSwap32(*(UInt32*)structs); UInt32 propertyLength = BytesSwap32(*(UInt32*)structs);
UInt32 nameOffset = BytesSwap32(*(UInt32*)(structs + 4)); UInt32 nameOffset = BytesSwap32(*(UInt32*)(structs + 4));
structs += 8; structs += 8;
ASCII* propertyName = strings + nameOffset; ASCII* propertyName = strings + nameOffset;
if (StringCompare(propertyName, "reg") == 0 && StringStartsWith(currentNode, "memory")) {
UInt32* cells = (UInt32*)structs;
UInt64 base = Merge32To64(BytesSwap32(cells[0]), BytesSwap32(cells[1]));
UInt64 size = Merge32To64(BytesSwap32(cells[2]), BytesSwap32(cells[3]));
OSLog("Memory: base=0x%x, size=0x%x\n", base, size); if (StringCompare(propertyName, "reg") == 0) {
if (StringStartsWith(currentNode, "memory")) {
UInt32* cells = (UInt32*)structs;
Address base = Merge32To64(BytesSwap32(cells[1]), BytesSwap32(cells[0]));
Size size = Merge32To64(BytesSwap32(cells[3]), BytesSwap32(cells[2]));
bootMap->totalRAM.base = base;
bootMap->totalRAM.size = size;
}
else if (inReservedMemory && currentDepth > reservedMemoryDepth) {
UInt32* cells = (UInt32*)structs;
Address base = Merge32To64(BytesSwap32(cells[1]), BytesSwap32(cells[0]));
Size size = Merge32To64(BytesSwap32(cells[3]), BytesSwap32(cells[2]));
UInt32 index = bootMap->reservedCount;
bootMap->reserved[index].base = base;
bootMap->reserved[index].size = size;
bootMap->reservedCount++;
}
} }
structs += propertyLength; structs += propertyLength;
structs = (BytePointer)AlignUp64((Address)structs, 4); structs = (BytePointer)AlignUp64((Address)structs, 4);
break; break;
} }
case FDTTokenEndNode: break; case FDTTokenEndNode: {
if (inReservedMemory && currentDepth == reservedMemoryDepth) {
inReservedMemory = false;
}
currentDepth--;
break;
}
case FDTTokenNOP: continue; case FDTTokenNOP: continue;
case FDTTokenEnd: return; case FDTTokenEnd: return;
default: default:
+6 -2
View File
@@ -1,4 +1,5 @@
#include "../Common/bootinfo.h" #include "../Common/bootinfo.h"
#include <VM/PMM.h>
#include <Arch/DTB.h> #include <Arch/DTB.h>
#include <OS/Log.h> #include <OS/Log.h>
#include <OS/Panic.h> #include <OS/Panic.h>
@@ -8,6 +9,9 @@ void KernelMain(Bootinfo* bootinfo) {
if (bootinfo->magic != BOOTINFO_MAGIC) { if (bootinfo->magic != BOOTINFO_MAGIC) {
OSPanic("Invalid bootinfo magic"); OSPanic("Invalid bootinfo magic");
} }
DTBParse(bootinfo->dtb); VMBootMemoryMap bootMap = {0};
bootMap.reservedCount = 0;
DTBParse(bootinfo->dtb, &bootMap);
PMMInitialize(&bootMap);
} }
+6
View File
@@ -0,0 +1,6 @@
#include <Lib/Stubs.h>
#include <Lib/String.h>
void* memset(void* destination, int value, Size count) {
return StringSet(destination, value, count);
}
+83
View File
@@ -0,0 +1,83 @@
#include <VM/PMM.h>
#include <Lib/String.h>
extern char _kernelStart[];
extern char _kernelEnd[];
static inline Size BitmapGetByteIndex(Address address) {
return (address / kVMPageSize) / kVMBlocksPerByte;
}
static inline UInt8 BitmapGetBitOffset(Address address) {
return (UInt8)((address / kVMPageSize) % kVMBlocksPerByte);
}
static inline Boolean BitmapTest(const MemoryPointer bitmap, Address address) {
return (bitmap[BitmapGetByteIndex(address)] & (1U << BitmapGetBitOffset(address))) != 0;
}
static inline void BitmapSet(MemoryPointer bitmap, Address address) {
bitmap[BitmapGetByteIndex(address)] |= (1U << BitmapGetBitOffset(address));
}
static inline void BitmapUnset(MemoryPointer bitmap, Address address) {
bitmap[BitmapGetByteIndex(address)] &= ~(1U << BitmapGetBitOffset(address));
}
static MemoryPointer sPMMBitmap;
static Size sPMMBitmapSize;
static Size sPMMTotalPages;
void PMMInitialize(VMBootMemoryMap* bootMap) {
UInt32 vIndex = bootMap->reservedCount;
bootMap->reserved[vIndex].base = 0x0;
bootMap->reserved[vIndex].size = bootMap->totalRAM.base;
bootMap->reservedCount++;
UInt32 kIndex = bootMap->reservedCount;
bootMap->reserved[kIndex].base = (Address)_kernelStart;
bootMap->reserved[kIndex].size = (Address)_kernelEnd - (Address)_kernelStart;
bootMap->reservedCount++;
sPMMTotalPages = bootMap->totalRAM.size / kVMPageSize;
sPMMBitmapSize = sPMMTotalPages / kVMBlocksPerByte;
sPMMBitmap = (MemoryPointer)_kernelEnd;
StringSet(sPMMBitmap, 0, sPMMBitmapSize);
UInt32 bIndex = bootMap->reservedCount;
bootMap->reserved[bIndex].base = (Address)sPMMBitmap;
bootMap->reserved[bIndex].size = sPMMBitmapSize;
bootMap->reservedCount++;
for (Size i = 0; i < bootMap->reservedCount; i++) {
Address regionBase = bootMap->reserved[i].base;
Size regionSize = bootMap->reserved[i].size;
Size pagesToReserve = (regionSize + kVMPageSize - 1) / kVMPageSize;
for (Size p = 0; p < pagesToReserve; p++) {
Address pageAdress = regionBase + (p * kVMPageSize);
BitmapSet(sPMMBitmap, pageAdress);
}
}
}
Pointer PMMAllocatePage() {
for (Size i = 0; i < sPMMBitmapSize; i++) {
if (sPMMBitmap[i] == 0xFF) continue;
for (Size bit = 0; bit < kVMBlocksPerByte; bit++) {
if ((sPMMBitmap[i] & (1 << bit)) == 0) {
Address address = (i * kVMBlocksPerByte + bit) * kVMPageSize;
BitmapSet(sPMMBitmap, address);
return (Pointer)address;
}
}
}
return nullptr;
}
void PMMFreePage(Address address) {
BitmapUnset(sPMMBitmap, address);
}
+8
View File
@@ -7,14 +7,22 @@ PHDRS
SECTIONS SECTIONS
{ {
. = 0x40100000; . = 0x40100000;
_kernelStart = .;
.text : { .text : {
*(.text.boot) *(.text.boot)
*(.text*) *(.text*)
} :text } :text
. = ALIGN(8);
.rodata : { *(.rodata*) } :text .rodata : { *(.rodata*) } :text
. = ALIGN(4096);
.data : { *(.data*) } :data .data : { *(.data*) } :data
. = ALIGN(8);
.bss : { *(.bss*) *(COMMON) } :data .bss : { *(.bss*) *(COMMON) } :data
. = ALIGN(4096);
_kernelEnd = .;
} }