style #13

Merged
xamidev merged 6 commits from style into main 2026-03-14 09:34:01 +01:00
29 changed files with 147 additions and 229 deletions
Showing only changes of commit 8e2a612d88 - Show all commits

View File

@@ -26,6 +26,8 @@ if (something) {
} }
``` ```
Having no braces for a single statement structure is fine.
Functions should have their opening brace on a separate line, and the same goes for the closing brace: Functions should have their opening brace on a separate line, and the same goes for the closing brace:
```c ```c
@@ -59,7 +61,7 @@ Global variables need to have descriptive names. Local variables can be kept sho
## Typedefs ## Typedefs
Structures should not be `typedef`'d. Structures should not be `typedef`'d. However using `typedef` for an enumeration is fine.
## Functions ## Functions

View File

@@ -6,28 +6,24 @@
#include <limine.h> #include <limine.h>
// Framebuffer request
__attribute__((used, section(".limine_requests"))) __attribute__((used, section(".limine_requests")))
volatile struct limine_framebuffer_request framebuffer_request = { volatile struct limine_framebuffer_request framebuffer_request = {
.id = LIMINE_FRAMEBUFFER_REQUEST, .id = LIMINE_FRAMEBUFFER_REQUEST,
.revision = 0 .revision = 0
}; };
// Memory map request
__attribute__((used, section(".limine_requests"))) __attribute__((used, section(".limine_requests")))
volatile struct limine_memmap_request memmap_request = { volatile struct limine_memmap_request memmap_request = {
.id = LIMINE_MEMMAP_REQUEST, .id = LIMINE_MEMMAP_REQUEST,
.revision = 0 .revision = 0
}; };
// Higher Half Direct Map
__attribute__((used, section(".limine_requests"))) __attribute__((used, section(".limine_requests")))
volatile struct limine_hhdm_request hhdm_request = { volatile struct limine_hhdm_request hhdm_request = {
.id = LIMINE_HHDM_REQUEST, .id = LIMINE_HHDM_REQUEST,
.revision = 0 .revision = 0
}; };
// Executable Address/Kernel Address (find base phys/virt address of kernel)
__attribute__((used, section(".limine_requests"))) __attribute__((used, section(".limine_requests")))
volatile struct limine_kernel_address_request kerneladdr_request = { volatile struct limine_kernel_address_request kerneladdr_request = {
.id = LIMINE_KERNEL_ADDRESS_REQUEST, .id = LIMINE_KERNEL_ADDRESS_REQUEST,

View File

@@ -28,6 +28,10 @@
// 2 MB should be enough (as of now, the whole kernel ELF is around 75kb) // 2 MB should be enough (as of now, the whole kernel ELF is around 75kb)
#define KERNEL_SIZE 0x200000 #define KERNEL_SIZE 0x200000
#define KERNEL_STACK_SIZE 65536 #define KERNEL_STACK_SIZE 65536
#define KERNEL_IDT_ENTRIES 33
/* paging */
#define PAGING_MAX_PHYS 0x100000000
/* heap */ /* heap */
#define KHEAP_SIZE (32*1024*1024) #define KHEAP_SIZE (32*1024*1024)

View File

@@ -1,3 +1,9 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief Miscellaneous debug features
* @license GPL-3.0-only
*/
#include <kernel.h> #include <kernel.h>
#include "limine.h" #include "limine.h"
#include "string/string.h" #include "string/string.h"
@@ -9,12 +15,10 @@ void memmap_display(struct limine_memmap_response* response)
{ {
DEBUG("Got memory map from Limine: revision %u, %u entries", response->revision, response->entry_count); DEBUG("Got memory map from Limine: revision %u, %u entries", response->revision, response->entry_count);
for (size_t i=0; i<response->entry_count; i++) for (size_t i=0; i<response->entry_count; i++) {
{
struct limine_memmap_entry* entry = response->entries[i]; struct limine_memmap_entry* entry = response->entries[i];
char type[32] = {0}; char type[32] = {0};
switch(entry->type) switch(entry->type) {
{
case LIMINE_MEMMAP_USABLE: case LIMINE_MEMMAP_USABLE:
strcpy(type, "USABLE"); strcpy(type, "USABLE");
break; break;

View File

@@ -1,3 +1,9 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief Kernel panic
* @license GPL-3.0-only
*/
#include <stddef.h> #include <stddef.h>
#include "idt/idt.h" #include "idt/idt.h"
#include "io/serial/serial.h" #include "io/serial/serial.h"
@@ -8,8 +14,7 @@ extern struct init_status init;
void panic(struct cpu_status_t* ctx, const char* str) void panic(struct cpu_status_t* ctx, const char* str)
{ {
CLEAR_INTERRUPTS; CLEAR_INTERRUPTS;
if (ctx == NULL) if (ctx == NULL) {
{
DEBUG("\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m Something went horribly wrong! (no cpu ctx)"); DEBUG("\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[0m Something went horribly wrong! (no cpu ctx)");
fctprintf((void*)&skputc, 0, "\x1b[38;5;231m\x1b[48;5;27m"); fctprintf((void*)&skputc, 0, "\x1b[38;5;231m\x1b[48;5;27m");
DIE_DEBUG(str); DIE_DEBUG(str);
@@ -18,8 +23,7 @@ void panic(struct cpu_status_t* ctx, const char* str)
skputc('\n'); skputc('\n');
DEBUG("\x1b[38;5;231m\x1b[48;5;196mend Kernel panic - halting...\x1b[0m"); DEBUG("\x1b[38;5;231m\x1b[48;5;196mend Kernel panic - halting...\x1b[0m");
if (init.terminal) if (init.terminal) {
{
printf("\r\n\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[48;5;232m Something went horribly wrong! (no cpu ctx)"); printf("\r\n\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[48;5;232m Something went horribly wrong! (no cpu ctx)");
printf("\r\n%s\r\n\x1b[38;5;231mend Kernel panic - halting...\x1b[0m", str); printf("\r\n%s\r\n\x1b[38;5;231mend Kernel panic - halting...\x1b[0m", str);
} }
@@ -32,8 +36,7 @@ void panic(struct cpu_status_t* ctx, const char* str)
ctx->vector_number, ctx->error_code, ctx->rax, ctx->rbx, ctx->rcx, ctx->rdx, ctx->rsi, ctx->rdi, ctx->vector_number, ctx->error_code, ctx->rax, ctx->rbx, ctx->rcx, ctx->rdx, ctx->rsi, ctx->rdi,
ctx->r8, ctx->r9, ctx->r10, ctx->r11, ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->iret_flags); ctx->r8, ctx->r9, ctx->r10, ctx->r11, ctx->r12, ctx->r13, ctx->r14, ctx->r15, ctx->iret_flags);
if (init.terminal) if (init.terminal) {
{
printf("\r\n\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[48;5;232mat rip=%p\r\nSomething went horribly wrong! (%s) vect=0x%.2x errcode=0x%x\n\rrax=%p rbx=%p rcx=%p rdx=%p\n\rrsi=%p rdi=%p r8=%p r9=%p\n\rr10=%p r11=%p r12=%p r13=%p\n\rr14=%p r15=%p\n\n\rflags=%p\n\rHalting...\x1b[0m", printf("\r\n\x1b[38;5;231m\x1b[48;5;196mKernel panic!!!\x1b[48;5;232mat rip=%p\r\nSomething went horribly wrong! (%s) vect=0x%.2x errcode=0x%x\n\rrax=%p rbx=%p rcx=%p rdx=%p\n\rrsi=%p rdi=%p r8=%p r9=%p\n\rr10=%p r11=%p r12=%p r13=%p\n\rr14=%p r15=%p\n\n\rflags=%p\n\rHalting...\x1b[0m",
ctx->iret_rip, ctx->iret_rip,
str, str,

View File

@@ -1,3 +1,9 @@
/*
* @author xamidev <xamidev@riseup.net>
* @brief Stack trace tools
* @license GPL-3.0-only
*/
#include <stdint.h> #include <stdint.h>
#include "kernel.h" #include "kernel.h"
@@ -6,45 +12,39 @@ extern struct init_status init;
void debug_stack_trace(unsigned int max_frames) void debug_stack_trace(unsigned int max_frames)
{ {
DEBUG("*** begin stack trace ***"); DEBUG("*** begin stack trace ***");
if (init.terminal) if (init.terminal) {
{
printf("\r\n*** begin stack trace ***\r\n"); printf("\r\n*** begin stack trace ***\r\n");
} }
// Thanks GCC :) // Thanks GCC :)
uintptr_t* rbp = (uintptr_t*)__builtin_frame_address(0); uintptr_t* rbp = (uintptr_t*)__builtin_frame_address(0);
for (unsigned int frame=0; frame<max_frames && rbp != NULL; frame++) for (unsigned int frame=0; frame<max_frames && rbp != NULL; frame++) {
{
// Return address, 1 word above saved rbp // Return address, 1 word above saved rbp
uintptr_t rip = rbp[1]; uintptr_t rip = rbp[1];
uintptr_t offset = 0; uintptr_t offset = 0;
const char* name = debug_find_symbol(rip, &offset); const char* name = debug_find_symbol(rip, &offset);
DEBUG("[%u] <0x%p> (%s+0x%x)", frame, (void*)rip, name, offset); DEBUG("[%u] <0x%p> (%s+0x%x)", frame, (void*)rip, name, offset);
if (init.terminal) if (init.terminal) {
{
printf("[%u] <0x%p> (%s+0x%x)\r\n", frame, (void*)rip, name, offset); printf("[%u] <0x%p> (%s+0x%x)\r\n", frame, (void*)rip, name, offset);
} }
uintptr_t* next_rbp = (uintptr_t*)rbp[0]; uintptr_t* next_rbp = (uintptr_t*)rbp[0];
// invalid rbp or we're at the end // Invalid rbp or we're at the end
if (next_rbp <= rbp || next_rbp == NULL) if (next_rbp <= rbp || next_rbp == NULL) {
{
break; break;
} }
rbp = next_rbp; rbp = next_rbp;
} }
if (init.terminal) if (init.terminal) {
{
printf("*** end stack trace ***"); printf("*** end stack trace ***");
} }
DEBUG("*** end stack trace ***"); DEBUG("*** end stack trace ***");
} }
typedef struct typedef struct {
{
uint64_t addr; uint64_t addr;
const char *name; const char *name;
} __attribute__((packed)) kernel_symbol_t; } __attribute__((packed)) kernel_symbol_t;
@@ -55,8 +55,7 @@ __attribute__((weak)) extern uint64_t symbol_count;
// binary search // binary search
const char* debug_find_symbol(uintptr_t rip, uintptr_t* offset) const char* debug_find_symbol(uintptr_t rip, uintptr_t* offset)
{ {
if (!symbol_table || symbol_count == 0) if (!symbol_table || symbol_count == 0) {
{
if (offset) *offset = 0; if (offset) *offset = 0;
return "???"; return "???";
} }
@@ -64,11 +63,9 @@ const char* debug_find_symbol(uintptr_t rip, uintptr_t* offset)
int low = 0, high = (int)symbol_count - 1; int low = 0, high = (int)symbol_count - 1;
int best = -1; int best = -1;
while (low <= high) while (low <= high) {
{
int mid = (low + high) / 2; int mid = (low + high) / 2;
if (symbol_table[mid].addr <= rip) if (symbol_table[mid].addr <= rip) {
{
best = mid; best = mid;
low = mid + 1; low = mid + 1;
} else { } else {
@@ -76,15 +73,15 @@ const char* debug_find_symbol(uintptr_t rip, uintptr_t* offset)
} }
} }
if (best != -1) if (best != -1) {
{ if (offset) {
if (offset)
{
*offset = rip - symbol_table[best].addr; *offset = rip - symbol_table[best].addr;
} }
return symbol_table[best].name; return symbol_table[best].name;
} }
if (offset) *offset = 0; if (offset) {
*offset = 0;
}
return "unknown"; return "unknown";
} }

View File

@@ -53,8 +53,7 @@ void idt_load(void* idt_addr)
void idt_init() void idt_init()
{ {
// Hardcoded... // Hardcoded...
for (size_t i=0; i<=33; i++) for (size_t i=0; i<=KERNEL_IDT_ENTRIES; i++) {
{
// Each vector handler is 16-byte aligned, so <vector_no>*16 = address of that handler // Each vector handler is 16-byte aligned, so <vector_no>*16 = address of that handler
idt_set_entry(i, vector_0_handler + (i*16), 0); idt_set_entry(i, vector_0_handler + (i*16), 0);
} }
@@ -98,8 +97,7 @@ static void gp_fault_handler(struct cpu_status_t* ctx)
(ctx->error_code == 0) ? "NOT_SEGMENT_RELATED" : "SEGMENT_RELATED"); (ctx->error_code == 0) ? "NOT_SEGMENT_RELATED" : "SEGMENT_RELATED");
// Segment-related // Segment-related
if (ctx->error_code != 0) if (ctx->error_code != 0) {
{
bool is_external = CHECK_BIT(ctx->error_code, 0); bool is_external = CHECK_BIT(ctx->error_code, 0);
// is it IDT, GDT, LDT? // is it IDT, GDT, LDT?
uint8_t table = ctx->error_code & 0x6; // 0b110 (isolate table) uint8_t table = ctx->error_code & 0x6; // 0b110 (isolate table)
@@ -118,13 +116,11 @@ static void gp_fault_handler(struct cpu_status_t* ctx)
struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context) struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
{ {
if (context == NULL) if (context == NULL) {
{
panic(NULL, "Interrupt dispatch recieved NULL context!"); panic(NULL, "Interrupt dispatch recieved NULL context!");
} }
switch(context->vector_number) switch(context->vector_number) {
{
case 0: case 0:
panic(context, "Divide Error"); panic(context, "Divide Error");
break; break;
@@ -197,15 +193,13 @@ struct cpu_status_t* interrupt_dispatch(struct cpu_status_t* context)
// Send an EOI so that we can continue having interrupts // Send an EOI so that we can continue having interrupts
outb(0x20, 0x20); outb(0x20, 0x20);
if (ticks % SCHEDULER_QUANTUM == 0) if (ticks % SCHEDULER_QUANTUM == 0) {
{
return scheduler_schedule(context); return scheduler_schedule(context);
} }
break; break;
case 33: case 33: // Keyboard Interrupt
DEBUG("Keyboard Interrupt");
keyboard_handler(); keyboard_handler();
outb(0x20, 0x20); outb(0x20, 0x20);
break; break;

View File

@@ -11,8 +11,7 @@
void idt_init(); void idt_init();
struct interrupt_descriptor struct interrupt_descriptor {
{
uint16_t address_low; uint16_t address_low;
uint16_t selector; uint16_t selector;
uint8_t ist; uint8_t ist;
@@ -22,8 +21,7 @@ struct interrupt_descriptor
uint32_t reserved; uint32_t reserved;
} __attribute__((packed)); } __attribute__((packed));
struct idtr struct idtr {
{
uint16_t limit; uint16_t limit;
uint64_t base; uint64_t base;
} __attribute__((packed)); } __attribute__((packed));
@@ -31,8 +29,7 @@ struct idtr
// All general-purpose registers (except rsp) as stored on the stack, // All general-purpose registers (except rsp) as stored on the stack,
// plus the values we pushed (vector number, error code) and the iret frame // plus the values we pushed (vector number, error code) and the iret frame
// In reverse order because the stack grows downwards. // In reverse order because the stack grows downwards.
struct cpu_status_t struct cpu_status_t {
{
uint64_t r15; uint64_t r15;
uint64_t r14; uint64_t r14;
uint64_t r13; uint64_t r13;

View File

@@ -161,11 +161,9 @@ void keyboard_handler()
unsigned char scancode = inb(0x60); unsigned char scancode = inb(0x60);
// Key release (bit 7 set) // Key release (bit 7 set)
if (scancode & 0x80) if (scancode & 0x80) {
{
unsigned char code = scancode & 0x7F; unsigned char code = scancode & 0x7F;
switch (code) switch (code) {
{
// Clear the corresponding bit if corresponding key is released // Clear the corresponding bit if corresponding key is released
case LEFT_SHIFT_PRESSED: case LEFT_SHIFT_PRESSED:
case RIGHT_SHIFT_PRESSED: case RIGHT_SHIFT_PRESSED:
@@ -179,12 +177,9 @@ void keyboard_handler()
break; break;
} }
return; return;
} } else {
else
{
// Key press // Key press
switch (scancode) switch (scancode) {
{
// Set bits for corresponding special key press // Set bits for corresponding special key press
case LEFT_SHIFT_PRESSED: case LEFT_SHIFT_PRESSED:
case RIGHT_SHIFT_PRESSED: case RIGHT_SHIFT_PRESSED:
@@ -200,15 +195,12 @@ void keyboard_handler()
default: default:
{ {
// Avoiding buffer overflow from extended keys lol // Avoiding buffer overflow from extended keys lol
if (scancode < 128) if (scancode < 128) {
{
// Should we get a SHIFTED char or a regular one? // Should we get a SHIFTED char or a regular one?
unsigned char c = (key_status & SHIFT_PRESSED_BIT) ? keymap_shifted[scancode] : keymap[scancode]; unsigned char c = (key_status & SHIFT_PRESSED_BIT) ? keymap_shifted[scancode] : keymap[scancode];
if (c) if (c) {
{ if (c == '\n') {
if (c == '\n')
{
_putchar('\r'); _putchar('\r');
} }
// Should probably have a keyboard buffer here... instead of this // Should probably have a keyboard buffer here... instead of this
@@ -225,8 +217,7 @@ void keyboard_init(unsigned char layout)
// Here we might go and select PS/2, USB, or other... (once we implement multiple keyboard protocols) // Here we might go and select PS/2, USB, or other... (once we implement multiple keyboard protocols)
// Keyboard layout selection // Keyboard layout selection
switch (layout) switch (layout) {
{
case US: case US:
keymap = kbdus; keymap = kbdus;
keymap_shifted = kbdus_shifted; keymap_shifted = kbdus_shifted;
@@ -242,8 +233,7 @@ void keyboard_init(unsigned char layout)
} }
// Flush keyboard buffer // Flush keyboard buffer
while (inb(0x64) & 1) while (inb(0x64) & 1) {
{
inb(0x60); inb(0x60);
} }

View File

@@ -13,15 +13,13 @@ void keyboard_handler();
#define ALT_PRESSED_BIT 0b00000010 #define ALT_PRESSED_BIT 0b00000010
#define CTRL_PRESSED_BIT 0b00000100 #define CTRL_PRESSED_BIT 0b00000100
enum SpecialKeys enum SpecialKeys {
{
SHIFT = 255, SHIFT = 255,
ALT = 254, ALT = 254,
CTRL = 253 CTRL = 253
}; };
enum SpecialScancodes enum SpecialScancodes {
{
LEFT_SHIFT_PRESSED = 0x2A, LEFT_SHIFT_PRESSED = 0x2A,
LEFT_SHIFT_RELEASED = 0xAA, LEFT_SHIFT_RELEASED = 0xAA,
RIGHT_SHIFT_PRESSED = 0x36, RIGHT_SHIFT_PRESSED = 0x36,
@@ -32,8 +30,7 @@ enum SpecialScancodes
ALT_RELEASED = 0xB8 ALT_RELEASED = 0xB8
}; };
enum KeyboardLayout enum KeyboardLayout {
{
US, US,
FR FR
}; };

View File

@@ -21,9 +21,6 @@ unsigned char inb(int port)
return data; return data;
} }
// COM1
#define PORT 0x3F8
int serial_init() int serial_init()
{ {
outb(PORT + 1, 0x00); // Disable all interrupts outb(PORT + 1, 0x00); // Disable all interrupts
@@ -36,8 +33,7 @@ int serial_init()
outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip outb(PORT + 4, 0x1E); // Set in loopback mode, test the serial chip
outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte) outb(PORT + 0, 0xAE); // Test serial chip (send byte 0xAE and check if serial returns same byte)
if (inb(PORT) != 0xAE) if (inb(PORT) != 0xAE) {
{
return -EIO; return -EIO;
} }
@@ -66,8 +62,7 @@ void skputc(char c)
void skputs(const char* str) void skputs(const char* str)
{ {
unsigned int i=0; unsigned int i=0;
while (str[i]) while (str[i]) {
{
skputc(str[i]); skputc(str[i]);
i++; i++;
} }

View File

@@ -7,6 +7,9 @@
#ifndef SERIAL_H #ifndef SERIAL_H
#define SERIAL_H #define SERIAL_H
// COM1
#define PORT 0x3F8
void outb(int port, unsigned char data); void outb(int port, unsigned char data);
unsigned char inb(int port); unsigned char inb(int port);

View File

@@ -34,8 +34,7 @@ void _putchar(char character)
void kputs(const char* str) void kputs(const char* str)
{ {
size_t i=0; size_t i=0;
while (str[i] != 0) while (str[i] != 0) {
{
_putchar(str[i]); _putchar(str[i]);
i++; i++;
} }

View File

@@ -7,8 +7,7 @@
#ifndef KERNEL_H #ifndef KERNEL_H
#define KERNEL_H #define KERNEL_H
enum ErrorCodes enum ErrorCodes {
{
ENOMEM, ENOMEM,
EIO EIO
}; };
@@ -47,8 +46,7 @@ void boot_mem_display();
#define assert(check) do { if(!(check)) hcf(); } while(0) #define assert(check) do { if(!(check)) hcf(); } while(0)
struct boot_context struct boot_context {
{
struct limine_framebuffer* fb; struct limine_framebuffer* fb;
struct limine_memmap_response* mmap; struct limine_memmap_response* mmap;
struct limine_hhdm_response* hhdm; struct limine_hhdm_response* hhdm;
@@ -56,8 +54,7 @@ struct boot_context
}; };
// Are these modules initialized yet? // Are these modules initialized yet?
struct init_status struct init_status {
{
bool terminal; bool terminal;
bool serial; bool serial;
bool keyboard; bool keyboard;

View File

@@ -65,8 +65,7 @@ void pedicel_main(void* arg)
void idle_main(void* arg) void idle_main(void* arg)
{ {
for (;;) for (;;) {
{
asm("hlt"); asm("hlt");
} }
} }
@@ -89,10 +88,10 @@ void kmain()
boot_ctx.kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL; boot_ctx.kaddr = kerneladdr_request.response ? kerneladdr_request.response : NULL;
boot_mem_display(); boot_mem_display();
pmm_init(boot_ctx.mmap, boot_ctx.hhdm); pmm_init(boot_ctx);
// Remap kernel , HHDM and framebuffer // Remap kernel , HHDM and framebuffer
paging_init(boot_ctx.kaddr, boot_ctx.fb); paging_init(boot_ctx);
kheap_init(); kheap_init();
keyboard_init(FR); keyboard_init(FR);

View File

@@ -21,8 +21,7 @@
#define USER_CODE_SEGMENT 0x18 #define USER_CODE_SEGMENT 0x18
#define USER_DATA_SEGMENT 0x20 #define USER_DATA_SEGMENT 0x20
struct GDTR struct GDTR {
{
uint16_t limit; uint16_t limit;
uint64_t address; uint64_t address;
} __attribute__((packed)); } __attribute__((packed));

View File

@@ -33,11 +33,9 @@ void kheap_init()
uintptr_t current_addr = kheap_start; uintptr_t current_addr = kheap_start;
// Map/alloc enough pages for heap (KHEAP_SIZE) // Map/alloc enough pages for heap (KHEAP_SIZE)
for (size_t i=0; i<heap_pages; i++) for (size_t i=0; i<heap_pages; i++) {
{
uintptr_t phys = pmm_alloc(); uintptr_t phys = pmm_alloc();
if (phys == 0) if (phys == 0) {
{
panic(NULL, "Not enough memory available to initialize kernel heap."); panic(NULL, "Not enough memory available to initialize kernel heap.");
} }
@@ -63,15 +61,11 @@ void* kmalloc(size_t size)
struct heap_block_t* curr = head; struct heap_block_t* curr = head;
while (curr) while (curr) {
{
// Is block free and big enough for us? // Is block free and big enough for us?
if (curr->free && curr->size >= size) if (curr->free && curr->size >= size) {
{
// We split the block if it is big enough // We split the block if it is big enough
if (curr->size >= size + sizeof(struct heap_block_t) + 16) if (curr->size >= size + sizeof(struct heap_block_t) + 16) {
{
//struct heap_block_t* new_block = (struct heap_block_t*)((uintptr_t)curr + sizeof(struct heap_block_t) + size);
struct heap_block_t* split = (struct heap_block_t*)((uintptr_t)curr + sizeof(struct heap_block_t) + size); struct heap_block_t* split = (struct heap_block_t*)((uintptr_t)curr + sizeof(struct heap_block_t) + size);
split->size = curr->size - size - sizeof(struct heap_block_t); split->size = curr->size - size - sizeof(struct heap_block_t);
@@ -109,10 +103,8 @@ void kfree(void* ptr)
// merge adjacent free blocks (coalescing) // merge adjacent free blocks (coalescing)
struct heap_block_t* curr = head; struct heap_block_t* curr = head;
while (curr && curr->next) while (curr && curr->next) {
{ if (curr->free && curr->next->free) {
if (curr->free && curr->next->free)
{
curr->size += sizeof(*curr) + curr->next->size; curr->size += sizeof(*curr) + curr->next->size;
curr->next = curr->next->next; curr->next = curr->next->next;
continue; continue;

View File

@@ -16,8 +16,7 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
struct heap_block_t struct heap_block_t {
{
size_t size; size_t size;
bool free; // 1byte bool free; // 1byte
uint8_t reserved[7]; // (7+1 = 8 bytes) uint8_t reserved[7]; // (7+1 = 8 bytes)

View File

@@ -21,8 +21,7 @@ void* memcpy(void* restrict dest, const void* restrict src, size_t n)
uint8_t* restrict pdest = (uint8_t* restrict)dest; uint8_t* restrict pdest = (uint8_t* restrict)dest;
const uint8_t* restrict psrc = (const uint8_t* restrict)src; const uint8_t* restrict psrc = (const uint8_t* restrict)src;
for (size_t i=0; i<n; i++) for (size_t i=0; i<n; i++) {
{
pdest[i] = psrc[i]; pdest[i] = psrc[i];
} }
@@ -33,8 +32,7 @@ void* memset(void* s, int c, size_t n)
{ {
uint8_t* p = (uint8_t*)s; uint8_t* p = (uint8_t*)s;
for (size_t i=0; i<n; i++) for (size_t i=0; i<n; i++) {
{
p[i] = (uint8_t)c; p[i] = (uint8_t)c;
} }
@@ -46,16 +44,12 @@ void* memmove(void *dest, const void* src, size_t n)
uint8_t* pdest = (uint8_t*)dest; uint8_t* pdest = (uint8_t*)dest;
const uint8_t* psrc = (uint8_t*)src; const uint8_t* psrc = (uint8_t*)src;
if (src > dest) if (src > dest) {
{ for (size_t i=0; i<n; i++) {
for (size_t i=0; i<n; i++)
{
pdest[i] = psrc[i]; pdest[i] = psrc[i];
} }
} else if (src < dest) } else if (src < dest) {
{ for (size_t i=n; i>0; i--) {
for (size_t i=n; i>0; i--)
{
pdest[i-1] = psrc[i-1]; pdest[i-1] = psrc[i-1];
} }
} }
@@ -67,10 +61,8 @@ int memcmp(const void* s1, const void* s2, size_t n)
const uint8_t* p1 = (const uint8_t*)s1; const uint8_t* p1 = (const uint8_t*)s1;
const uint8_t* p2 = (const uint8_t*)s2; const uint8_t* p2 = (const uint8_t*)s2;
for (size_t i=0; i<n; i++) for (size_t i=0; i<n; i++) {
{ if (p1[i] != p2[i]) {
if (p1[i] != p2[i])
{
return p1[i] < p2[i] ? -1 : 1; return p1[i] < p2[i] ? -1 : 1;
} }
} }

View File

@@ -39,8 +39,7 @@ static uint64_t* alloc_page_table()
{ {
uint64_t* virt = (uint64_t*)PHYS_TO_VIRT(pmm_alloc()); uint64_t* virt = (uint64_t*)PHYS_TO_VIRT(pmm_alloc());
for (size_t i=0; i<512; i++) for (size_t i=0; i<512; i++) {
{
virt[i] = 0; virt[i] = 0;
} }
return virt; return virt;
@@ -70,32 +69,26 @@ void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_
// PML4 // PML4
// If the entry at index is not present, allocate enough space for it // If the entry at index is not present, allocate enough space for it
// then populate the entry with correct addr + flags // then populate the entry with correct addr + flags
if (!(root_table[pml4_i] & PTE_PRESENT)) if (!(root_table[pml4_i] & PTE_PRESENT)) {
{
pdpt = alloc_page_table(); pdpt = alloc_page_table();
root_table[pml4_i] = VIRT_TO_PHYS(pdpt) | PTE_PRESENT | PTE_WRITABLE; root_table[pml4_i] = VIRT_TO_PHYS(pdpt) | PTE_PRESENT | PTE_WRITABLE;
} } else {
else {
pdpt = (uint64_t *)PHYS_TO_VIRT(root_table[pml4_i] & PTE_ADDR_MASK); pdpt = (uint64_t *)PHYS_TO_VIRT(root_table[pml4_i] & PTE_ADDR_MASK);
} }
// PDPT: same here // PDPT: same here
if (!(pdpt[pdpt_i] & PTE_PRESENT)) if (!(pdpt[pdpt_i] & PTE_PRESENT)) {
{
pd = alloc_page_table(); pd = alloc_page_table();
pdpt[pdpt_i] = VIRT_TO_PHYS(pd) | PTE_PRESENT | PTE_WRITABLE; pdpt[pdpt_i] = VIRT_TO_PHYS(pd) | PTE_PRESENT | PTE_WRITABLE;
} } else {
else {
pd = (uint64_t *)PHYS_TO_VIRT(pdpt[pdpt_i] & PTE_ADDR_MASK); pd = (uint64_t *)PHYS_TO_VIRT(pdpt[pdpt_i] & PTE_ADDR_MASK);
} }
// PD: and here // PD: and here
if (!(pd[pd_i] & PTE_PRESENT)) if (!(pd[pd_i] & PTE_PRESENT)) {
{
pt = alloc_page_table(); pt = alloc_page_table();
pd[pd_i] = VIRT_TO_PHYS(pt) | PTE_PRESENT | PTE_WRITABLE; pd[pd_i] = VIRT_TO_PHYS(pt) | PTE_PRESENT | PTE_WRITABLE;
} } else {
else {
pt = (uint64_t *)PHYS_TO_VIRT(pd[pd_i] & PTE_ADDR_MASK); pt = (uint64_t *)PHYS_TO_VIRT(pd[pd_i] & PTE_ADDR_MASK);
} }
@@ -109,9 +102,7 @@ void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_
uint64_t kernel_phys_base; uint64_t kernel_phys_base;
uint64_t kernel_virt_base; uint64_t kernel_virt_base;
extern struct boot_context boot_ctx; void paging_init(struct boot_context boot_ctx)
void paging_init()
{ {
// We should map the kernel, GDT, IDT, stack, framebuffer. // We should map the kernel, GDT, IDT, stack, framebuffer.
// Optionally we could map ACPI tables (we can find them in the Limine memmap) // Optionally we could map ACPI tables (we can find them in the Limine memmap)
@@ -129,31 +120,25 @@ void paging_init()
// Find max physical address from limine memmap // Find max physical address from limine memmap
uint64_t max_phys = 0; uint64_t max_phys = 0;
for (uint64_t i=0; i<boot_ctx.mmap->entry_count; i++) for (uint64_t i=0; i<boot_ctx.mmap->entry_count; i++) {
{
struct limine_memmap_entry* entry = boot_ctx.mmap->entries[i]; struct limine_memmap_entry* entry = boot_ctx.mmap->entries[i];
if (entry->length == 0) if (entry->length == 0) {
{
continue; continue;
} }
uint64_t top = entry->base + entry->length; uint64_t top = entry->base + entry->length;
if (top > max_phys) if (top > max_phys) {
{
max_phys = top; max_phys = top;
} }
} }
// 4GB // 4GB
if (max_phys > 0x100000000) if (max_phys > PAGING_MAX_PHYS) {
{ DEBUG("WARNING: max_phys capped to 4GB (%x) (from max_phys=%p)", PAGING_MAX_PHYS, max_phys);
DEBUG("WARNING: max_phys capped to 4GB (0x100000000) (from max_phys=%p)", max_phys); max_phys = PAGING_MAX_PHYS;
max_phys = 0x100000000;
} }
// HHDM map up to max_phys or 4GB, whichever is smaller, using given offset // HHDM map up to max_phys or PAGING_MAX_PHYS, whichever is smaller, using given offset
for (uint64_t i=0; i<max_phys; i += PAGE_SIZE) for (uint64_t i=0; i<max_phys; i += PAGE_SIZE) {
{
//paging_kmap_page(i+hhdm_off, i, PTE_WRITABLE);
paging_map_page(kernel_pml4, i+hhdm_off, i, PTE_WRITABLE | PTE_PRESENT); paging_map_page(kernel_pml4, i+hhdm_off, i, PTE_WRITABLE | PTE_PRESENT);
page_count++; page_count++;
} }
@@ -163,9 +148,7 @@ void paging_init()
// SOME DAY when we want a safer kernel we should map .text as Read/Exec // SOME DAY when we want a safer kernel we should map .text as Read/Exec
// .rodata as Read and .data as Read/Write // .rodata as Read and .data as Read/Write
// For now who gives a shit, let's RWX all kernel // For now who gives a shit, let's RWX all kernel
for (uint64_t i = 0; i < KERNEL_SIZE; i += PAGE_SIZE) for (uint64_t i = 0; i < KERNEL_SIZE; i += PAGE_SIZE) {
{
//paging_kmap_page(kernel_virt_base+i, kernel_phys_base+i, PTE_WRITABLE);
paging_map_page(kernel_pml4, kernel_virt_base+i, kernel_phys_base+i, PTE_WRITABLE); paging_map_page(kernel_pml4, kernel_virt_base+i, kernel_phys_base+i, PTE_WRITABLE);
page_count++; page_count++;
} }
@@ -178,9 +161,7 @@ void paging_init()
uint64_t fb_pages = (fb_size + PAGE_SIZE-1)/PAGE_SIZE; uint64_t fb_pages = (fb_size + PAGE_SIZE-1)/PAGE_SIZE;
// Map the framebuffer (with cache-disable & write-through) // Map the framebuffer (with cache-disable & write-through)
for (uint64_t i=0; i<fb_pages; i++) for (uint64_t i=0; i<fb_pages; i++) {
{
//paging_kmap_page(fb_virt+i*PAGE_SIZE, fb_phys+i*PAGE_SIZE, PTE_WRITABLE | PTE_PCD | PTE_PWT);
paging_map_page(kernel_pml4, fb_virt+i*PAGE_SIZE, fb_phys+i*PAGE_SIZE, PTE_WRITABLE | PTE_PCD | PTE_PWT); paging_map_page(kernel_pml4, fb_virt+i*PAGE_SIZE, fb_phys+i*PAGE_SIZE, PTE_WRITABLE | PTE_PCD | PTE_PWT);
page_count++; page_count++;
} }

View File

@@ -12,8 +12,9 @@
#include <stdint.h> #include <stdint.h>
#include <limine.h> #include <limine.h>
#include "mem/heap/kheap.h" #include "mem/heap/kheap.h"
#include <kernel.h>
void paging_init(); void paging_init(struct boot_context boot_ctx);
void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_t flags); void paging_map_page(uint64_t* root_table, uint64_t virt, uint64_t phys, uint64_t flags);
// To swap root page tables // To swap root page tables

View File

@@ -38,12 +38,10 @@ static void pmm_find_biggest_usable_region(struct limine_memmap_response* memmap
uint64_t offset = hhdm->offset; uint64_t offset = hhdm->offset;
DEBUG("Usable Memory:"); DEBUG("Usable Memory:");
for (size_t i=0; i<memmap->entry_count; i++) for (size_t i=0; i<memmap->entry_count; i++) {
{
struct limine_memmap_entry* entry = memmap->entries[i]; struct limine_memmap_entry* entry = memmap->entries[i];
if (entry->type == LIMINE_MEMMAP_USABLE) if (entry->type == LIMINE_MEMMAP_USABLE) {
{
DEBUG("0x%p-0x%p mapped at 0x%p-0x%p", entry->base, entry->base+entry->length, DEBUG("0x%p-0x%p mapped at 0x%p-0x%p", entry->base, entry->base+entry->length,
entry->base+offset, entry->base+entry->length+offset); entry->base+offset, entry->base+entry->length+offset);
if (entry->length > length_max) if (entry->length > length_max)
@@ -66,8 +64,7 @@ static uintptr_t g_freelist = 0;
uintptr_t pmm_alloc() uintptr_t pmm_alloc()
{ {
if (!g_freelist) if (!g_freelist) {
{
panic(NULL, "PMM is out of memory!"); panic(NULL, "PMM is out of memory!");
} }
uintptr_t addr = g_freelist; uintptr_t addr = g_freelist;
@@ -89,19 +86,17 @@ static void pmm_init_freelist()
uint64_t end = ALIGN_DOWN(biggest_entry->base + biggest_entry->length, PAGE_SIZE); uint64_t end = ALIGN_DOWN(biggest_entry->base + biggest_entry->length, PAGE_SIZE);
uint64_t page_count=0; uint64_t page_count=0;
for (uint64_t addr = base; addr < end; addr += PAGE_SIZE) for (uint64_t addr = base; addr < end; addr += PAGE_SIZE) {
{
pmm_free(addr); pmm_free(addr);
//DEBUG("page %u lives at phys 0x%p (virt 0x%p)", page_count, addr, PHYS_TO_VIRT(addr));
page_count++; page_count++;
} }
DEBUG("%u frames in freelist, available for use (%u bytes)", page_count, page_count*PAGE_SIZE); DEBUG("%u frames in freelist, available for use (%u bytes)", page_count, page_count*PAGE_SIZE);
} }
void pmm_init(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm) void pmm_init(struct boot_context boot_ctx)
{ {
hhdm_off = hhdm->offset; hhdm_off = boot_ctx.hhdm->offset;
pmm_find_biggest_usable_region(memmap, hhdm); pmm_find_biggest_usable_region(boot_ctx.mmap, boot_ctx.hhdm);
// Now we have biggest USABLE region, // Now we have biggest USABLE region,
// so to populate the free list we just iterate through it // so to populate the free list we just iterate through it

View File

@@ -8,8 +8,9 @@
#define PAGING_PMM_H #define PAGING_PMM_H
#include <limine.h> #include <limine.h>
#include <kernel.h>
void pmm_init(struct limine_memmap_response* memmap, struct limine_hhdm_response* hhdm); void pmm_init(struct boot_context boot_ctx);
void pmm_free(uintptr_t addr); void pmm_free(uintptr_t addr);
uintptr_t pmm_alloc(); uintptr_t pmm_alloc();

View File

@@ -16,8 +16,7 @@ Flags here aren't x86 flags, they are platform-agnostic
kernel-defined flags. kernel-defined flags.
*/ */
struct vm_object struct vm_object {
{
uintptr_t base; uintptr_t base;
size_t length; size_t length;
size_t flags; size_t flags;

View File

@@ -34,8 +34,7 @@ void process_display_list(struct process_t* processes_list)
{ {
int process_view_id = 0; int process_view_id = 0;
struct process_t* tmp = processes_list; struct process_t* tmp = processes_list;
while (tmp != NULL) while (tmp != NULL) {
{
DEBUG("{%d: %p} -> ", process_view_id, tmp); DEBUG("{%d: %p} -> ", process_view_id, tmp);
tmp = tmp->next; tmp = tmp->next;
process_view_id++; process_view_id++;
@@ -47,7 +46,6 @@ struct process_t* process_create(char* name, void(*function)(void*), void* arg)
{ {
CLEAR_INTERRUPTS; CLEAR_INTERRUPTS;
struct process_t* proc = (struct process_t*)kmalloc(sizeof(struct process_t)); struct process_t* proc = (struct process_t*)kmalloc(sizeof(struct process_t));
struct cpu_status_t* ctx = (struct cpu_status_t*)kmalloc(sizeof(struct cpu_status_t)); struct cpu_status_t* ctx = (struct cpu_status_t*)kmalloc(sizeof(struct cpu_status_t));
// No more memory? // No more memory?
@@ -88,29 +86,25 @@ void process_add(struct process_t** processes_list, struct process_t* process)
if (!process) return; if (!process) return;
process->next = NULL; process->next = NULL;
if (*processes_list == NULL) if (*processes_list == NULL) {
{
// List is empty // List is empty
*processes_list = process; *processes_list = process;
return; return;
} }
struct process_t* tmp = *processes_list; struct process_t* tmp = *processes_list;
while (tmp->next != NULL) while (tmp->next != NULL) {
{
tmp = tmp->next; tmp = tmp->next;
} }
// We're at last process before NULL // We're at last process before NULL
tmp->next = process; tmp->next = process;
// process->next = NULL;
} }
void process_delete(struct process_t** processes_list, struct process_t* process) void process_delete(struct process_t** processes_list, struct process_t* process)
{ {
if (!processes_list || !*processes_list || !process) return; if (!processes_list || !*processes_list || !process) return;
if (*processes_list == process) if (*processes_list == process) {
{
// process to delete is at head // process to delete is at head
*processes_list = process->next; *processes_list = process->next;
process->next = NULL; process->next = NULL;
@@ -119,13 +113,11 @@ void process_delete(struct process_t** processes_list, struct process_t* process
} }
struct process_t* tmp = *processes_list; struct process_t* tmp = *processes_list;
while (tmp->next && tmp->next != process) while (tmp->next && tmp->next != process) {
{
tmp = tmp->next; tmp = tmp->next;
} }
if (tmp->next == NULL) if (tmp->next == NULL) {
{
// Didn't find the process // Didn't find the process
return; return;
} }
@@ -148,15 +140,12 @@ void process_exit()
{ {
DEBUG("Exiting from process '%s'", current_process->name); DEBUG("Exiting from process '%s'", current_process->name);
CLEAR_INTERRUPTS; CLEAR_INTERRUPTS;
if (current_process) if (current_process) {
{
current_process->status = DEAD; current_process->status = DEAD;
} }
SET_INTERRUPTS; SET_INTERRUPTS;
//outb(0x20, 0x20); for (;;) {
for (;;)
{
asm("hlt"); asm("hlt");
} }
} }

View File

@@ -11,15 +11,13 @@
#include "config.h" #include "config.h"
#include <stdint.h> #include <stdint.h>
typedef enum typedef enum {
{
READY, READY,
RUNNING, RUNNING,
DEAD DEAD
} status_t; } status_t;
struct process_t struct process_t {
{
size_t pid; size_t pid;
char name[PROCESS_NAME_MAX]; char name[PROCESS_NAME_MAX];

View File

@@ -22,13 +22,11 @@ void scheduler_init()
struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context) struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
{ {
if (context == NULL) if (context == NULL) {
{
panic(NULL, "Scheduler called with NULL context"); panic(NULL, "Scheduler called with NULL context");
} }
if (current_process == NULL) if (current_process == NULL) {
{
// If no more processes, then set IDLE as the current process, that's it. // If no more processes, then set IDLE as the current process, that's it.
current_process = idle_proc; current_process = idle_proc;
} }
@@ -38,21 +36,17 @@ struct cpu_status_t* scheduler_schedule(struct cpu_status_t* context)
for (;;) { for (;;) {
struct process_t* prev_process = current_process; struct process_t* prev_process = current_process;
if (current_process->next != NULL) if (current_process->next != NULL) {
{
current_process = current_process->next; current_process = current_process->next;
} else } else {
{
current_process = processes_list; current_process = processes_list;
} }
if (current_process != NULL && current_process->status == DEAD) if (current_process != NULL && current_process->status == DEAD) {
{
process_delete(&prev_process, current_process); process_delete(&prev_process, current_process);
current_process = NULL; current_process = NULL;
return idle_proc->context; return idle_proc->context;
} else } else {
{
current_process->status = RUNNING; current_process->status = RUNNING;
break; break;
} }

View File

@@ -14,12 +14,14 @@ char* strcpy(char *dest, const char *src)
} }
// https://stackoverflow.com/questions/2488563/strcat-implementation // https://stackoverflow.com/questions/2488563/strcat-implementation
char *strcat(char *dest, const char *src){ char *strcat(char *dest, const char *src)
{
size_t i,j; size_t i,j;
for (i = 0; dest[i] != '\0'; i++) for (i = 0; dest[i] != '\0'; i++);
;
for (j = 0; src[j] != '\0'; j++) for (j = 0; src[j] != '\0'; j++)
dest[i+j] = src[j]; dest[i+j] = src[j];
dest[i+j] = '\0'; dest[i+j] = '\0';
return dest; return dest;
} }

View File

@@ -78,8 +78,7 @@ void pit_init()
void timer_wait(uint64_t wait_ticks) void timer_wait(uint64_t wait_ticks)
{ {
uint64_t then = ticks + wait_ticks; uint64_t then = ticks + wait_ticks;
while (ticks < then) while (ticks < then) {
{
asm("hlt"); asm("hlt");
}; };
} }