...
This commit is contained in:
19
.clangd
19
.clangd
@@ -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
19
.vscode/c_cpp_properties.json
vendored
Normal 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
15
.vscode/settings.json
vendored
@@ -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"
|
||||
}
|
||||
}
|
||||
12
makefile
12
makefile
@@ -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')
|
||||
|
||||
@@ -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)();
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
49
src/kernel/alloc.c
Normal 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
6
src/kernel/alloc.h
Normal 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
13
src/kernel/assert.h
Normal 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
|
||||
}
|
||||
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user