feat: heap, dbg command (currently heap test there)

This commit is contained in:
Karina
2025-12-29 08:41:51 +04:00
parent 6bfce3c866
commit db9b7cdbd5
14 changed files with 294 additions and 15 deletions
+1
View File
@@ -14,6 +14,7 @@ SG_Point console_get_dimensions();
void console_set_color(u32 color);
void console_set_default_color(u32 color);
void console_set_cursor_pos(SG_Point *p);
char console_getc();
void kprint(const char *str);
void kprintf(const char *fmt, ...);
void kgets(char* buff, u32 lim);
+28
View File
@@ -0,0 +1,28 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#ifndef HEAP_H
#define HEAP_H
#include <types.h>
#define KERNEL_HEAP_START 0xFFFFFFFFC0000000
#define PHYS_TO_HEAP(phys) ((phys) + KERNEL_HEAP_START)
#define HEAP_TO_PHYS(phys) ((phys) - KERNEL_HEAP_START)
#define HEADER_MAGIC 0x1CE
typedef struct block_header {
u64 magic;
struct block_header* next;
struct block_header* prev;
u64 size;
bool is_free;
} block_header;
void heap_init();
void* malloc(u64 size);
void free(void* ptr);
void* realloc(void* ptr, u64 new_size);
#endif
+2 -1
View File
@@ -6,6 +6,7 @@
#include <types.h>
void *memset(void *ptr, int value, usize num);
void* memset(void* ptr, int value, usize num);
void* memcpy(void* dest, const void* src, u64 n);
#endif
+3 -1
View File
@@ -31,11 +31,13 @@
#define KERNEL_VMA 0xFFFFFFFF80000000
#define HHDM_OFFSET 0xFFFF888000000000
#define FB_VIRT_BASE 0xFFFFFFFFFC000000
#define KERNEL_VIRT_TO_PHYS(virt) ((virt) - KERNEL_VMA)
#define PHYS_TO_HHDM(phys) ((phys) + HHDM_OFFSET)
#define HHDM_TO_PHYS(virt) ((virt) - HHDM_OFFSET)
void vmm_init(Bootinfo* info);
void vmm_map_page(u64* pml4, u64 phys, u64 virt, u64 flags);
u64* vmm_map_page(u64* pml4, u64 phys, u64 virt, u64 flags);
#endif
+1
View File
@@ -10,6 +10,7 @@ void cmd_help();
void cmd_regs();
void print_regs();
void cmd_sleep();
void cmd_debug();
int rectest(int a);
#endif
+9
View File
@@ -0,0 +1,9 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#ifndef DBGCMD_H
#define DBGCMD_H
void debug();
#endif
+1 -1
View File
@@ -234,7 +234,7 @@ void console_set_default_color(u32 color) {
s_def_color = color;
}
static char console_getc() {
char console_getc() {
while (kb_buf.head == kb_buf.tail) __asm__ volatile ("sti; hlt");
__asm__ volatile ("cli");
char temp = kb_buf.buffer[kb_buf.tail];
+13 -8
View File
@@ -2,7 +2,6 @@
// Copyright (c) 2025 0xKarinyash
#include "bootinfo.h"
#include "drivers/timer.h"
#include <shell/ksh.h>
#include <types.h>
@@ -10,6 +9,7 @@
#include <drivers/shitgui.h>
#include <drivers/serial.h>
#include <drivers/console.h>
#include <drivers/timer.h>
#include <core/panic.h>
#include <core/splash.h>
@@ -17,8 +17,10 @@
#include <gdt.h>
#include <idt.h>
#include <pic.h>
#include <mm/pmm.h>
#include <mm/vmm.h>
#include <mm/heap.h>
#define FG_COLOR 0xffffff
#define BG_COLOR 0x111111
@@ -30,18 +32,22 @@ void kmain(Bootinfo* info) {
serial_init();
serial_write("Kernel started\n");
console_init(&sg_ctx);
gdt_init();
serial_write("GDT initialized\n");
kprintf("GDT initialized\n");
idt_init();
serial_write("IDT initialized\n");
kprintf("IDT initialized\n");
pic_remap();
serial_write("PIC remapped\n");
kprintf("PIC remapped\n");
pmm_init(&info->mem);
serial_write("PMM initialized\n");
kprintf("PMM initialized\n");
vmm_init(info);
serial_write("VMM initialized\n");
kprintf("VMM initialized\n");
timer_init(1000);
serial_write("Timer initialized\n");
kprintf("Timer initialized\n");
heap_init();
kprintf("Heap initialized\n");
info = (Bootinfo*)PHYS_TO_HHDM((u64)info);
@@ -53,7 +59,6 @@ void kmain(Bootinfo* info) {
sg_ctx.width = info->framebuffer.width;
sg_ctx.pitch = info->framebuffer.pitch;
console_init(&sg_ctx);
console_clear(BG_COLOR);
console_set_color(FG_COLOR);
console_set_default_color(FG_COLOR);
+105
View File
@@ -0,0 +1,105 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
#include <mm/heap.h>
#include <mm/pmm.h>
#include <mm/vmm.h>
#include <mm/memory.h>
#include <core/panic.h>
#include <types.h>
#define HEAP_SIZE_PAGES 32
extern u64* pml4_kernel;
static block_header* heap_list_head = nullptr;
void combine_forward(block_header* curr) {
if (!curr->next || !curr->next->is_free) return;
curr->size += sizeof(block_header) + curr->next->size;
curr->next = curr->next->next;
if (curr->next) curr->next->prev = curr; // what the fuck
}
void heap_init() {
u64 heap_start = KERNEL_HEAP_START;
for (u64 i = 0; i < HEAP_SIZE_PAGES; i++) {
u64 phys = (u64)pmm_alloc_page();
if (!phys) panic("OOM during heap init");
u64 virt = heap_start + (i * PAGE_SIZE);
vmm_map_page(pml4_kernel, phys, virt, PTE_PRESENT | PTE_RW);
}
heap_list_head = (block_header*)heap_start;
heap_list_head->magic = HEADER_MAGIC;
heap_list_head->size = (HEAP_SIZE_PAGES * PAGE_SIZE) - sizeof(block_header);
heap_list_head->is_free = true;
heap_list_head->next = nullptr;
heap_list_head->prev = nullptr;
}
void* malloc(u64 size) {
if (size == 0) return nullptr;
u64 aligned_size = (size + 15) & ~15;
block_header* curr = heap_list_head;
while (curr) {
if (curr->is_free && curr->size >= aligned_size) {
if (curr->size > aligned_size + sizeof(block_header) + 16) {
block_header* new_block = (block_header*)((u64)curr + sizeof(block_header) + aligned_size);
new_block->size = curr->size - aligned_size - sizeof(block_header);
new_block->is_free = true;
new_block->next = curr->next;
new_block->prev = curr;
new_block->magic = HEADER_MAGIC;
if (curr->next) curr->next->prev = new_block;
curr->next = new_block;
curr->size = aligned_size;
}
curr->is_free = false;
return (void*)((u64)curr + sizeof(block_header));
}
curr = curr->next;
}
return nullptr;
}
void free(void* ptr) {
if (!ptr) return;
block_header* curr = (block_header*)((u64)ptr - sizeof(block_header));
if (curr->magic != HEADER_MAGIC) return;
curr->is_free = true;
if (curr->next && curr->next->is_free) combine_forward(curr);
if (curr->prev && curr->prev->is_free) combine_forward(curr->prev);
}
void* realloc(void* ptr, u64 new_size) {
if (!ptr) return malloc(new_size);
if (new_size == 0) {
free(ptr);
return nullptr;
}
block_header* curr = (block_header*)((u64)ptr - sizeof(block_header));
if (curr->size >= new_size) return ptr;
if (curr->next &&
curr->next->is_free &&
(curr->size + sizeof(block_header) + curr->next->size) >= new_size) { // why ts shit so fucking unreadable
combine_forward(curr);
return ptr;
}
void* new_ptr = malloc(new_size);
if (!new_ptr) return nullptr;
memcpy(new_ptr, ptr, curr->size);
free(ptr);
return new_ptr;
}
+19
View File
@@ -10,4 +10,23 @@ void *memset(void *ptr, int value, usize num) {
*p++ = (u8)value;
}
return ptr;
}
void* memcpy(void* dest, const void* src, u64 n) {
u8* d = (u8*)dest;
const u8* s = (const u8*)src;
while (n >= 8) {
*(u64*)d = *(const u64*)s;
d += 8;
s += 8;
n -= 8;
}
while (n > 0) {
*d++ = *s++;
n--;
}
return dest;
}
+14 -4
View File
@@ -28,24 +28,29 @@ static u64* get_table_virt(u64 phys) {
return (u64*)phys;
}
void vmm_map_page(u64* pml4, u64 phys, u64 virt, u64 flags) {
u64* vmm_map_page(u64* pml4, u64 phys, u64 virt, u64 flags) {
u64 pt_idx = VMM_PT_INDEX(virt);
u64 pd_idx = VMM_PD_INDEX(virt);
u64 pdpt_idx = VMM_PDPT_INDEX(virt);
u64 pml4_idx = VMM_PML4_INDEX(virt);
if (!(pml4[pml4_idx] & PTE_PRESENT)) {
u64* pml4_virt = pml4;
if (is_initialized) pml4_virt = (u64*)PHYS_TO_HHDM((u64)pml4);
if (!(pml4_virt[pml4_idx] & PTE_PRESENT)) {
u64* addr = pmm_alloc_page();
if (!addr) return nullptr;
u64* addr_virt = get_table_virt((u64)addr);
memset(addr_virt, 0, PAGE_SIZE);
pml4[pml4_idx] = (u64)addr | PTE_PRESENT | PTE_RW;
pml4_virt[pml4_idx] = (u64)addr | PTE_PRESENT | PTE_RW;
}
u64* pdpt = (u64*)PTE_GET_ADDR(pml4[pml4_idx]);
u64* pdpt = (u64*)PTE_GET_ADDR(pml4_virt[pml4_idx]);
u64* pdpt_virt = get_table_virt((u64)pdpt);
if (!(pdpt_virt[pdpt_idx] & PTE_PRESENT)) {
u64* addr = pmm_alloc_page();
if (!addr) return nullptr;
u64* addr_virt = get_table_virt((u64)addr);
memset(addr_virt, 0, PAGE_SIZE);
pdpt_virt[pdpt_idx] = (u64)addr | PTE_PRESENT | PTE_RW;
@@ -56,6 +61,7 @@ void vmm_map_page(u64* pml4, u64 phys, u64 virt, u64 flags) {
if (!(pd_virt[pd_idx] & PTE_PRESENT)) {
u64* addr = pmm_alloc_page();
if (!addr) return nullptr;
u64* addr_virt = get_table_virt((u64)addr);
memset(addr_virt, 0, PAGE_SIZE);
pd_virt[pd_idx] = (u64)addr | PTE_PRESENT | PTE_RW;
@@ -64,6 +70,10 @@ void vmm_map_page(u64* pml4, u64 phys, u64 virt, u64 flags) {
u64* pt = (u64*)PTE_GET_ADDR(pd_virt[pd_idx]);
u64* pt_virt = get_table_virt((u64)pt);
pt_virt[pt_idx] = phys | flags;
__asm__ volatile("invlpg (%0)" :: "r" (virt) : "memory");
return (u64*)virt;
}
void vmm_unmap_page(u64* pml4, u64 virt) {
+6
View File
@@ -8,6 +8,7 @@
#include <types.h>
#include "../data/cats.h"
#include "shell/dbgcmd.h"
const char* ascii_logo[] = {
" /\\___/\\ ",
@@ -74,4 +75,9 @@ void print_regs(Registers *regs) {
void cmd_sleep() {
sleep(3000);
}
void cmd_debug() {
debug();
return;
}
+89
View File
@@ -0,0 +1,89 @@
// SPDX-License-Identifier: GPL-3.0-or-later
// Copyright (c) 2025 0xKarinyash
// contents of this file will be changed CONSTANTLY
// im just testing new stuff here
#include <drivers/console.h>
#include <types.h>
#include <shell/dbgcmd.h>
#include <mm/heap.h>
#define VECTOR_BUFFER_SIZE 8
typedef struct {
i32* data;
u64 size;
u64 capacity;
} Vector;
void vector_init(Vector* vec) {
vec->data = nullptr;
vec->size = 0;
vec->capacity = 0;
}
u8 vector_append(Vector* vec, const i32 num) {
if (vec->size >= vec->capacity) {
u64 new_cap = (vec->capacity == 0) ? VECTOR_BUFFER_SIZE : vec->capacity * 2;
i32* new_data = realloc(vec->data, new_cap * sizeof(i32));
if (!new_data) return 2; // Out of memory
vec->data = new_data;
vec->capacity = new_cap;
}
vec->data[vec->size] = num;
vec->size++;
return 0;
}
void vector_reset(Vector* vec) {
vec->size = 0;
}
u8 vector_reserve(Vector* vec, u64 new_cap) {
if (new_cap <= vec->capacity) return 0;
i32* new_data = realloc(vec->data, new_cap * sizeof(i32));
if (!new_data) return 2;
vec->data = new_data;
vec->capacity = new_cap;
return 0;
}
void vector_free(Vector* vec) {
free(vec->data);
vec->data = nullptr;
vec->size = vec->capacity = 0;
}
void render_list(Vector* numbers) {
kprintf("\nNumbers [%d/%d]: [", numbers->size, numbers->capacity);
if (numbers->size == 0) kprintf("]");
for (u64 i = 0; i < numbers->size; i++) {
kprintf("%d", numbers->data[i]);
if (i + 1 >= numbers->size) {
kprintf("]");
break;
}
kprintf(", ");
}
}
void debug() {
Vector nums;
vector_init(&nums);
kprintf("Heap test\n");
kprintf("press any key to add 1 number press 'q' to exit\n");
char c = 'd';
u64 i = 0;
while (c != 'q') {
render_list(&nums);
vector_append(&nums, i);
i++;
c = console_getc();
}
vector_free(&nums);
}
+3
View File
@@ -27,6 +27,7 @@ typedef enum {
TOKEN_SLEEP,
TOKEN_REGS,
TOKEN_DEBUG,
TOKEN_RECTEST,
TOKEN_PANIC,
TOKEN_PANIC_UD2,
@@ -58,6 +59,7 @@ static const ksh_command_map token_map[] = {
{"neofetch", TOKEN_KFETCH},
{"sleep", TOKEN_SLEEP},
{"dbg", TOKEN_DEBUG},
{"regs", TOKEN_REGS},
{"rectest", TOKEN_RECTEST},
{"panic", TOKEN_PANIC},
@@ -87,6 +89,7 @@ void ksh() {
case TOKEN_QUIT: return; // that'll cause panic lol
case TOKEN_SLEEP: cmd_sleep(); break;
case TOKEN_DEBUG: cmd_debug(); break;
case TOKEN_REGS: cmd_regs(); break;
case TOKEN_RECTEST: rectest(0); break;
case TOKEN_PANIC: panic("Manually initiated panic");