commit 6d2e453d274c54b42dc2913429441ee279c9fc70
parent 0d3653c9700853e65ebaf570db9ab6bc870e7de3
Author: cowmonk <cowmonk@based.pt>
Date: Thu, 16 Oct 2025 13:53:36 -0700
Added Memory Paging + Formating Fixes
Memory paging was "fixed", there was previously a stub because I was
working out some compilation issue. Turns out, I had extern keyword
called to the structs. Stupidly, I forgot to declare the struct in the
header the whole time. Luckily that worked itself out, and now vga
memory is mapped.
Diffstat:
8 files changed, 456 insertions(+), 425 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -7,3 +7,4 @@ isodir/boot/limine/limine-bios-cd.bin
isodir/boot/limine/limine-uefi-cd.bin
isodir/EFI/BOOT/BOOTX64.EFI
isodir/EFI/BOOT/BOOTIA32.EFI
+compile_flags.txt
diff --git a/kernel/drivers/video/framebuffer.c b/kernel/drivers/video/framebuffer.c
@@ -7,279 +7,290 @@
static fb_console_t console;
-void fb_init(void)
+void
+fb_init(void)
{
- if (framebuffer_request.response == NULL ||
- framebuffer_request.response->framebuffer_count < 1) {
- return;
- }
-
- console.fb = framebuffer_request.response->framebuffers[0];
- console.fg_color = 0xFFFFFF; // White
- console.bg_color = 0x000000; // Black
- console.cursor_x = 0;
- console.cursor_y = 0;
- console.cols = console.fb->width / FB_CHAR_WIDTH;
- console.rows = console.fb->height / FB_CHAR_HEIGHT;
-
- fb_clear();
+ if (framebuffer_request.response == NULL ||
+ framebuffer_request.response->framebuffer_count < 1) {
+ return;
+ }
+
+ console.fb = framebuffer_request.response->framebuffers[0];
+ console.fg_color = 0xFFFFFF; // White
+ console.bg_color = 0x000000; // Black
+ console.cursor_x = 0;
+ console.cursor_y = 0;
+ console.cols = console.fb->width / FB_CHAR_WIDTH;
+ console.rows = console.fb->height / FB_CHAR_HEIGHT;
+
+ fb_clear();
}
-void fb_clear(void)
+void
+fb_clear(void)
{
- if (!console.fb) return;
-
- uint32_t *fb = (uint32_t *)console.fb->address;
- size_t pixels = (console.fb->pitch / 4) * console.fb->height;
-
- for (size_t i = 0; i < pixels; i++) {
- fb[i] = console.bg_color;
- }
-
- console.cursor_x = 0;
- console.cursor_y = 0;
+ if (!console.fb) return;
+
+ uint32_t *fb = (uint32_t *)console.fb->address;
+ size_t pixels = (console.fb->pitch / 4) * console.fb->height;
+
+ for (size_t i = 0; i < pixels; i++) {
+ fb[i] = console.bg_color;
+ }
+
+ console.cursor_x = 0;
+ console.cursor_y = 0;
}
-void fb_draw_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t color)
+void
+fb_draw_rect(uint32_t x, uint32_t y, uint32_t w, uint32_t h, uint32_t color)
{
- if (!console.fb) return;
-
- uint32_t *fb = (uint32_t *)console.fb->address;
- uint32_t pitch_pixels = console.fb->pitch / 4;
-
- for (uint32_t row = y; row < y + h && row < console.fb->height; row++) {
- for (uint32_t col = x; col < x + w && col < console.fb->width; col++) {
- fb[row * pitch_pixels + col] = color;
+ if (!console.fb) return;
+
+ uint32_t *fb = (uint32_t *)console.fb->address;
+ uint32_t pitch_pixels = console.fb->pitch / 4;
+
+ for (uint32_t row = y; row < y + h && row < console.fb->height; row++) {
+ for (uint32_t col = x; col < x + w && col < console.fb->width; col++) {
+ fb[row * pitch_pixels + col] = color;
+ }
}
- }
}
-void fb_set_color(uint32_t fg, uint32_t bg)
+void
+fb_set_color(uint32_t fg, uint32_t bg)
{
- console.fg_color = fg;
- console.bg_color = bg;
+ console.fg_color = fg;
+ console.bg_color = bg;
}
-static void draw_char(uint32_t x, uint32_t y, char c, uint32_t fg_color, uint32_t bg_color)
+static void
+draw_char(uint32_t x, uint32_t y, char c, uint32_t fg_color, uint32_t bg_color)
{
- if (!console.fb) return;
-
- uint32_t *fb = (uint32_t *)console.fb->address;
- uint32_t pitch_pixels = console.fb->pitch / 4;
-
- // Get the font data for this character
- const uint8_t *char_data = &IBM_VGA_8x16[c * 16];
-
- // Draw each row of the character
- for (uint32_t row = 0; row < FB_CHAR_HEIGHT; row++) {
- uint8_t font_row = char_data[row];
+ if (!console.fb) return;
+
+ uint32_t *fb = (uint32_t *)console.fb->address;
+ uint32_t pitch_pixels = console.fb->pitch / 4;
+
+ // Get the font data for this character
+ const uint8_t *char_data = &IBM_VGA_8x16[c * 16];
- // Draw each pixel in the row
- for (uint32_t col = 0; col < FB_CHAR_WIDTH; col++) {
- uint32_t px = x + col;
- uint32_t py = y + row;
-
- // Check bounds
- if (px >= console.fb->width || py >= console.fb->height) continue;
-
- // Check if this pixel should be set (bit test)
- if (font_row & (0x80 >> col)) {
- fb[py * pitch_pixels + px] = fg_color;
- } else {
- fb[py * pitch_pixels + px] = bg_color;
- }
+ // Draw each row of the character
+ for (uint32_t row = 0; row < FB_CHAR_HEIGHT; row++) {
+ uint8_t font_row = char_data[row];
+
+ // Draw each pixel in the row
+ for (uint32_t col = 0; col < FB_CHAR_WIDTH; col++) {
+ uint32_t px = x + col;
+ uint32_t py = y + row;
+
+ // Check bounds
+ if (px >= console.fb->width || py >= console.fb->height) continue;
+
+ // Check if this pixel should be set (bit test)
+ if (font_row & (0x80 >> col)) {
+ fb[py * pitch_pixels + px] = fg_color;
+ } else {
+ fb[py * pitch_pixels + px] = bg_color;
+ }
+ }
}
- }
}
-static void scroll_up(void)
+static void
+scroll_up(void)
{
- if (!console.fb) return;
-
- uint32_t *fb = (uint32_t *)console.fb->address;
- uint32_t pitch_pixels = console.fb->pitch / 4;
-
- // Move all lines up by one character height
- for (uint32_t y = 0; y < console.fb->height - FB_CHAR_HEIGHT; y++) {
- for (uint32_t x = 0; x < console.fb->width; x++) {
- fb[y * pitch_pixels + x] = fb[(y + FB_CHAR_HEIGHT) * pitch_pixels + x];
+ if (!console.fb) return;
+
+ uint32_t *fb = (uint32_t *)console.fb->address;
+ uint32_t pitch_pixels = console.fb->pitch / 4;
+
+ // Move all lines up by one character height
+ for (uint32_t y = 0; y < console.fb->height - FB_CHAR_HEIGHT; y++) {
+ for (uint32_t x = 0; x < console.fb->width; x++) {
+ fb[y * pitch_pixels + x] = fb[(y + FB_CHAR_HEIGHT) * pitch_pixels + x];
+ }
}
- }
-
- // Clear the last line
- for (uint32_t y = console.fb->height - FB_CHAR_HEIGHT; y < console.fb->height; y++) {
- for (uint32_t x = 0; x < console.fb->width; x++) {
- fb[y * pitch_pixels + x] = console.bg_color;
+
+ // Clear the last line
+ for (uint32_t y = console.fb->height - FB_CHAR_HEIGHT; y < console.fb->height; y++) {
+ for (uint32_t x = 0; x < console.fb->width; x++) {
+ fb[y * pitch_pixels + x] = console.bg_color;
+ }
}
- }
}
-void fb_putchar(char c)
+void
+fb_putchar(char c)
{
- if (!console.fb) return;
-
- // Handle special characters
- switch (c) {
- case '\n':
- console.cursor_x = 0;
- console.cursor_y++;
- break;
- case '\r':
- console.cursor_x = 0;
- break;
- case '\t':
- console.cursor_x = (console.cursor_x + 8) & ~7;
- break;
- case '\b':
- if (console.cursor_x > 0) {
- console.cursor_x--;
- draw_char(console.cursor_x * FB_CHAR_WIDTH,
- console.cursor_y * FB_CHAR_HEIGHT,
- ' ', console.fg_color, console.bg_color);
- }
- break;
- default:
- // Draw the character
- draw_char(console.cursor_x * FB_CHAR_WIDTH,
- console.cursor_y * FB_CHAR_HEIGHT,
- c, console.fg_color, console.bg_color);
- console.cursor_x++;
- break;
- }
-
- // Handle line wrapping
- if (console.cursor_x >= console.cols) {
- console.cursor_x = 0;
- console.cursor_y++;
- }
-
- // Handle scrolling
- if (console.cursor_y >= console.rows) {
- scroll_up();
- console.cursor_y = console.rows - 1;
- }
+ if (!console.fb) return;
+
+ // Handle special characters
+ switch (c) {
+ case '\n':
+ console.cursor_x = 0;
+ console.cursor_y++;
+ break;
+ case '\r':
+ console.cursor_x = 0;
+ break;
+ case '\t':
+ console.cursor_x = (console.cursor_x + 8) & ~7;
+ break;
+ case '\b':
+ if (console.cursor_x > 0) {
+ console.cursor_x--;
+ draw_char(console.cursor_x * FB_CHAR_WIDTH,
+ console.cursor_y * FB_CHAR_HEIGHT,
+ ' ', console.fg_color, console.bg_color);
+ }
+ break;
+ default:
+ // Draw the character
+ draw_char(console.cursor_x * FB_CHAR_WIDTH,
+ console.cursor_y * FB_CHAR_HEIGHT,
+ c, console.fg_color, console.bg_color);
+ console.cursor_x++;
+ break;
+ }
+
+ // Handle line wrapping
+ if (console.cursor_x >= console.cols) {
+ console.cursor_x = 0;
+ console.cursor_y++;
+ }
+
+ // Handle scrolling
+ if (console.cursor_y >= console.rows) {
+ scroll_up();
+ console.cursor_y = console.rows - 1;
+ }
}
-void fb_puts(const char *str)
+void
+fb_puts(const char *str)
{
- while (*str) {
- fb_putchar(*str++);
- }
+ while (*str) {
+ fb_putchar(*str++);
+ }
}
-static void print_number(unsigned long num, int base, int width, char pad)
+static void
+print_number(unsigned long num, int base, int width, char pad)
{
- char digits[] = "0123456789ABCDEF";
- char buffer[32];
- int pos = 0;
-
- // Convert number to string (reversed)
- if (num == 0) {
- buffer[pos++] = '0';
- } else {
- while (num > 0) {
- buffer[pos++] = digits[num % base];
- num /= base;
+ char digits[] = "0123456789ABCDEF";
+ char buffer[32];
+ int pos = 0;
+
+ // Convert number to string (reversed)
+ if (num == 0) {
+ buffer[pos++] = '0';
+ } else {
+ while (num > 0) {
+ buffer[pos++] = digits[num % base];
+ num /= base;
+ }
+ }
+
+ // Add padding if needed
+ while (pos < width) {
+ buffer[pos++] = pad;
+ }
+
+ // Print reversed
+ while (pos > 0) {
+ fb_putchar(buffer[--pos]);
}
- }
-
- // Add padding if needed
- while (pos < width) {
- buffer[pos++] = pad;
- }
-
- // Print reversed
- while (pos > 0) {
- fb_putchar(buffer[--pos]);
- }
}
-static void print_signed(long num, int width, char pad)
+static void
+print_signed(long num, int width, char pad)
{
- if (num < 0) {
- fb_putchar('-');
- print_number(-num, 10, width, pad);
- } else {
- print_number(num, 10, width, pad);
- }
+ if (num < 0) {
+ fb_putchar('-');
+ print_number(-num, 10, width, pad);
+ } else {
+ print_number(num, 10, width, pad);
+ }
}
-void fb_printf(const char *fmt, ...)
+void
+fb_printf(const char *fmt, ...)
{
- va_list args;
- va_start(args, fmt);
-
- while (*fmt) {
- if (*fmt == '%') {
- fmt++;
-
- // Handle width and padding
- char pad = ' ';
- int width = 0;
-
- if (*fmt == '0') {
- pad = '0';
- fmt++;
- }
-
- while (*fmt >= '0' && *fmt <= '9') {
- width = width * 10 + (*fmt - '0');
- fmt++;
- }
-
- // Handle format specifiers
- switch (*fmt) {
- case 'd':
- case 'i':
- print_signed(va_arg(args, int), width, pad);
- break;
-
- case 'u':
- print_number(va_arg(args, unsigned int), 10, width, pad);
- break;
-
- case 'x':
- print_number(va_arg(args, unsigned int), 16, width, pad);
- break;
-
- case 'X':
- print_number(va_arg(args, unsigned int), 16, width, pad);
- break;
-
- case 'p':
- fb_puts("0x");
- print_number((unsigned long)va_arg(args, void*), 16, 16, '0');
- break;
-
- case 'c':
- fb_putchar(va_arg(args, int));
- break;
-
- case 's':
- {
- const char *str = va_arg(args, const char*);
- if (str) {
- fb_puts(str);
- } else {
- fb_puts("(null)");
+ va_list args;
+ va_start(args, fmt);
+
+ while (*fmt) {
+ if (*fmt == '%') {
+ fmt++;
+
+ // Handle width and padding
+ char pad = ' ';
+ int width = 0;
+
+ if (*fmt == '0') {
+ pad = '0';
+ fmt++;
}
- }
- break;
-
- case '%':
- fb_putchar('%');
- break;
-
- default:
- fb_putchar('%');
- fb_putchar(*fmt);
- break;
- }
- } else {
- fb_putchar(*fmt);
+
+ while (*fmt >= '0' && *fmt <= '9') {
+ width = width * 10 + (*fmt - '0');
+ fmt++;
+ }
+
+ // Handle format specifiers
+ switch (*fmt) {
+ case 'd':
+ case 'i':
+ print_signed(va_arg(args, int), width, pad);
+ break;
+
+ case 'u':
+ print_number(va_arg(args, unsigned int), 10, width, pad);
+ break;
+
+ case 'x':
+ print_number(va_arg(args, unsigned int), 16, width, pad);
+ break;
+
+ case 'X':
+ print_number(va_arg(args, unsigned int), 16, width, pad);
+ break;
+
+ case 'p':
+ fb_puts("0x");
+ print_number((unsigned long)va_arg(args, void*), 16, 16, '0');
+ break;
+
+ case 'c':
+ fb_putchar(va_arg(args, int));
+ break;
+
+ case 's':
+ {
+ const char *str = va_arg(args, const char*);
+ if (str) {
+ fb_puts(str);
+ } else {
+ fb_puts("(null)");
+ }
+ }
+ break;
+
+ case '%':
+ fb_putchar('%');
+ break;
+
+ default:
+ fb_putchar('%');
+ fb_putchar(*fmt);
+ break;
+ }
+ } else {
+ fb_putchar(*fmt);
+ }
+ fmt++;
}
- fmt++;
- }
-
- va_end(args);
+
+ va_end(args);
}
diff --git a/kernel/drivers/video/vga.c b/kernel/drivers/video/vga.c
@@ -4,69 +4,69 @@
static inline void
outb(uint16_t port, uint8_t val)
{
- __asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
+ __asm__ volatile ("outb %0, %1" : : "a"(val), "Nd"(port));
}
static inline uint8_t
inb(uint16_t port)
{
- uint8_t ret;
- __asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
- return ret;
+ uint8_t ret;
+ __asm__ volatile ("inb %1, %0" : "=a"(ret) : "Nd"(port));
+ return ret;
}
// Write vga registers for mode change
static void
write_regs(uint8_t *regs)
{
- unsigned i;
-
- // Write misc output register
- outb(VGA_MISC_WRITE, *regs);
- regs++;
-
- // Write sequencer registers (5 registers)
- for (i = 0; i < 5; i++) {
- outb(VGA_SEQ_INDEX, i);
- outb(VGA_SEQ_DATA, *regs);
- regs++;
- }
-
- // Unlock CRTC registers 0-7 by clearing protect bit
- outb(VGA_CRTC_INDEX, 0x03);
- outb(VGA_CRTC_DATA, inb(VGA_CRTC_DATA) | 0x80);
- outb(VGA_CRTC_INDEX, 0x11);
- outb(VGA_CRTC_DATA, inb(VGA_CRTC_DATA) & ~0x80);
-
- // Update the register values to match
- regs[0x03] = regs[0x03] | 0x80;
- regs[0x11] = regs[0x11] & ~0x80;
-
- // Write CRTC registers (25 registers)
- for (i = 0; i < 25; i++) {
- outb(VGA_CRTC_INDEX, i);
- outb(VGA_CRTC_DATA, *regs);
- regs++;
- }
-
- // Write graphics controller registers (9 registers)
- for (i = 0; i < 9; i++) {
- outb(VGA_GC_INDEX, i);
- outb(VGA_GC_DATA, *regs);
- regs++;
- }
-
- // Write attribute controller registers (21 registers)
- for (i = 0; i < 21; i++) {
- inb(VGA_INSTAT_READ); // Reset flip-flop
- outb(VGA_AC_INDEX, i);
- outb(VGA_AC_WRITE, *regs);
- regs++;
- }
-
- // Enable video display
- inb(VGA_INSTAT_READ);
- outb(VGA_AC_INDEX, 0x20);
+ unsigned i;
+
+ // Write misc output register
+ outb(VGA_MISC_WRITE, *regs);
+ regs++;
+
+ // Write sequencer registers (5 registers)
+ for (i = 0; i < 5; i++) {
+ outb(VGA_SEQ_INDEX, i);
+ outb(VGA_SEQ_DATA, *regs);
+ regs++;
+ }
+
+ // Unlock CRTC registers 0-7 by clearing protect bit
+ outb(VGA_CRTC_INDEX, 0x03);
+ outb(VGA_CRTC_DATA, inb(VGA_CRTC_DATA) | 0x80);
+ outb(VGA_CRTC_INDEX, 0x11);
+ outb(VGA_CRTC_DATA, inb(VGA_CRTC_DATA) & ~0x80);
+
+ // Update the register values to match
+ regs[0x03] = regs[0x03] | 0x80;
+ regs[0x11] = regs[0x11] & ~0x80;
+
+ // Write CRTC registers (25 registers)
+ for (i = 0; i < 25; i++) {
+ outb(VGA_CRTC_INDEX, i);
+ outb(VGA_CRTC_DATA, *regs);
+ regs++;
+ }
+
+ // Write graphics controller registers (9 registers)
+ for (i = 0; i < 9; i++) {
+ outb(VGA_GC_INDEX, i);
+ outb(VGA_GC_DATA, *regs);
+ regs++;
+ }
+
+ // Write attribute controller registers (21 registers)
+ for (i = 0; i < 21; i++) {
+ inb(VGA_INSTAT_READ); // Reset flip-flop
+ outb(VGA_AC_INDEX, i);
+ outb(VGA_AC_WRITE, *regs);
+ regs++;
+ }
+
+ // Enable video display
+ inb(VGA_INSTAT_READ);
+ outb(VGA_AC_INDEX, 0x20);
}
void
@@ -75,22 +75,22 @@ vga_set_mode_13h(void)
// Register values for VGA mode 13h (320x200, 256 colors)
// Order: Misc, Seq[5], CRTC[25], GC[9], AC[21]
static uint8_t mode_320x200x256[] = {
- // Misc output register
- 0x63,
- // Sequencer registers
- 0x03, 0x01, 0x0F, 0x00, 0x0E,
- // CRTC registers
- 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
- 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
- 0xFF,
- // Graphics controller registers
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
- 0xFF,
- // Attribute controller registers
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
- 0x41, 0x00, 0x0F, 0x00, 0x00
+ // Misc output register
+ 0x63,
+ // Sequencer registers
+ 0x03, 0x01, 0x0F, 0x00, 0x0E,
+ // CRTC registers
+ 0x5F, 0x4F, 0x50, 0x82, 0x54, 0x80, 0xBF, 0x1F,
+ 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x9C, 0x0E, 0x8F, 0x28, 0x40, 0x96, 0xB9, 0xA3,
+ 0xFF,
+ // Graphics controller registers
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F,
+ 0xFF,
+ // Attribute controller registers
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
+ 0x41, 0x00, 0x0F, 0x00, 0x00
};
write_regs(mode_320x200x256);
@@ -113,6 +113,6 @@ vga_clear_screen(uint8_t color)
uint8_t *vga = (uint8_t *)VGA_GRAPHICS_BUFFER;
// fill entire buffer (64k pixels)
for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) {
- vga[i] = color;
+ vga[i] = color;
}
}
diff --git a/kernel/include/mm/paging.h b/kernel/include/mm/paging.h
@@ -0,0 +1,11 @@
+#ifndef PAGING_H
+#define PAGING_H
+
+#include <limine.h>
+
+volatile struct limine_hhdm_request hhdm_request;
+volatile struct limine_kernel_address_request kernel_address_request;
+
+void map_vga_memory(void);
+
+#endif /* ifndef PAGING_H */
diff --git a/kernel/init/kernel.c b/kernel/init/kernel.c
@@ -3,6 +3,7 @@
#include <stddef.h>
#include <bootloader.h>
#include <drivers/video/framebuffer.h>
+#include <mm/paging.h>
static void
hcf(void)
@@ -20,6 +21,7 @@ kernel_main(void)
/* Initialize framebuffer console */
fb_init();
+ map_vga_memory();
/* Test print */
fb_puts("Hello World\n");
diff --git a/kernel/klibc/string.c b/kernel/klibc/string.c
@@ -1,4 +1,4 @@
-#include <string.h>
+#include <klibc/string.h>
size_t
strlen(const char* str)
diff --git a/kernel/mm/paging.c b/kernel/mm/paging.c
@@ -0,0 +1,125 @@
+#include <stdint.h>
+#include <stddef.h>
+#include <limine.h>
+#include <mm/paging.h>
+
+#define PAGE_PRESENT (1ULL << 0)
+#define PAGE_WRITABLE (1ULL << 1)
+#define PAGE_USER (1ULL << 2)
+#define PAGE_SIZE_2MB (1ULL << 7)
+#define PAGE_SIZE 4096
+
+// Get hhdm offset
+extern volatile struct limine_hhdm_request hhdm_request;
+extern volatile struct limine_kernel_address_request kernel_address_request;
+
+// Static storage for page tables
+static uint64_t pdpt[512] __attribute__((aligned(4096)));
+static uint64_t pd[512] __attribute__((aligned(4096)));
+
+// Get current cr3 value (PML address)
+static uint64_t
+get_cr3(void)
+{
+ uint64_t cr3;
+ __asm__ volatile("mov %%cr3, %0" : "=r"(cr3));
+ return cr3;
+}
+
+// Set cr3 to flush TLB
+static void
+set_cr3(uint64_t cr3)
+{
+ __asm__ volatile("mov %0, %%cr3" : : "r"(cr3) : "memory");
+}
+
+// Convert physical address to virt address using hhdm
+static void*
+phys_to_virt(uint64_t phys)
+{
+ if (hhdm_request.response == NULL) {
+ // Fallback if hhdm is not available
+ return (void *)(phys + 0xffff800000000000ULL);
+ }
+ return (void *)(phys + hhdm_request.response->offset);
+}
+
+// Convert virt address to physical address
+static uint64_t
+virt_to_phys(void *virt)
+{
+ uint64_t addr = (uint64_t)virt;
+
+ // Check if this is a kernel address
+ if (kernel_address_request.response != NULL) {
+ uint64_t kernel_virt_base = kernel_address_request.response->virtual_base;
+ uint64_t kernel_phys_base = kernel_address_request.response->physical_base;
+
+ // If address is in kernel space, convert using kernel base
+ if (addr >= kernel_virt_base && addr < kernel_virt_base + 0x200000) {
+ return kernel_phys_base + (addr - kernel_virt_base);
+ }
+ }
+
+ // Otherwise, in hhdm range
+ if (hhdm_request.response == NULL) {
+ // Fallback to default if hhdm not avail
+ return (addr - 0xffff800000000000ULL);
+ }
+ return (addr - hhdm_request.response->offset);
+}
+
+void
+map_vga_memory(void)
+{
+ // Get current PML4 from cr3
+ uint64_t cr3 = get_cr3();
+ uint64_t *pml4 = (uint64_t *)phys_to_virt(cr3 & ~0xFFF);
+
+ // VGA memory starts at 0xA0000 (640KB)
+ // Map entire lower 1MB region for simplcity
+
+ /* For address 0xA0000:
+ * PML4 index = 0 (bits 47-39)
+ * PDPT index = 0 (bits 38-30)
+ * PD index = 0 (bits 29-21)
+ * PT index = 160 (0xA0) (bits 20-12)
+ */
+
+ // Check if PML4[0] is present
+ if (!(pml4[0] & PAGE_PRESENT)) {
+ // Clear PDPT
+ for (int i = 0; i < 512; i++) {
+ pdpt[i] = 0;
+ }
+ // Install PDPT (use physical address)
+ pml4[0] = virt_to_phys(pdpt) | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
+ }
+
+ // Get PDPT (convert physical address from entry to virt for access)
+ uint64_t *pdpt_ptr = (uint64_t *)phys_to_virt(pml4[0] & ~0xFFF);
+
+ // Check if PDPT[0] is present
+ if (!(pdpt_ptr[0] & PAGE_PRESENT)) {
+ // Clear pd
+ for (int i = 0; i < 512; i++) {
+ pd[i] = 0;
+ }
+ // Install pd (use physical address)
+ pdpt_ptr[0] = virt_to_phys(pd) | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
+ }
+
+ // Get pd (convert physical address from entry to virt for access)
+ uint64_t *pd_ptr = (uint64_t *)phys_to_virt(pdpt_ptr[0] & ~0xFFF);
+
+ // Check if we can use 2MB pages
+ if (!(pd_ptr[0] & PAGE_PRESENT)) {
+ // Map the first 2MB as a large page (0x0 - 0x200000)
+ // This include VGA memory at 0xA0000-0xBFFFF
+ pd_ptr[0] = 0x0 | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER | PAGE_SIZE_2MB;
+ }
+
+ // Flush TLB
+ set_cr3(cr3);
+
+}
diff --git a/kernel/mm/paging.stub b/kernel/mm/paging.stub
@@ -1,119 +0,0 @@
-#include <stdint.h>
-#include <stddef.h>
-#include <limine.h>
-
-#define PAGE_PRESENT (1ULL << 0)
-#define PAGE_WRITABLE (1ULL << 1)
-#define PAGE_USER (1ULL << 2)
-#define PAGE_SIZE_2MB (1ULL << 7)
-#define PAGE_SIZE 4096
-
-// Get hhdm offset
-extern volatile struct limine_hhdm_request hhdm_request;
-extern volatile struct limine_kernel_address_request kernel_address_request;
-
-// Static storage for page tables
-static uint64_t pdpt[512] __attribute__((aligned(4096)));
-static uint64_t pd[512] __attribute__((aligned(4096)));
-
-// Get current cr3 value (PML address)
-static uint64_t get_cr3(void)
-{
- uint64_t cr3;
- __asm__ volatile("mov %%cr3, %0" : "=r"(cr3));
- return cr3;
-}
-
-// Set cr3 to flush TLB
-static void set_cr3(uint64_t cr3)
-{
- __asm__ volatile("mov %0, %%cr3" : : "r"(cr3) : "memory");
-}
-
-// Convert physical address to virt address using hhdm
-static inline void *phys_to_virt(uint64_t phys)
-{
- if (hhdm_request.response == NULL) {
- // Fallback if hhdm is not available
- return (void *)(phys + 0xffff800000000000ULL);
- }
- return (void *)(phys + hhdm_request.response->offset);
-}
-
-// Convert virt address to physical address
-static inline uint64_t virt_to_phys(void *virt)
-{
- uint64_t addr = (uint64_t)virt;
-
- // Check if this is a kernel address
- if (kernel_address_request.response != NULL) {
- uint64_t kernel_virt_base = kernel_address_request.response->virtual_base;
- uint64_t kernel_phys_base = kernel_address_request.response->physical_base;
-
- // If address is in kernel space, convert using kernel base
- if (addr >= kernel_virt_base && addr < kernel_virt_base + 0x200000) {
- return kernel_phys_base + (addr - kernel_virt_base);
- }
- }
-
- // Otherwise, in hhdm range
- if (hhdm_request.response == NULL) {
- // Fallback to default if hhdm not avail
- return (addr - 0xffff800000000000ULL);
- }
- return (addr - hhdm_request.response->offset);
-}
-
-void map_vga_memory(void)
-{
- // Get current PML4 from cr3
- uint64_t cr3 = get_cr3();
- uint64_t *pml4 = (uint64_t *)phys_to_virt(cr3 & ~0xFFF);
-
- // VGA memory starts at 0xA0000 (640KB)
- // Map entire lower 1MB region for simplcity
-
- /* For address 0xA0000:
- * PML4 index = 0 (bits 47-39)
- * PDPT index = 0 (bits 38-30)
- * PD index = 0 (bits 29-21)
- * PT index = 160 (0xA0) (bits 20-12)
- */
-
- // Check if PML4[0] is present
- if (!(pml4[0] & PAGE_PRESENT)) {
- // Clear PDPT
- for (int i = 0; i < 512; i++) {
- pdpt[i] = 0;
- }
- // Install PDPT (use physical address)
- pml4[0] = virt_to_phys(pdpt) | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
- }
-
- // Get PDPT (convert physical address from entry to virt for access)
- uint64_t *pdpt_ptr = (uint64_t *)phys_to_virt(pml4[0] & ~0xFFF);
-
- // Check if PDPT[0] is present
- if (!(pdpt_ptr[0] & PAGE_PRESENT)) {
- // Clear pd
- for (int i = 0; i < 512; i++) {
- pd[i] = 0;
- }
- // Install pd (use physical address)
- pdpt_ptr[0] = virt_to_phys(pd) | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER;
- }
-
- // Get pd (convert physical address from entry to virt for access)
- uint64_t *pd_ptr = (uint64_t *)phys_to_virt(pdpt_ptr[0] & ~0xFFF);
-
- // Check if we can use 2MB pages
- if (!(pd_ptr[0] & PAGE_PRESENT)) {
- // Map the first 2MB as a large page (0x0 - 0x200000)
- // This include VGA memory at 0xA0000-0xBFFFF
- pd_ptr[0] = 0x0 | PAGE_PRESENT | PAGE_WRITABLE | PAGE_USER | PAGE_SIZE_2MB;
- }
-
- // Flush TLB
- set_cr3(cr3);
-
-}