This commit is contained in:
nub31
2025-09-06 22:07:17 +02:00
parent 45a9023bab
commit 4f55956fee
32 changed files with 89 additions and 83 deletions

View File

@@ -2,14 +2,12 @@
"version": 4,
"configurations": [
{
"name": "test",
"name": "kernel",
"defines": [
"DEBUG"
],
"includePath": [
"src/kernel",
"src/arch",
"src"
"src/lib"
],
"intelliSenseMode": "linux-gcc-x64",
"compilerPath": "/usr/bin/x86_64-elf-gcc",

View File

@@ -31,6 +31,10 @@
"assert.h": "c",
"io.h": "c",
"mem.h": "c",
"string.h": "c"
"string.h": "c",
"kernel.h": "c",
"printf.h": "c",
"vmm.h": "c",
"console.h": "c"
}
}

View File

@@ -8,7 +8,7 @@ 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
CFLAGS += -m64 -ffreestanding -nostdinc -nostdlib -fno-builtin -Wall -Wextra -Wshadow -std=c23 -I src/lib
LDFLAGS +=
ASFLAGS += -f elf64

View File

@@ -1,9 +1,11 @@
#include "arch.h"
#include "console.h"
#include "mem/pmm.h"
#include "mem/vmm.h"
#include "panic.h"
#include "util.h"
#include <arch.h>
#include <def.h>
#include <printf.h>
static void arch_halt()
{
@@ -20,9 +22,9 @@ static void arch_enable_interrupts()
enable_interrupts();
}
static void arch_panic(const char* msg)
static void arch_panic()
{
panic(msg);
panic();
}
static void arch_console_putchar(char c)
@@ -49,7 +51,8 @@ void* arch_alloc(size_t page_count)
u64 physical_address = pmm_alloc();
if (!physical_address)
{
panic("Out of physical memory");
printf("Out of physical memory");
panic();
}
vmm_map(physical_address, virtual_address + (i * PAGE_SIZE), PTE_PRESENT | PTE_WRITABLE);

View File

@@ -1,6 +1,6 @@
#pragma once
#include "std.h"
#include <def.h>
#define VGA_BLACK 0
#define VGA_BLUE 1

View File

