Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,15 @@ practices while remaining approachable to contributors and learners alike.
- [x] Halt loop
- [x] Basics of the kernel + GDT, IDT and interrupt handlers
- [x] PIC, timer and keyboard support
- [ ] Stack tracing support
- [x] Stack tracing support

### Memory

- [ ] Limine Memory map parsing
- [ ] Physical memory manager
- [ ] Virtual memory manager
- [ ] Kernel heap (malloc, free)
- [ ] Move to Limine 6 (APIC or x2APIC)
- [x] Limine Memory map parsing
- [x] Physical memory manager
- [x] Virtual memory manager
- [x] Kernel heap (malloc, free)
- [x] Create classes and helpers with the heap

### Internal Driver Framework

Expand All @@ -39,6 +39,7 @@ practices while remaining approachable to contributors and learners alike.
- [ ] Driver lifecycle
- [ ] MMIO port I/O helpers
- [ ] Block device abstraction
- [ ] Move to Limine 6 barely (APIC or x2APIC mapped to legacy PIC)

### Hardware discovery

Expand Down Expand Up @@ -81,7 +82,7 @@ practices while remaining approachable to contributors and learners alike.

- [ ] ACPI
- [ ] MADT parsing
- [ ] x2APIC
- [ ] x2APIC and APIC
- [ ] APIC timer
- [ ] IPIs

