This commit is contained in:
nub31
2025-09-03 18:31:10 +02:00
parent 0583c8c1a3
commit f05e7c9e64
31 changed files with 164 additions and 163 deletions

View File

@@ -12,4 +12,8 @@ CompileFlags:
- "-nostdinc"
- "-nostdlib"
- "-I"
- "/home/oliste/repos/nub-os/src/stdlib"
- "/home/oliste/repos/nub-os/src"
- "-I"
- "/home/oliste/repos/nub-os/src/kernel"
- "-I"
- "/home/oliste/repos/nub-os/src/arch"

View File

@@ -2,7 +2,7 @@ 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/stdlib -g
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

View File

@@ -1,21 +0,0 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
typedef struct
{
uint64_t base_address;
size_t length;
} memory_region_t;
typedef struct
{
memory_region_t* regions;
size_t num_regions;
} memory_map_t;
extern memory_map_t memory_map;
void panic();
void put_char(char character);

30
src/arch/arch.h Normal file
View File

@@ -0,0 +1,30 @@
#pragma once
#include "std.h"
typedef struct
{
uint64_t base_address;
size_t length;
} memory_region_t;
typedef struct
{
memory_region_t* regions;
size_t num_regions;
} memory_map_t;
extern memory_map_t memory_map;
void arch_panic(const char* msg);
void arch_putchar(char c);
uintptr_t arch_kernel_base();
uintptr_t arch_page_size();
void arch_interrupts_enable();
void arch_interrupts_disable();
void arch_register_interrupt_handler(int vector, void (*handler)(void));
void arch_halt();

45
src/arch/x86_64/arch.c Normal file
View File

@@ -0,0 +1,45 @@
#include "arch.h"
#include "console/console.h"
#include "interrupts/idt.h"
#include "interrupts/irq.h"
#include "kernel.h"
#include "memory/mmap.h"
#include "multiboot.h"
void x86_64_main(uint32_t magic, multiboot_info_t* info)
{
console_clear();
if (magic != 0x2BADB002)
{
arch_panic("Multiboot magic does not match\n");
}
if (info == NULL)
{
arch_panic("Multiboot info is NULL\n");
}
idt_init();
remap_pic();
map_memory(info);
enable_interrupts();
kernel_main();
}
void arch_panic(const char* msg);
void arch_putchar(char c)
{
console_put_char(c, VGA_DEFAULT_COLOR);
}
uintptr_t arch_kernel_base();
uintptr_t arch_page_size();
void arch_interrupts_enable();
void arch_interrupts_disable();
void arch_register_interrupt_handler(int vector, void (*handler)(void));
void arch_halt();

View File

@@ -1,6 +1,6 @@
global _start
global pml4
extern entry
extern x86_64_main
%define FLAGS 0b10
%define MAGIC 0x1BADB002
@@ -150,7 +150,7 @@ section .text
; Finally, we call in to c
mov edi, [multiboot_magic]
mov esi, [multiboot_info]
call entry
call x86_64_main
.hang:
hlt
jmp .hang

View File

