...
This commit is contained in:
6
.clangd
6
.clangd
@@ -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"
|
||||
|
||||
2
makefile
2
makefile
@@ -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
|
||||
|
||||
|
||||
@@ -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
30
src/arch/arch.h
Normal 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
45
src/arch/x86_64/arch.c
Normal 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();
|
||||
@@ -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
|
||||
@@ -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++)
|
||||
{
|
||||
@@ -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();
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "isr.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef void (*irq_handler_t)(const isr_frame_t*);
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#include "isr.h"
|
||||
#include "exceptions.h"
|
||||
#include "irq.h"
|
||||
#include <stdio.h>
|
||||
|
||||
void handle_isr(const isr_frame_t* frame)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include "std.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include "std.h"
|
||||
|
||||
enum
|
||||
{
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
#pragma once
|
||||
|
||||
void main();
|
||||
void kernel_main();
|
||||
@@ -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)))
|
||||
|
||||
@@ -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
6
src/std.h
Normal file
@@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include "stdlib/def.h"
|
||||
#include "stdlib/io.h"
|
||||
#include "stdlib/mem.h"
|
||||
#include "stdlib/string.h"
|
||||
@@ -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;
|
||||
@@ -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
9
src/stdlib/mem.c
Normal 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
5
src/stdlib/mem.h
Normal file
@@ -0,0 +1,5 @@
|
||||
#pragma once
|
||||
|
||||
#include "std.h"
|
||||
|
||||
void memset(void* destination, uint8_t value, size_t length);
|
||||
@@ -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)
|
||||
@@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#define bool _Bool
|
||||
#define true 1
|
||||
#define false 0
|
||||
|
||||
#define __bool_true_false_are_defined 1
|
||||
@@ -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)
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
Reference in New Issue
Block a user