feat: heap, dbg command (currently heap test there)
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
@@ -10,6 +10,7 @@ void cmd_help();
|
||||
void cmd_regs();
|
||||
void print_regs();
|
||||
void cmd_sleep();
|
||||
void cmd_debug();
|
||||
int rectest(int a);
|
||||
|
||||
#endif
|
||||
@@ -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
|
||||
@@ -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
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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) {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user