This commit is contained in:
nub31
2025-09-06 21:21:59 +02:00
parent 130e271461
commit 45a9023bab
12 changed files with 167 additions and 67 deletions

19
.clangd
View File

@@ -1,19 +0,0 @@
CompileFlags:
Add:
- "-target"
- "x86_64-unknown-none"
- "-ffreestanding"
- "-fno-builtin"
- "-fno-common"
- "-Wall"
- "-Wextra"
- "-Wshadow"
- "-fno-strict-aliasing"
- "-nostdinc"
- "-nostdlib"
- "-I"
- "/home/oliste/repos/nub-os/src"
- "-I"
- "/home/oliste/repos/nub-os/src/kernel"
- "-I"
- "/home/oliste/repos/nub-os/src/arch"

19
.vscode/c_cpp_properties.json vendored Normal file
View File

@@ -0,0 +1,19 @@
{
"version": 4,
"configurations": [
{
"name": "test",
"defines": [
"DEBUG"
],
"includePath": [
"src/kernel",
"src/arch",
"src"
],
"intelliSenseMode": "linux-gcc-x64",
"compilerPath": "/usr/bin/x86_64-elf-gcc",
"cStandard": "c23"
}
]
}

15
.vscode/settings.json vendored
View File

@@ -18,6 +18,19 @@
"system_error": "c",
"std.h": "c",
"panic.h": "c",
"pmm.h": "c"
"pmm.h": "c",
"array": "cpp",
"string_view": "cpp",
"initializer_list": "cpp",
"ranges": "cpp",
"span": "cpp",
"valarray": "cpp",
"alloc.h": "c",
"arch.h": "c",
"def.h": "c",
"assert.h": "c",
"io.h": "c",
"mem.h": "c",
"string.h": "c"
}
}

View File

@@ -2,9 +2,15 @@ CC = x86_64-elf-gcc
LD = x86_64-elf-ld
AS = nasm
CFLAGS = -m64 -ffreestanding -nostdinc -nostdlib -fno-builtin -Wall -Wextra -Wshadow -std=c11 -I src -I src/kernel -I src/arch -g
LDFLAGS = -g
ASFLAGS = -f elf64 -g -F dwarf
# Modify these settings here for defines and debug info
CFLAGS = -g -D DEBUG
LDFLAGS = -g
ASFLAGS = -g -F dwarf
# Do not modify
CFLAGS += -m64 -ffreestanding -nostdinc -nostdlib -fno-builtin -Wall -Wextra -Wshadow -std=c23 -I src -I src/kernel -I src/arch
LDFLAGS +=
ASFLAGS += -f elf64
SRC_C := $(shell find src -name '*.c')
SRC_ASM := $(shell find src -name '*.asm')

View File

@@ -11,14 +11,18 @@ typedef struct
const arch_console_clear_t clear;
} arch_console_api_t;
typedef u64 (*arch_mem_get_page_size_t)();
typedef size_t (*arch_mem_get_page_size_t)();
typedef void* (*arch_mem_alloc_t)(size_t page_count);
typedef void (*arch_mem_free_t)(void* virtual_address, size_t page_count);
typedef struct
{
const arch_mem_get_page_size_t get_page_size;
const arch_mem_alloc_t alloc;
const arch_mem_free_t free;
} arch_mem_api_t;
typedef void (*arch_panic_t)(const char*);
typedef void (*arch_panic_t)(const char* msg);
typedef void (*arch_enable_interrupts_t)();
typedef void (*arch_disable_interrupts_t)();
typedef void (*arch_halt_t)();

View File