@@ -1,5 +1,4 @@
#include "vga.h"
#include <stddef.h>
#include "console.h"
#define ROWS 25
#define COLUMNS 80
@@ -14,9 +13,9 @@ static vga_char_t* vga_buffer = (vga_char_t*)0xb8000;
static uint8_t cursor_row = 0;
static uint8_t cursor_col = 0;
void vga_put_char(char character, uint8_t color)
void console_put_char(char c, uint8_t color)
{
switch (character)
switch (c)
{
case '\n':
{
@@ -66,7 +65,7 @@ void vga_put_char(char character, uint8_t color)
default:
{
vga_buffer[COLUMNS * cursor_row + cursor_col] = (vga_char_t){
.character = character,
.character = c,
.color = color,
};
cursor_col += 1;
@@ -102,7 +101,7 @@ void vga_put_char(char character, uint8_t color)
}
}
void vga_clear()
void console_clear()
{
for (size_t row = 0; row < ROWS; row++)
{

View File

@@ -1,6 +1,6 @@
#pragma once
#include <stdint.h>
#include "std.h"
#define VGA_BLACK 0
#define VGA_BLUE 1
@@ -21,5 +21,5 @@
#define VGA_DEFAULT_COLOR VGA_LIGHT_GRAY | VGA_BLACK << 4
void vga_put_char(char character, uint8_t color);
void vga_clear();
void console_put_char(char character, uint8_t color);
void console_clear();

View File

@@ -1,44 +0,0 @@
#include "../../kernel/kernel.h"
#include "../api.h"
#include "interrupts/idt.h"
#include "interrupts/irq.h"
#include "memory/mmap.h"
#include "multiboot.h"
#include "util.h"
#include "vga/vga.h"
#include <stdint.h>
#include <stdio.h>
void entry(uint32_t magic, multiboot_info_t* info)
{
if (magic != 0x2BADB002)
{
printf("Multiboot magic does not match\n");
panic();
}
if (info == NULL)
{
printf("Multiboot info is NULL\n");
panic();
}
vga_clear();
idt_init();
remap_pic();
map_memory(info);
enable_interrupts();
main();
}
void panic()
{
printf("Kernel panic!\n");
disable_interrupts();
halt();
}
void put_char(char character)
{
vga_put_char(character, VGA_DEFAULT_COLOR);
}

View File

@@ -1,5 +1,5 @@
#include "exceptions.h"
#include "../../api.h"
#include "arch.h"
static const char* exception_messages[32] = {
"divide by zero",
@@ -39,5 +39,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();
arch_panic("An unhandled exception occurred");
}

View File

@@ -1,7 +1,6 @@
#pragma once
#include "isr.h"
#include <stdbool.h>
typedef void (*irq_handler_t)(const isr_frame_t*);

View File

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

View File

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

View File

@@ -1,7 +1,4 @@
#include "mmap.h"
#include "../../api.h"
#include <stddef.h>
#include <stdio.h>
#define USABLE_REGION_SIZE 32
@@ -13,8 +10,7 @@ void map_memory(multiboot_info_t* info)
{
if (!(info->flags & (1 << 6)))
{
printf("Invalid memory map given by bootloader\n");
panic();
arch_panic("Invalid memory map given by bootloader\n");
}
size_t num_regions = 0;

View File

@@ -1,6 +1,6 @@
#pragma once
#include "../../api.h"
#include "../multiboot.h"
#include "arch.h"
#include "x86_64/multiboot.h"
void map_memory(multiboot_info_t* mbd);

View File

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

View File

@@ -1,12 +1,11 @@
#include "kernel.h"
#include "pmm.h"
#include <stdio.h>
void main()
void kernel_main()
{
pmm_init();
uint64_t page = pmm_alloc_page();
printf("page: %u\n", page);
printf("Welcome to nub OS :)\n");
}
}

View File

@@ -1,3 +1,3 @@
#pragma once
void main();
void kernel_main();

View File

@@ -1,8 +1,5 @@
#include "pmm.h"
#include "../arch/api.h"
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "arch.h"
#define BITMAP_SIZE 32768 // Supports up to 1GB of RAM
#define USABLE_REGION_SIZE 32
@@ -19,8 +16,8 @@ void pmm_init()
{
memory_region_t region = memory_map.regions[i];
uint64_t start_page = region.base_address / PAGE_SIZE;
uint64_t num_pages = region.length / PAGE_SIZE;
uint64_t start_page = region.base_address / arch_page_size();
uint64_t num_pages = region.length / arch_page_size();
for (uint64_t page = start_page; page < start_page + num_pages; page++)
{
@@ -39,7 +36,7 @@ void pmm_init()
}
// Reserve first 64MB which is reserved by boot code
for (uint64_t page = 0; page < (64 * 1024 * 1024) / PAGE_SIZE; page++)
for (uint64_t page = 0; page < (64 * 1024 * 1024) / arch_page_size(); page++)
{
if (page < BITMAP_SIZE * 8)
{
@@ -65,7 +62,7 @@ uint64_t pmm_alloc_page()
{
page_bitmap[i] |= (1 << bit);
free_pages--;
return ((i * 8 + bit) * PAGE_SIZE);
return ((i * 8 + bit) * arch_page_size());
}
}
}
@@ -77,7 +74,7 @@ uint64_t pmm_alloc_page()
// Frees the physical page at the specified address
void pmm_free_page(uint64_t addr)
{
uint64_t page = addr / PAGE_SIZE;
uint64_t page = addr / arch_page_size();
if (page < BITMAP_SIZE * 8)
{
if (page_bitmap[page / 8] & (1 << (page % 8)))

View File

@@ -1,8 +1,6 @@
#pragma once
#include <stdint.h>
#define PAGE_SIZE 4096
#include "std.h"
void pmm_init();
uint64_t pmm_alloc_page();

6
src/std.h Normal file
View File

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

View File

@@ -1,5 +1,29 @@
#pragma once
typedef __builtin_va_list va_list;
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#define va_end(ap) __builtin_va_end(ap)
#define va_copy(dest, src) __builtin_va_copy(dest, src)
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1
#ifndef NULL
#define NULL ((void*)0)
#endif
typedef unsigned long size_t;
typedef long ptrdiff_t;
typedef long intptr_t;
typedef unsigned long uintptr_t;
#define offsetof(type, member) __builtin_offsetof(type, member)
typedef signed char int8_t;
typedef unsigned char uint8_t;
typedef signed short int16_t;

View File

@@ -1,9 +1,4 @@
#include "../arch/api.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include "arch.h"
void printf(const char* fmt, ...)
{
@@ -20,20 +15,20 @@ void printf(const char* fmt, ...)
if (fmt[i] == '%')
{
put_char('%');
arch_putchar('%');
}
else if (fmt[i] == 's')
{
const char* str = va_arg(args, const char*);
for (size_t j = 0; str[j] != '\0'; j++)
{
put_char(str[j]);
arch_putchar(str[j]);
}
}
else if (fmt[i] == 'c')
{
char character = (char)va_arg(args, int64_t);
put_char(character);
arch_putchar(character);
}
else if (fmt[i] == 'd')
{
@@ -42,7 +37,7 @@ void printf(const char* fmt, ...)
itoa64(val, buf);
for (size_t j = 0; buf[j] != '\0'; j++)
{
put_char(buf[j]);
arch_putchar(buf[j]);
}
}
else if (fmt[i] == 'u')
@@ -52,7 +47,7 @@ void printf(const char* fmt, ...)
uitoa64(val, buf);
for (size_t j = 0; buf[j] != '\0'; j++)
{
put_char(buf[j]);
arch_putchar(buf[j]);
}
}
else if (fmt[i] == 'x')
@@ -62,12 +57,12 @@ void printf(const char* fmt, ...)
uitoa64_hex(val, buf);
for (size_t j = 0; buf[j] != '\0'; j++)
{
put_char(buf[j]);
arch_putchar(buf[j]);
}
}
else
{
put_char(fmt[i]);
arch_putchar(fmt[i]);
}
}
else if (fmt[i] == '%')
@@ -76,7 +71,7 @@ void printf(const char* fmt, ...)
}
else
{
put_char(fmt[i]);
arch_putchar(fmt[i]);
}
}

9
src/stdlib/mem.c Normal file
View File

@@ -0,0 +1,9 @@
#include "mem.h"
void memset(void* destination, uint8_t value, size_t length)
{
for (size_t i = 0; i < length; i++)
{
((uint8_t*)destination)[i] = value;
}
}

5
src/stdlib/mem.h Normal file
View File

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

View File

@@ -1,8 +0,0 @@
#pragma once
typedef __builtin_va_list va_list;
#define va_start(ap, last) __builtin_va_start(ap, last)
#define va_arg(ap, type) __builtin_va_arg(ap, type)
#define va_end(ap) __builtin_va_end(ap)
#define va_copy(dest, src) __builtin_va_copy(dest, src)

View File

@@ -1,7 +0,0 @@
#pragma once
#define bool _Bool
#define true 1
#define false 0
#define __bool_true_false_are_defined 1

View File

@@ -1,12 +0,0 @@
#pragma once
#ifndef NULL
#define NULL ((void*)0)
#endif
typedef unsigned long size_t;
typedef long ptrdiff_t;
typedef long intptr_t;
typedef unsigned long uintptr_t;
#define offsetof(type, member) __builtin_offsetof(type, member)

View File

@@ -1,14 +1,6 @@
#include <string.h>
#include "string.h"
void memset(void* destination, uint8_t value, size_t length)
{
for (size_t i = 0; i < length; i++)
{
((uint8_t*)destination)[i] = value;
}
}
int strcmp(const char* a, const char* b)
int kstrcmp(const char* a, const char* b)
{
while ((*a != '\0' && *b != '\0') && *a == *b)
{

View File

@@ -1,11 +1,8 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
#include "std.h"
void memset(void* destination, uint8_t value, size_t length);
int strcmp(const char* a, const char* b);
void reverse(char* str, size_t length);
void uitoa64(uint64_t value, char* buffer);
void itoa64(int64_t value, char* buffer);
void uitoa64_hex(uint64_t value, char* buffer);