@@ -1,5 +1,6 @@
#include "exceptions.h"
#include "../panic.h"
#include <printf.h>
static const char* exception_messages[32] = {
"divide by zero",
@@ -39,5 +40,5 @@ static const char* exception_messages[32] = {
void handle_exception(const isr_frame_t* frame)
{
printf("exception[%d]: %s, error code: %d\n", frame->int_no, exception_messages[frame->int_no], frame->err_code);
panic("An unhandled exception occurred");
panic();
}

View File

@@ -1,5 +1,6 @@
#include "irq.h"
#include "../util.h"
#include <printf.h>
#define PIC1_COMMAND 0x20
#define PIC1_DATA 0x21

View File

@@ -1,6 +1,8 @@
#include "isr.h"
#include "exceptions.h"
#include "irq.h"
#include <def.h>
#include <printf.h>
void handle_isr(const isr_frame_t* frame)
{

View File

@@ -1,6 +1,6 @@
#pragma once
#include "std.h"
#include <def.h>
typedef struct
{

View File

@@ -1,11 +1,13 @@
#include "console.h"
#include "interrupts/idt.h"
#include "interrupts/irq.h"
#include "kernel.h"
#include "mem/pmm.h"
#include "mem/vmm.h"
#include "panic.h"
#include "util.h"
#include <printf.h>
extern void kernel_main();
void x86_64_main(u32 magic, multiboot_info_t* info, u32 kernel_page_count)
{
@@ -13,12 +15,14 @@ void x86_64_main(u32 magic, multiboot_info_t* info, u32 kernel_page_count)
if (magic != 0x2BADB002)
{
panic("Multiboot magic does not match\n");
printf("Multiboot magic does not match\n");
panic();
}
if (info == NULL)
{
panic("Multiboot info is NULL\n");
printf("Multiboot info is NULL\n");
panic();
}
idt_init();

View File

@@ -1,5 +1,7 @@
#include "pmm.h"
#include "x86_64/panic.h"
#include "../panic.h"
#include <mem.h>
#include <printf.h>
typedef struct
{
@@ -27,7 +29,8 @@ void pmm_init(u32 kernel_page_count, multiboot_info_t* info)
{
if (!(info->flags & (1 << 6)))
{
panic("Invalid memory map given by bootloader\n");
printf("Invalid memory map given by bootloader\n");
panic();
}
u64 offset = 0;
@@ -84,7 +87,8 @@ void pmm_init(u32 kernel_page_count, multiboot_info_t* info)
{
if (page >= BITMAP_PAGE_COUNT)
{
panic("Bitmap is not large enough to hold the memory reserved by the kernel");
printf("Bitmap is not large enough to hold the memory reserved by the kernel");
panic();
}
page_bitmap[page / 8] |= (1 << (page % 8));
@@ -123,7 +127,7 @@ void pmm_free(u64 physical_address)
else
{
printf("Physical address %x is already free", physical_address);
panic("Failed to free physical address");
panic();
}
}
}

View File

@@ -1,7 +1,7 @@
#pragma once
#include "std.h"
#include "x86_64/multiboot.h"
#include "../multiboot.h"
#include <def.h>
// todo(nub31): Fixed at 2mb for now, might add support for 4k pages later
#define PAGE_SIZE MiB(2)

View File

@@ -1,6 +1,7 @@
#include "vmm.h"
#include "../panic.h"
#include "pmm.h"
#include "x86_64/panic.h"
#include <printf.h>
#define PML4_INDEX(addr) (((addr) >> 39) & 0x1FF)
#define PDPT_INDEX(addr) (((addr) >> 30) & 0x1FF)
@@ -23,7 +24,8 @@ void vmm_init(u32 kernel_page_count)
{
if (page >= BITMAP_PAGE_COUNT)
{
panic("Bitmap is not large enough to hold the addresses reserved by the kernel");
printf("Bitmap is not large enough to hold the addresses reserved by the kernel");
panic();
}
page_bitmap[page / 8] |= (1 << (page % 8));
@@ -75,7 +77,7 @@ void vmm_free_address(u64 virtual_address, size_t page_count)
if (start_page + page_count > BITMAP_PAGE_COUNT)
{
printf("Virtual address range exceeds bitmap bounds\n");
panic("Failed to free virtual address");
panic();
}
for (size_t i = 0; i < page_count; i++)
@@ -87,7 +89,7 @@ void vmm_free_address(u64 virtual_address, size_t page_count)
if (!(page_bitmap[byte_index] & (1 << bit_index)))
{
printf("Virtual address 0x%x (page %u) is already free\n", virtual_address + (i * PAGE_SIZE), page);
panic("Failed to free virtual address");
panic();
}
}
@@ -105,7 +107,7 @@ static u64 create_2mb_pte(u64 physical_address, u32 flags)
if (physical_address & (PAGE_SIZE - 1))
{
printf("Physical address not page aligned (0x%x)\n", physical_address);
panic("Failed to create PTE");
panic();
}
return (physical_address & PTE_MASK) | flags | PTE_PS;
@@ -122,7 +124,7 @@ void vmm_map(u64 physical_address, u64 virtual_address, u32 flags)
{
// todo(nub31): Dynamically create a pdpt table
printf("PDPT not present at PML4 index %u\n", pml4_idx);
panic("Failed to map virtual to physical page");
panic();
}
u64* pdpt_physical_address = (u64*)(pdpt & PTE_MASK);
@@ -131,7 +133,7 @@ void vmm_map(u64 physical_address, u64 virtual_address, u32 flags)
{
// todo(nub31): Dynamically create a pd table
printf("PD not present at PDPT index %u\n", pdpt_idx);
panic("Failed to map virtual to physical page");
panic();
}
u64* pd_physical_address = (u64*)(pd & PTE_MASK);
@@ -140,7 +142,7 @@ void vmm_map(u64 physical_address, u64 virtual_address, u32 flags)
if (entry & PTE_PRESENT)
{
printf("Virtual address 0x%x is already mapped\n", virtual_address);
panic("Failed to map virtual to physical page");
panic();
}
pd_physical_address[pd_idx] = create_2mb_pte(physical_address, flags);
@@ -156,7 +158,7 @@ u64 vmm_unmap(u64 virtual_address)
if (!(pdpt_entry & PTE_PRESENT))
{
printf("PDPT not present at PML4 index %llu\n", pml4_idx);
panic("Failed to unmap virtual address");
panic();
}
u64* pdpt_physical_address = (u64*)(pdpt_entry & PTE_MASK);
@@ -164,14 +166,14 @@ u64 vmm_unmap(u64 virtual_address)
if (!(pd_entry & PTE_PRESENT))
{
printf("PD not present at PDPT index %llu\n", pdpt_idx);
panic("Failed to unmap virtual address");
panic();
}
u64* pd_physical_address = (u64*)(pd_entry & PTE_MASK);
if (!(pd_physical_address[pd_idx] & PTE_PRESENT))
{
printf("Virtual address 0x%llx is not mapped\n", virtual_address);
panic("Failed to unmap virtual address");
panic();
}
u64 physical_address = pd_physical_address[pd_idx] & PTE_MASK;

View File

@@ -1,6 +1,6 @@
#pragma once
#include "std.h"
#include <def.h>
// Defines the theoretical max virtual memory space the kernel can allocate
// The value must be a multible of 8

View File

@@ -1,9 +1,8 @@
#include "panic.h"
#include "util.h"
void panic(const char* msg)
void panic()
{
printf(msg);
disable_interrupts();
halt();
}

View File

@@ -1,3 +1,3 @@
#pragma once
void panic(const char* msg);
void panic();

View File

@@ -1,6 +1,6 @@
#pragma once
#include "std.h"
#include <def.h>
enum
{

View File

@@ -1,5 +1,4 @@
#include "arch.h"
#include "assert.h"
#include <assert.h>
typedef struct block_header
{

View File

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

View File

@@ -1,22 +1,11 @@
#include "kernel.h"
#include "alloc.h"
#include "arch.h"
#include "assert.h"
#include "std.h"
#include <arch.h>
#include <printf.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();

View File

@@ -1,6 +1,6 @@
#pragma once
#include "std.h"
#include <def.h>
typedef void (*arch_console_putchar_t)(char c);
typedef void (*arch_console_clear_t)();
@@ -22,7 +22,7 @@ typedef struct
const arch_mem_free_t free;
} arch_mem_api_t;
typedef void (*arch_panic_t)(const char* msg);
typedef void (*arch_panic_t)();
typedef void (*arch_enable_interrupts_t)();
typedef void (*arch_disable_interrupts_t)();
typedef void (*arch_halt_t)();

View File

@@ -1,13 +1,14 @@
#pragma once
#include "arch.h"
#include <arch.h>
// In arch code, make sure arch_api.panic is set up befire calling
static inline void assert(bool condition, const char* msg)
{
#if DEBUG
if (!condition)
{
arch_api.panic(msg);
arch_api.panic();
}
#endif
}

View File

@@ -37,14 +37,20 @@ typedef signed long long i64;
#define INT16_MIN (-32768)
#define INT16_MAX 32767
#define UINT16_MIN 0x0
#define UINT16_MAX 0xffff
#define INT32_MIN (-2147483647 - 1)
#define INT32_MAX 2147483647
#define UINT32_MIN 0x0
#define UINT32_MAX 0xffffffffU
#define INT64_MIN (-9223372036854775807LL - 1)
#define INT64_MAX 9223372036854775807LL
#define UINT64_MIN 0x0
#define UINT64_MAX 0xffffffffffffffffULL
#define INT8_C(x) x
@@ -59,10 +65,7 @@ typedef signed long long i64;
#define INT64_C(x) x##LL
#define UINT64_C(x) x##ULL
#define INTMAX_C(x) x##LL
#define UINTMAX_C(x) x##ULL
#define KiB(count) ((u64)count * 1024)
#define MiB(count) (KiB((u64)count) * 1024)
#define GiB(count) (MiB((u64)count) * 1024)
#define TiB(count) (GiB((u64)count) * 1024)
#define KiB(count) (count * UINT64_C(count))
#define MiB(count) (KiB(count) * UINT64_C(count))
#define GiB(count) (MiB(count) * UINT64_C(count))
#define TiB(count) (GiB(count) * UINT64_C(count))

6
src/lib/mem.h Normal file
View File

@@ -0,0 +1,6 @@
#pragma once
#include <def.h>
void memset(void* destination, u8 value, size_t length);
void memcpy(void* destination, void* source, size_t length);

View File

@@ -1,4 +1,7 @@
#include "arch.h"
#include "printf.h"
#include <arch.h>
#include <def.h>
#include <string.h>
void printf(const char* fmt, ...)
{

4
src/lib/printf.h Normal file
View File

@@ -0,0 +1,4 @@
#pragma once
// In arch code, make sure arch_api.console.putchar is set up befire calling
void printf(const char* fmt, ...);

View File

@@ -1,6 +1,6 @@
#pragma once
#include "std.h"
#include <def.h>
int strcmp(const char* a, const char* b);
void reverse(char* str, size_t length);

View File

@@ -1,6 +0,0 @@
#pragma once
#include "stdlib/def.h"
#include "stdlib/io.h"
#include "stdlib/mem.h"
#include "stdlib/string.h"

View File

@@ -1,3 +0,0 @@
#pragma once
void printf(const char* fmt, ...);

View File

@@ -1,6 +0,0 @@
#pragma once
#include "std.h"
void memset(void* destination, u8 value, size_t length);
void memcpy(void* destination, void* source, size_t length);