@@ -1,6 +1,7 @@
#include "arch.h"
#include "console.h"
#include "mem/pmm.h"
#include "mem/vmm.h"
#include "panic.h"
#include "util.h"
@@ -34,13 +35,44 @@ static void arch_console_clear()
console_clear();
}
static u64 arch_get_page_size()
static size_t arch_get_page_size()
{
return PAGE_SIZE;
}
void* arch_alloc(size_t page_count)
{
u64 virtual_address = vmm_alloc_address(page_count);
for (size_t i = 0; i < page_count; i++)
{
u64 physical_address = pmm_alloc();
if (!physical_address)
{
panic("Out of physical memory");
}
vmm_map(physical_address, virtual_address + (i * PAGE_SIZE), PTE_PRESENT | PTE_WRITABLE);
}
return (void*)virtual_address;
}
void arch_free(void* virtual_address, size_t page_count)
{
for (size_t i = 0; i < page_count; i++)
{
u64 physical_address = vmm_unmap((u64)virtual_address + (i * PAGE_SIZE));
pmm_free(physical_address);
}
vmm_free_address((u64)virtual_address, page_count);
}
static const arch_mem_api_t arch_mem_api = {
.get_page_size = arch_get_page_size,
.alloc = arch_alloc,
.free = arch_free,
};
static const arch_console_api_t arch_console_api = {

View File

@@ -8,11 +8,6 @@
#define PTE_MASK 0x000FFFFFFFFFF000ULL
#define PTE_PRESENT (1ULL << 0)
#define PTE_WRITABLE (1ULL << 1)
#define PTE_USER (1ULL << 2)
#define PTE_PS (1ULL << 7)
#define BITMAP_PAGE_COUNT (ADDRES_SPACE_SIZE / PAGE_SIZE)
#define BITMAP_SIZE (BITMAP_PAGE_COUNT / 8)
@@ -185,33 +180,4 @@ u64 vmm_unmap(u64 virtual_address)
__asm__ volatile("invlpg (%0)" : : "r"(virtual_address) : "memory");
return physical_address;
}
void* vmm_alloc(size_t page_count)
{
u64 virtual_address = vmm_alloc_address(page_count);
for (size_t i = 0; i < page_count; i++)
{
u64 physical_address = pmm_alloc();
if (!physical_address)
{
panic("Out of physical memory");
}
vmm_map(physical_address, virtual_address + (i * PAGE_SIZE), PTE_PRESENT | PTE_WRITABLE);
}
return (void*)virtual_address;
}
void vmm_free(void* virtual_address, size_t page_count)
{
for (size_t i = 0; i < page_count; i++)
{
u64 physical_address = vmm_unmap((u64)virtual_address + (i * PAGE_SIZE));
pmm_free(physical_address);
}
vmm_free_address((u64)virtual_address, page_count);
}

View File

@@ -6,6 +6,11 @@
// The value must be a multible of 8
#define ADDRES_SPACE_SIZE GiB(64)
#define PTE_PRESENT (1ULL << 0)
#define PTE_WRITABLE (1ULL << 1)
#define PTE_USER (1ULL << 2)
#define PTE_PS (1ULL << 7)
void vmm_init(u32 kernel_page_count);
// Allocates a free page aligned block of virtual addresses
@@ -19,10 +24,4 @@ void vmm_free_address(u64 virtual_address, size_t page_count);
// Low level function to map a virtual address to a physical address
void vmm_map(u64 physical_address, u64 virtual_address, u32 flags);
// Low level function to unmap a virtual address from a physical address
u64 vmm_unmap(u64 virtual_address);
// Allocates and maps `page_count` continuous pages and returns the virtual address of the first page
void* vmm_alloc(size_t page_count);
// Frees the pages allocated via `vmm_alloc` at the specified virtual address
// Only use this function for pages mapped via `vmm_alloc`
void vmm_free(void* virtual_address, size_t page_count);
u64 vmm_unmap(u64 virtual_address);

49
src/kernel/alloc.c Normal file
View File

@@ -0,0 +1,49 @@
#include "arch.h"
#include "assert.h"
typedef struct block_header
{
size_t size;
bool is_free;
struct block_header* next;
struct block_header* prev;
u8 data[];
} block_header_t;
static block_header_t* heap_start = NULL;
#define HEADER_SIZE sizeof(block_header_t)
static block_header_t* find_free_block(size_t size)
{
block_header_t* current = heap_start;
while (current != NULL)
{
if (current->is_free && current->size >= size)
{
return current;
}
current = current->next;
}
return NULL;
}
void* malloc(size_t size)
{
// Align to pointer size
size = (size + sizeof(void*) - 1) & ~(sizeof(void*) - 1);
block_header_t* block = find_free_block(size);
block->is_free = false;
return (u8*)block + HEADER_SIZE;
}
void free(void* ptr)
{
block_header_t* block = (block_header_t*)((u8*)ptr - HEADER_SIZE);
assert(block->is_free, "Block is already free");
block->is_free = true;
}

6
src/kernel/alloc.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
#include "std.h"
void* malloc(size_t size);
void free(void* ptr);

13
src/kernel/assert.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include "arch.h"
static inline void assert(bool condition, const char* msg)
{
#if DEBUG
if (!condition)
{
arch_api.panic(msg);
}
#endif
}

View File

@@ -1,10 +1,22 @@
#include "kernel.h"
#include "alloc.h"
#include "arch.h"
#include "assert.h"
#include "std.h"
void kernel_main()
{
assert(false, "test");
arch_api.enable_interrupts();
u64* mem = malloc(1);
*mem = 23;
printf("%d\n", *mem);
free(mem);
printf("Welcome to nub OS :)\n");
printf("Kernel has exited\n");
arch_api.halt();