Expand Down
4 changes: 2 additions & 2 deletions include/graphics/framebuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ class FramebufferConsole {

void clear();
void putChar(char c);
void write(string str);
void writeLn(string str);
void write(cstring str);
void writeLn(cstring str);
void newline();
void backspace();
void backspace(char c);
Expand Down
4 changes: 2 additions & 2 deletions include/io/serial.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

namespace io {
void serialWriteChar(char c);
void serialWrite(string input);
void serialWrite(cstring input);
void serialWriteHex(u64 num);
void serialWriteNumber(u32 num);
void serialWriteNumber(u64 num);
}

#endif //AVERY_SERIAL_H
10 changes: 6 additions & 4 deletions include/kernel/console.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ extern FramebufferConsole* GlobalFramebufferConsole;
namespace out {
extern ConsoleOutputMode outputMode;
void initFramebufferConsole(const Framebuffer& framebuffer);
void print(string str);
void println(string str);
void print(cstring str);
void print(const string& str);
void println(cstring str);
void println(const string& str);
void printHex(u64 num);
void printNumber(u32 num);
void printNumber(u64 num);
void putChar(char c);
void clear();

Expand All @@ -42,7 +44,7 @@ namespace out {
};

namespace in {
string getLine(string prompt = nullptr);
string getLine(cstring prompt = nullptr);
char getChar();
}

Expand Down
21 changes: 21 additions & 0 deletions include/kernel/debug.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,23 @@ debug::error( \
} \
} while (0)

#define TEST_RESULT(expr) \
do \
{ \
if (expr) { \
out::setColor(Color::green, Color::blue); \
out::println("========================"); \
out::println("TEST SUCCEEDED"); \
out::setColor(Color::white, Color::blue); \
} \
else { \
out::setColor(Color::red, Color::blue); \
out::println("========================"); \
out::println("TEST FAILED"); \
out::setColor(Color::white, Color::blue); \
} \
} while (0)

#ifndef NDEBUG
#define ASSERT(expr) VERIFY(expr)
#else
Expand All @@ -66,6 +83,10 @@ namespace debug {
void warn(const char* message, LogType logType = LogType::Serial);
void error(const char* message, LogType logType = LogType::Serial);

inline void serialError(const char* message) {
error(message, LogType::Serial);
}

struct StackFrame {
StackFrame* rbp;
uptr rip;
Expand Down
62 changes: 61 additions & 1 deletion include/kernel/memory.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,69 @@ namespace memory {
}
}

void setHHDM(volatile limine_hhdm_request& request);
void setHHDM(volatile struct limine_hhdm_request& request);
u64 getHHDMOffset();
void initMemoryServices(volatile struct limine_memmap_request& request);

namespace heap {
void init();

void* allocate(u64 size);
void free(void* ptr);
void* realloc(void* ptr, u64 newSize);

u64 getUsedMemory();
u64 getFreeMemory();

struct HeapBlock {
u64 magic;
u64 size;
bool free;
HeapBlock* next;
HeapBlock* prev;
};

void splitBlock(HeapBlock* block, u64 size);
void mergeWithNext(HeapBlock* block);
HeapBlock* findFreeBlock(u64 size);
bool expandHeap(u64 size);
}

template <typename T>
T* allocElem(u64 count) {
return heap::allocate(sizeof(T) * count);
}

inline void* alloc(u64 size) {
return heap::allocate(size);
}

inline void free(void* ptr) {
heap::free(ptr);
}

inline void* calloc(u64 count, u64 size) {
return heap::allocate(count * size);
}

inline void* realloc(void* ptr, u64 newSize) {
return heap::realloc(ptr, newSize);
}

template <typename T, typename... Args>
UniquePtr<T> makeUnique(Args&&... args) {
return UniquePtr<T>(new T(static_cast<Args&&>(args)...));
}
}

void* operator new(usize size);
void* operator new[](usize size);

void operator delete(void* ptr) noexcept;
void operator delete[](void* ptr) noexcept;

void operator delete(void* ptr, usize size) noexcept;
void operator delete[](void* ptr, usize size) noexcept;


#endif //AVERY_MEMORY_H
93 changes: 93 additions & 0 deletions include/kernel/memory/physicalMemory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/*
* physicalMemory.h
* As part of the Avery project
* Created by Max Van den Eynde in 2026
* --------------------------------------
* Description: ${FILE_DESCRIPTION}
* Copyright (c) 2026 Max Van den Eynde
*/

#ifndef AVERY_PHYSICALMEMORY_H
#define AVERY_PHYSICALMEMORY_H

#define PAGE_SIZE 4096
#include "../../types.h"
#include "kernel/memory.h"

struct limine_memmap_request;

namespace pmm {
struct MemoryRegion {
physAddr base;
u64 length;
u64 type;
};

struct MemoryInfo {
u64 totalMemory;
u64 usableMemory;
u64 reservedMemory;
u64 pageCount;
};

struct PhysicalMemory {
u8* bitmap;
physAddr bitmapPhysicalAddress;
u64 bitmapSize;

u64 totalPages;
u64 usedPages;
u64 freePages;

physAddr highestAddress;
u64 lastAllocIndex;
};

extern PhysicalMemory physicalMemory;

void init(volatile limine_memmap_request& memmap);
void markUsed(physAddr addr, u64 pageCount);
void markFree(physAddr addr, u64 pageCount);

physAddr allocPage();
physAddr allocPages(u64 count);

void freePage(physAddr addr);
void freePages(physAddr addr, u64 count);

bool isFree(physAddr addr);
u64 getFreePages();
u64 getTotalPages();
u64 getUsedPages();
u64 getFreeMemory();

inline void* physicalToVirtual(physAddr p) {
return reinterpret_cast<void*>(p + memory::getHHDMOffset());
}

inline physAddr virtualToPhysicalHHDM(void* v) {
return reinterpret_cast<u64>(v) - memory::getHHDMOffset();
}

inline physAddr pageToPhysical(u64 page) {
return page * PAGE_SIZE;
}

inline u64 physicalToPage(physAddr addr) {
return addr / PAGE_SIZE;
}

inline void bitmapSet(u64 bit) {
physicalMemory.bitmap[bit / 8] |= (1 << (bit % 8));
}

inline void bitmapClear(u64 bit) {
physicalMemory.bitmap[bit / 8] &= ~(1 << (bit % 8));
}

inline bool bitmapTest(u64 bit) {
return physicalMemory.bitmap[bit / 8] & (1 << (bit % 8));
}
}

#endif //AVERY_PHYSICALMEMORY_H
47 changes: 47 additions & 0 deletions include/kernel/memory/virtualMemory.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
/*
* virtualMemory.h
* As part of the Avery project
* Created by Max Van den Eynde in 2026
* --------------------------------------
* Description: Virtual Memory Manager definitions
* Copyright (c) 2026 Max Van den Eynde
*/

#ifndef AVERY_VIRTUALMEMORY_H
#define AVERY_VIRTUALMEMORY_H
#include "../../types.h"

#define PAGE_ENTRIES 512


namespace vmm {
struct PageTable {
u64 entries[PAGE_ENTRIES];
};

constexpr u64 AddressMask = 0x000FFFFFFFFFF000ull;

constexpr u64 FlagPresent = 1ull << 0;
constexpr u64 FlagWritable = 1ull << 1;
constexpr u64 FlagUser = 1ull << 2;
constexpr u64 FlagNX = 1ull << 63;

void init();

PageTable* createAddressSpace();
void switchAddressSpace(PageTable* table);

bool mapPage(PageTable* pml4, virtAddr virt, physAddr phys, u64 flags);
bool unmapPage(PageTable* pml4, virtAddr virt);
bool mapRange(PageTable* pml4, virtAddr virt, physAddr phys, u64 size, u64 flags);

physAddr virtToPhysical(PageTable* pml4, virtAddr virt);

PageTable* newTable();
PageTable* getNextTable(PageTable* table, u64 index, bool create);
u64* getPte(PageTable* pml4, virtAddr virt, bool create);

PageTable* getKernelPml4();
}

#endif //AVERY_VIRTUALMEMORY_H
20 changes: 20 additions & 0 deletions include/tests.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* tests.h
* As part of the Avery project
* Created by Max Van den Eynde in 2026
* --------------------------------------
* Description: ${FILE_DESCRIPTION}
* Copyright (c) 2026 Max Van den Eynde
*/

#ifndef AVERY_TESTS_H
#define AVERY_TESTS_H

namespace tests {
void pmmTest();
void vmmTest();
void mallocTest();
void runAllMemoryTests();
}

#endif //AVERY_TESTS_H
Loading
Loading