From 63a238d2c4133f11dbe3a213f9f8c88980466722 Mon Sep 17 00:00:00 2001 From: Tom-on64 Date: Thu, 26 Mar 2026 21:07:29 +0100 Subject: [PATCH] The printk(), panic() and kernel.h update --- config.mk | 6 +- kernel/include/ctype.h | 33 ++++++ kernel/include/kernel.h | 176 +++++++++++-------------------- kernel/include/paging.h | 2 +- kernel/include/serial.h | 8 +- kernel/include/stdarg.h | 9 ++ kernel/include/types.h | 44 ++++++++ kernel/include/vsnprintf.h | 4 +- kernel/makefile | 2 +- kernel/src/ctype.c | 115 ++++++++++++++++++++ kernel/src/isr.c | 21 ++-- kernel/src/{kernel.c => kmain.c} | 9 +- kernel/src/paging.c | 6 +- kernel/src/panic.c | 33 ++++++ kernel/src/pmm.c | 9 +- kernel/src/printk.c | 28 +++++ kernel/src/serial.c | 10 +- kernel/src/vsnprintf.c | 4 +- 18 files changed, 366 insertions(+), 153 deletions(-) create mode 100644 kernel/include/ctype.h create mode 100644 kernel/include/stdarg.h create mode 100644 kernel/include/types.h create mode 100644 kernel/src/ctype.c rename kernel/src/{kernel.c => kmain.c} (93%) create mode 100644 kernel/src/panic.c create mode 100644 kernel/src/printk.c diff --git a/config.mk b/config.mk index ebbaa98..1fc34d0 100644 --- a/config.mk +++ b/config.mk @@ -12,9 +12,10 @@ HOSTCCFLAGS = -Wall -Wextra -O2 CCFLAGS = -Wall -Wextra -m64 -ffreestanding -fcommon -Iinclude \ -mcmodel=kernel \ -fno-pie \ - -fno-stack-protector \ + -fno-omit-frame-pointer \ -mno-mmx \ -mno-80387 \ + -fno-stack-protector \ -mno-red-zone \ -nostartfiles \ -nostdlib \ @@ -26,6 +27,9 @@ LDFLAGS = -melf_x86_64 -nostdlib -static \ -z text -z max-page-size=0x1000 ARFLAGS = +# Kernel config +CONSOLE_LOGLEVEL=7 + # Disk image IMG_NAME = disk.img IMG_SIZE = 256 # 256MB diff --git a/kernel/include/ctype.h b/kernel/include/ctype.h new file mode 100644 index 0000000..b2ba33d --- /dev/null +++ b/kernel/include/ctype.h @@ -0,0 +1,33 @@ +#ifndef _CTYPE_H +#define _CTYPE_H + +#define _DIGIT_MASK (1<<0) +#define _ALPHA_MASK (1<<1) +#define _LOWER_MASK (1<<2) +#define _PUNCT_MASK (1<<3) +#define _SPACE_MASK (1<<4) +#define _CNTRL_MASK (1<<5) +#define _PRINT_MASK (1<<6) +#define _HEXDG_MASK (1<<7) + +// A table for the ASCII character set +extern const unsigned char _CTYPE_TABLE[256]; + +// Just a macro to make this easier +#define _CTYPE_CHECK(_c, _mask) (_CTYPE_TABLE[(unsigned char)(_c)] & (_mask)) + +#define isalnum(_c) (isalpha((_c)) || isdigit((_c)) +#define isalpha(_c) _CTYPE_CHECK((_c), _ALPHA_MASK) +#define islower(_c) _CTYPE_CHECK((_c), _LOWER_MASK) +#define isupper(_c) (!islower((_c)) && isalpha((_c))) +#define isdigit(_c) _CTYPE_CHECK((_c), _DIGIT_MASK) +#define iscntrl(_c) _CTYPE_CHECK((_c), _CNTRL_MASK) +#define isgraph(_c) (!isblank((_c))) +#define isspace(_c) _CTYPE_CHECK((_c), _SPACE_MASK) +#define isblank(_c) (iscntrl((_c)) || isspace((_c))) +#define isprint(_c) _CTYPE_CHECK((_c), _PRINT_MASK) +#define ispunct(_c) _CTYPE_CHECK((_c), _PUNCT_MASK) +// Why is this one's name longer :(( +#define isxdigit(_c) _CTYPE_CHECK((_c), _HEXDG_MASK); + +#endif diff --git a/kernel/include/kernel.h b/kernel/include/kernel.h index 9dda247..3b611df 100644 --- a/kernel/include/kernel.h +++ b/kernel/include/kernel.h @@ -1,137 +1,85 @@ #ifndef _KERNEL_H #define _KERNEL_H -// Null definition -#define NULL ((void*)0) +#include +#include -/* - * Virtual memory addresses - */ -#define USER_HEAP 0x10000000 -#define USER_SHARED 0xA0000000 -#define USER_STACK 0xBF000000 -#define KERNEL_BASE 0xC0000000 -#define KERNEL_SIZE 0x10000000 -#define KERNEL_HEAP_BASE 0xD0000000 -#define KERNEL_HEAP_SIZE 0x10000000 -#define KERNEL_SHARED 0xF0000000 -#define KERNEL_FRAMEBUF 0xC8000000 - -/* - * Variable arguments - */ -//typedef struct { unsigned int gp_off; unsigned int fp_off; void *arg_overflow; void *reg_save; } va_list; -typedef __builtin_va_list va_list; -#define va_start(_ap, _last) __builtin_va_start(_ap, _last) -#define va_end(_ap) __builtin_va_end(_ap) -#define va_arg(_ap, _type) __builtin_va_arg(_ap, _type) - -/* - * Utility macros - */ - -// Assertions -#define STATIC_ASSERT(_cond, _msg)\ - typedef int static_assert_##_msg[(_cond) ? 1 : -1] - -// Array -#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0])) -#define array_sizeof ARRAY_SIZE -#define container_of(_p, _t, _m) \ - ((_t*)((char*)(_p) - offsetof(_t, _m))) - -// Align -#define ALIGN(x, a) __ALIGN_MASK((x), (typeof(x))(a) - 1) -#define ALIGN_DOWN(x, a) ((x) & ~((typeof(x))(a) - 1)) -#define __ALIGN_MASK(x, mask) (((x) + (mask)) & ~(mask)) -#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) -#define PTR_ALIGN_DOWN(p, a) ((typeof(p))ALIGN_DOWN((unsigned long)(p), (a))) - -// Bit -#define BIT(_n) (1UL << (_n)) -#define BIT_MASK(_n) (BIT(_n) - 1) - -// Math -#define swap(_a, _b) ({ typeof(_a) _tmp = (_a); (_a) = (_b); (_b) = (_a); }) -#define min(_x, _y) ({ typeof(_x) __x = (_x); typeof(_y) __y = (_y); __x < __y ? __x : __y; }) -#define max(_x, _y) ({ typeof(_x) __x = (_x); typeof(_y) __y = (_y); __x > __y ? __x : __y; }) -#define ceil(_x, _y) ((((_x) + (_y)) (_y)) * (_y)) -#define floor(_x, _y) ((_x) - ((_x) % (_y))) -#define dceil(_x, _y) (((_x) + (_y) - 1) / (_y)) - -// Misc -#define fence() __asm__ volatile ("":::"memory") - -/* - * Attribute definitions - */ -#define __align(_b) __attribute__((aligned(_b))) +#define __alias(symbol) __attribute__((alias(#symbol))) +#define __align(x) __attribute__((aligned(x))) +#define __printf(a, b) __attribute__((format(printf, a, b))) +#define __scanf(a, b) __attribute__((format(scanf, a, b))) +#define __align_largest __attribute__((aligned)) #define __depricated __attribute__((depricated)) #define __packed __attribute__((packed)) #define __noreturn __attribute__((noreturn)) #define __const __attribute__((const)) #define __pure __attribute__((pure)) -#define __inline __attribute__((always_inline)) -#define __no_inline __attribute__((never_inline)) #define __section(_s) __attribute__((section(_s))) #define __cold __attribute__((cold)) #define __hot __attribute__((hot)) #define __naked __attribute__((naked)) +#define __always_inline __attribute__((always_inline)) +#define noinline __attribute__((never_inline)) -/* - * Standard int types - */ -typedef unsigned char uint8_t; -typedef unsigned short uint16_t; -typedef unsigned int uint32_t; -typedef unsigned long uint64_t; -typedef signed char int8_t; -typedef signed short int16_t; -typedef signed int int32_t; -typedef signed long int64_t; +#define ALIGN(_addr, _align) (((_addr) + (_align) - 1) & ~((_align) - 1)) +#define ALIGN_DOWN(_addr, _align) ((_addr) & ~((_align) - 1)) +#define BIT(_n) (1ULL << (_n)) -typedef uint64_t size_t; -typedef int64_t ssize_t; +#define min(_a, _b) ((_a) < (_b) ? (_a) : (_b)) +#define max(_a, _b) ((_a) > (_b) ? (_a) : (_b)) -typedef uint64_t uintptr_t; -typedef int64_t intptr_t; +#define fence() __asm__ volatile ("" ::: "memory") + +#define KERN_SOH "\001" +#define KERN_SOH_ASCII '\001' +#define KERN_EMERG KERN_SOH "0" +#define KERN_ALERT KERN_SOH "1" +#define KERN_CRIT KERN_SOH "2" +#define KERN_ERROR KERN_SOH "3" +#define KERN_WARNING KERN_SOH "4" +#define KERN_NOTICE KERN_SOH "5" +#define KERN_INFO KERN_SOH "6" +#define KERN_DEBUG KERN_SOH "7" +#define KERN_DEFAULT "" -typedef uint64_t offset_t; +#define LOGLEVEL_EMERG 0 +#define LOGLEVEL_ALERT 1 +#define LOGLEVEL_CRIT 2 +#define LOGLEVEL_ERROR 3 +#define LOGLEVEL_WARNING 4 +#define LOGLEVEL_NOTICE 5 +#define LOGLEVEL_INFO 6 +#define LOGLEVEL_DEBUG 7 -/* - * Boolean - */ -#define bool _Bool -#define true 1 -#define false 0 +#ifndef LOGLEVEL_DEFAULT +#define LOGLEVEL_DEFAULT LOGLEVEL_ERROR +#endif -/* - * System types - */ -typedef uint32_t pid_t; +#ifndef CONSOLE_LOGLEVEL +#define CONSOLE_LOGLEVEL 4 +#endif -/* - * Linker defined values - */ -extern uint64_t __kernel_start, __kernel_text_start, __kernel_rodata_start, __kernel_data_start; -extern uint64_t __kernel_end, __kernel_text_end, __kernel_rodata_end, __kernel_data_end; +extern uint8_t console_loglevel; -/* - * Logging and errors - * TODO: Use something other than debugf() - */ -#include -#define printk debugf -#define pr_dbg(_s) printk("[debug] %s\n", (_s)) -#define pr_wrn(_s) printk("[warning] %s\n", (_s)) -#define pr_err(_s) printk("[error] %s\n", (_s)) -#define panic(_s) do {\ - printk("[kernel] Panic! %s", (_s));\ - while (1) __asm__ volatile ("cli; hlt");\ - } while (0) -#define BUG() panic("BUG()") -#define WARN() pr_wrn("WARN()") -#define BUG_ON(_e) ((_e) ? BUG() : NULL) -#define WARN_ON(_e) ((_e) ? WARN() : NULL) +// TODO: Add a ring buffer for the logs +int printk(const char* fmt, ...); +int vprintk(const char* fmt, va_list ap); + +#define pr_emerg(fmt, ...) printk(KERN_EMERG fmt, ##__VA_ARGS__) +#define pr_alert(fmt, ...) printk(KERN_ALERT fmt, ##__VA_ARGS__) +#define pr_crit(fmt, ...) printk(KERN_CRIT fmt, ##__VA_ARGS__) +#define pr_error(fmt, ...) printk(KERN_ERROR fmt, ##__VA_ARGS__) +#define pr_warning(fmt, ...) printk(KERN_WARNING fmt, ##__VA_ARGS__) +#define pr_notice(fmt, ...) printk(KERN_NOTICE fmt, ##__VA_ARGS__) +#define pr_info(fmt, ...) printk(KERN_INFO fmt, ##__VA_ARGS__) +#define pr_debug(fmt, ...) printk(KERN_DEBUG fmt, ##__VA_ARGS__) + +#define PANIC_MSG_BUFSZ 1024 + +void panic(const char* fmt, ...) __noreturn __cold; +void vpanic(const char* fmt, va_list ap)__noreturn __cold; + +extern uintptr_t __kernel_start, __kernel_text_start, __kernel_rodata_start, __kernel_data_start; +extern uintptr_t __kernel_end, __kernel_text_end, __kernel_rodata_end, __kernel_data_end; #endif diff --git a/kernel/include/paging.h b/kernel/include/paging.h index e6be24b..dbe739c 100644 --- a/kernel/include/paging.h +++ b/kernel/include/paging.h @@ -30,7 +30,7 @@ #define TO_VIRT(_ptr) ((void*)((uintptr_t)(_ptr) + bootloader.hhdm_offset)) #define TO_PHYS(_ptr) ((void*)((uintptr_t)(_ptr) - bootloader.hhdm_offset)) -#define PAGE_SIZE 0x1000 +#define PAGE_SIZE 4096 #define PAGE_SIZE_LARGE 0x200000 #define PAGE_SIZE_HUGE 0x40000000 diff --git a/kernel/include/serial.h b/kernel/include/serial.h index 8d35981..c62c6d7 100644 --- a/kernel/include/serial.h +++ b/kernel/include/serial.h @@ -16,11 +16,11 @@ int serial_txem(int dev); void serial_send(int dev, char data); int serial_rcvd(int dev); char serial_recv(int dev); -void serial_write(int dev, char* buf, size_t len); -void serial_puts(int dev, char* s); +void serial_write(int dev, const char* buf, size_t len); +void serial_puts(int dev, const char* s); void serial_cls(int dev); -int debugf(char* fmt, ...); -int vdebugf(char* fmt, va_list args); +int debugf(const char* fmt, ...); +int vdebugf(const char* fmt, va_list args); #endif diff --git a/kernel/include/stdarg.h b/kernel/include/stdarg.h new file mode 100644 index 0000000..3f2ea40 --- /dev/null +++ b/kernel/include/stdarg.h @@ -0,0 +1,9 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef __builtin_va_list va_list; +#define va_start(_ap, _last) __builtin_va_start(_ap, _last) +#define va_end(_ap) __builtin_va_end(_ap) +#define va_arg(_ap, _type) __builtin_va_arg(_ap, _type) + +#endif diff --git a/kernel/include/types.h b/kernel/include/types.h new file mode 100644 index 0000000..08ec03e --- /dev/null +++ b/kernel/include/types.h @@ -0,0 +1,44 @@ +#ifndef _TYPES_H +#define _TYPES_H + +// NULL pointer +#define NULL ((void*)0) + +/* + * Integral types + */ +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long uint64_t; +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef signed long int64_t; +_Static_assert(sizeof(int8_t) == 1, "int8_t not 8 bits."); +_Static_assert(sizeof(int16_t) == 2, "int16_t not 16 bits."); +_Static_assert(sizeof(int32_t) == 4, "int32_t not 32 bits."); +_Static_assert(sizeof(int64_t) == 8, "int64_t not 64 bits."); +_Static_assert(sizeof(uint8_t) == 1, "uint8_t not 8 bits."); +_Static_assert(sizeof(uint16_t) == 2, "uint16_t not 16 bits."); +_Static_assert(sizeof(uint32_t) == 4, "uint32_t not 32 bits."); +_Static_assert(sizeof(uint64_t) == 8, "uint64_t not 64 bits."); + +// TODO: Add a static assertion here +typedef uint64_t size_t; +typedef int64_t ssize_t; +typedef size_t offset_t; + +typedef uint64_t uintptr_t; +typedef int64_t intptr_t; +_Static_assert(sizeof(intptr_t) == sizeof(void*), "intptr_t must match pointer size."); +_Static_assert(sizeof(uintptr_t) == sizeof(void*), "uintptr_t must match pointer size."); + +/* + * Boolean + */ +#define bool _Bool +#define true 1 +#define false 0 + +#endif diff --git a/kernel/include/vsnprintf.h b/kernel/include/vsnprintf.h index 49055c9..0e73e6e 100644 --- a/kernel/include/vsnprintf.h +++ b/kernel/include/vsnprintf.h @@ -3,7 +3,7 @@ #include -int snprintf(char *buf, size_t n, char *fmt, ...); -int vsnprintf(char* buf, size_t n, char* fmt, va_list ap); +int snprintf(char *buf, size_t n, const char *fmt, ...); +int vsnprintf(char* buf, size_t n, const char* fmt, va_list ap); #endif diff --git a/kernel/makefile b/kernel/makefile index 7033b09..d8e219f 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -18,7 +18,7 @@ $(OUT): $(OBJS_C) $(OBJS_S) $(BIN)/%.c.o: $(SRC)/%.c $(SSP) @mkdir -p $(dir $@) - $(CC) $(CCFLAGS) -DSTACK_CHK_GUARD="$$(cat $(SSP))" -I$(INC) -c -o $@ $< + $(CC) $(CCFLAGS) -DCONSOLE_LOGLEVEL='$(CONSOLE_LOGLEVEL)' -DSTACK_CHK_GUARD="$$(cat $(SSP))" -I$(INC) -c -o $@ $< $(BIN)/%.s.o: $(SRC)/%.s @mkdir -p $(dir $@) diff --git a/kernel/src/ctype.c b/kernel/src/ctype.c new file mode 100644 index 0000000..3b95dff --- /dev/null +++ b/kernel/src/ctype.c @@ -0,0 +1,115 @@ +#include + +const unsigned char _CTYPE_TABLE[256] = { + // Control characters (ASCII 0-31) + _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 0-7 + _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 8-15 + _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 16-23 + _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, _CNTRL_MASK, // 24-31 + // Space (ASCII 32) + _SPACE_MASK | _PRINT_MASK, + // Punctuation (ASCII 33-47) + _PUNCT_MASK | _PRINT_MASK, // '!' (ASCII 33) + _PUNCT_MASK | _PRINT_MASK, // '"' (ASCII 34) + _PUNCT_MASK | _PRINT_MASK, // '#' (ASCII 35) + _PUNCT_MASK | _PRINT_MASK, // '$' (ASCII 36) + _PUNCT_MASK | _PRINT_MASK, // '%' (ASCII 37) + _PUNCT_MASK | _PRINT_MASK, // '&' (ASCII 38) + _PUNCT_MASK | _PRINT_MASK, // '\'' (ASCII 39) + _PUNCT_MASK | _PRINT_MASK, // '(' (ASCII 40) + _PUNCT_MASK | _PRINT_MASK, // ')' (ASCII 41) + _PUNCT_MASK | _PRINT_MASK, // '*' (ASCII 42) + _PUNCT_MASK | _PRINT_MASK, // '+' (ASCII 43) + _PUNCT_MASK | _PRINT_MASK, // ',' (ASCII 44) + _PUNCT_MASK | _PRINT_MASK, // '-' (ASCII 45) + _PUNCT_MASK | _PRINT_MASK, // '.' (ASCII 46) + _PUNCT_MASK | _PRINT_MASK, // '/' (ASCII 47) + // Digits (ASCII 48-57) + _DIGIT_MASK | _PRINT_MASK, // '0' (ASCII 48) + _DIGIT_MASK | _PRINT_MASK, // '1' (ASCII 49) + _DIGIT_MASK | _PRINT_MASK, // '2' (ASCII 50) + _DIGIT_MASK | _PRINT_MASK, // '3' (ASCII 51) + _DIGIT_MASK | _PRINT_MASK, // '4' (ASCII 52) + _DIGIT_MASK | _PRINT_MASK, // '5' (ASCII 53) + _DIGIT_MASK | _PRINT_MASK, // '6' (ASCII 54) + _DIGIT_MASK | _PRINT_MASK, // '7' (ASCII 55) + _DIGIT_MASK | _PRINT_MASK, // '8' (ASCII 56) + _DIGIT_MASK | _PRINT_MASK, // '9' (ASCII 57) + // Punctuation (ASCII 58-64) + _PUNCT_MASK | _PRINT_MASK, // ':' (ASCII 58) + _PUNCT_MASK | _PRINT_MASK, // ';' (ASCII 59) + _PUNCT_MASK | _PRINT_MASK, // '<' (ASCII 60) + _PUNCT_MASK | _PRINT_MASK, // '=' (ASCII 61) + _PUNCT_MASK | _PRINT_MASK, // '>' (ASCII 62) + _PUNCT_MASK | _PRINT_MASK, // '?' (ASCII 63) + _PUNCT_MASK | _PRINT_MASK, // '@' (ASCII 64) + // Upperchase letters (ASCII 65-90) + _ALPHA_MASK | _PRINT_MASK, // 'A' (ASCII 65) + _ALPHA_MASK | _PRINT_MASK, // 'B' (ASCII 66) + _ALPHA_MASK | _PRINT_MASK, // 'C' (ASCII 67) + _ALPHA_MASK | _PRINT_MASK, // 'D' (ASCII 68) + _ALPHA_MASK | _PRINT_MASK, // 'E' (ASCII 69) + _ALPHA_MASK | _PRINT_MASK, // 'F' (ASCII 70) + _ALPHA_MASK | _PRINT_MASK, // 'G' (ASCII 71) + _ALPHA_MASK | _PRINT_MASK, // 'H' (ASCII 72) + _ALPHA_MASK | _PRINT_MASK, // 'I' (ASCII 73) + _ALPHA_MASK | _PRINT_MASK, // 'J' (ASCII 74) + _ALPHA_MASK | _PRINT_MASK, // 'K' (ASCII 75) + _ALPHA_MASK | _PRINT_MASK, // 'L' (ASCII 76) + _ALPHA_MASK | _PRINT_MASK, // 'M' (ASCII 77) + _ALPHA_MASK | _PRINT_MASK, // 'N' (ASCII 78) + _ALPHA_MASK | _PRINT_MASK, // 'O' (ASCII 79) + _ALPHA_MASK | _PRINT_MASK, // 'P' (ASCII 80) + _ALPHA_MASK | _PRINT_MASK, // 'Q' (ASCII 81) + _ALPHA_MASK | _PRINT_MASK, // 'R' (ASCII 82) + _ALPHA_MASK | _PRINT_MASK, // 'S' (ASCII 83) + _ALPHA_MASK | _PRINT_MASK, // 'T' (ASCII 84) + _ALPHA_MASK | _PRINT_MASK, // 'U' (ASCII 85) + _ALPHA_MASK | _PRINT_MASK, // 'V' (ASCII 86) + _ALPHA_MASK | _PRINT_MASK, // 'W' (ASCII 87) + _ALPHA_MASK | _PRINT_MASK, // 'X' (ASCII 88) + _ALPHA_MASK | _PRINT_MASK, // 'Y' (ASCII 89) + _ALPHA_MASK | _PRINT_MASK, // 'Z' (ASCII 90) + // Punctuation (ASCII 91-96) + _PUNCT_MASK | _PRINT_MASK, // '[' (ASCII 91) + _PUNCT_MASK | _PRINT_MASK, // '\' (ASCII 92) + _PUNCT_MASK | _PRINT_MASK, // ']' (ASCII 93) + _PUNCT_MASK | _PRINT_MASK, // '^' (ASCII 94) + _PUNCT_MASK | _PRINT_MASK, // '_' (ASCII 95) + _PUNCT_MASK | _PRINT_MASK, // '`' (ASCII 96) + // Lowercase letters (ASCII 97-122) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'a' (ASCII 97) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'b' (ASCII 98) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'c' (ASCII 99) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'd' (ASCII 100) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'e' (ASCII 101) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'f' (ASCII 102) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'g' (ASCII 103) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'h' (ASCII 104) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'i' (ASCII 105) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'j' (ASCII 106) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'k' (ASCII 107) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'l' (ASCII 108) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'm' (ASCII 109) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'n' (ASCII 110) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'o' (ASCII 111) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'p' (ASCII 112) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'q' (ASCII 113) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'r' (ASCII 114) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 's' (ASCII 115) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 't' (ASCII 116) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'u' (ASCII 117) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'v' (ASCII 118) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'w' (ASCII 119) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'x' (ASCII 120) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'y' (ASCII 121) + _ALPHA_MASK | _LOWER_MASK | _PRINT_MASK, // 'z' (ASCII 122) + // Punctuation (ASCII 123-126 + _PUNCT_MASK | _PRINT_MASK, // '{' (ASCII 123) + _PUNCT_MASK | _PRINT_MASK, // '|' (ASCII 124) + _PUNCT_MASK | _PRINT_MASK, // '}' (ASCII 125) + _PUNCT_MASK | _PRINT_MASK, // '~' (ASCII 126) + // Control character (ASCII 127) + _CNTRL_MASK // DEL (ASCII 127) +}; + diff --git a/kernel/src/isr.c b/kernel/src/isr.c index 0aa2faf..e4b9471 100644 --- a/kernel/src/isr.c +++ b/kernel/src/isr.c @@ -1,5 +1,4 @@ #include -#include #include #include #include @@ -99,16 +98,16 @@ void isr_handle_interrupt(size_t rsp) { struct isr_int_frame* iframe = (void*)rsp; if (iframe->interrupt < 32) { - debugf("[kernel] Register Dump:\n"); - debugf("\tRAX: %016lu RBX: %016lu RCX: %016lx\n", iframe->rax, iframe->rbx, iframe->rcx); - debugf("\tRDX: %016lu RSI: %016lu RDI: %016lx\n", iframe->rdx, iframe->rsi, iframe->rdi); - debugf("\tR08: %016lu R09: %016lu R10: %016lx\n", iframe->r8, iframe->r9, iframe->r10); - debugf("\tR11: %016lu R12: %016lu R13: %016lx\n", iframe->r11, iframe->r12, iframe->r13); - debugf("\tR14: %016lu R15: %016lu DS/ES: %016lx\n", iframe->r14, iframe->r15, iframe->ds); - debugf("\tRBP: %016lu RSP: %016lu SS: %016lx\n", iframe->rbp, iframe->user_rsp, iframe->user_ss); - debugf("\tRIP: %016lu RFLAGS: %016lx CS: %016lx\n", iframe->rip, iframe->rflags, iframe->cs); + pr_emerg("Register Dump:\n"); + pr_emerg("\tRAX: %016lu RBX: %016lu RCX: %016lx\n", iframe->rax, iframe->rbx, iframe->rcx); + pr_emerg("\tRDX: %016lu RSI: %016lu RDI: %016lx\n", iframe->rdx, iframe->rsi, iframe->rdi); + pr_emerg("\tR08: %016lu R09: %016lu R10: %016lx\n", iframe->r8, iframe->r9, iframe->r10); + pr_emerg("\tR11: %016lu R12: %016lu R13: %016lx\n", iframe->r11, iframe->r12, iframe->r13); + pr_emerg("\tR14: %016lu R15: %016lu DS/ES: %016lx\n", iframe->r14, iframe->r15, iframe->ds); + pr_emerg("\tRBP: %016lu RSP: %016lu SS: %016lx\n", iframe->rbp, iframe->user_rsp, iframe->user_ss); + pr_emerg("\tRIP: %016lu RFLAGS: %016lx CS: %016lx\n", iframe->rip, iframe->rflags, iframe->cs); - if (iframe->error) debugf("[kernel] Error code: 0x%lx\n", iframe->error); + if (iframe->error) pr_emerg("Error code: 0x%lx\n", iframe->error); panic(exceptions[iframe->interrupt]); } else if (iframe->interrupt >= 32 && iframe->interrupt < 48) { // ISRs 32-47 - Hardware interrupts @@ -117,7 +116,7 @@ void isr_handle_interrupt(size_t rsp) { if (irq_handlers[irq]) irq_handlers[irq](iframe); } else if (iframe->interrupt == 128) { // ISR 128 - System call - debugf("SYSCALL!\n"); + pr_notice("SYSCALL!\n"); } } diff --git a/kernel/src/kernel.c b/kernel/src/kmain.c similarity index 93% rename from kernel/src/kernel.c rename to kernel/src/kmain.c index 02bf234..b441520 100644 --- a/kernel/src/kernel.c +++ b/kernel/src/kmain.c @@ -1,13 +1,12 @@ #include +#include #include #include #include #include #include -#include #include - -#include +#include __noreturn void _start(void) { @@ -24,7 +23,7 @@ void _start(void) { uint32_t eax = 0; char s[12]; cpuid(&eax, (void*)&s[0], (void*)&s[8], (void*)&s[4]); - debugf("[kernel] CPUID_GETVENDORID: %s\n", s); + pr_info("[kernel] CPUID_GETVENDORID: %s\n", s); // System init if (gdt_init() < 0) panic("Failed to initalize GDT."); @@ -34,6 +33,8 @@ void _start(void) { if (pmm_init() < 0) panic("Failed to initalize Physical Memory Manager."); if (pag_init() < 0) panic("Failed to initalize Paging."); + panic("Yeah.."); + // Patiently wait for things to do :) while (1); } diff --git a/kernel/src/paging.c b/kernel/src/paging.c index 339ee4e..6aa6bd4 100644 --- a/kernel/src/paging.c +++ b/kernel/src/paging.c @@ -20,7 +20,7 @@ int pag_init(void) { pag_kernel_pml4, (void*)bootloader.kernel_virt_base, (void*)bootloader.kernel_phys_base, - dceil(bootloader.executable->size, PAGE_SIZE), + ALIGN(bootloader.executable->size, PAGE_SIZE), PTE_FLAG_WRITE | PTE_FLAG_PRESENT ); if (ret != SUCCESS) return ret; @@ -40,7 +40,7 @@ int pag_init(void) { case LIMINE_MEMMAP_FRAMEBUFFER: flags = PTE_FLAG_WRITE | PTE_FLAG_PWT; break; case LIMINE_MEMMAP_RESERVED_MAPPED: flags = 0; break; default: - debugf( + pr_warning( "[pag] %p - %p: Unknown memmap type %d. Will remain unmapped.\n", entry->base, entry->base + entry->length, entry->type ); @@ -50,7 +50,7 @@ int pag_init(void) { ret = pag_map_region( pag_kernel_pml4, (void*)(entry->base + bootloader.hhdm_offset), (void*)entry->base, - dceil(entry->length, PAGE_SIZE), + ALIGN(entry->length, PAGE_SIZE), flags | PTE_FLAG_PRESENT ); if (ret != SUCCESS) return ret; diff --git a/kernel/src/panic.c b/kernel/src/panic.c new file mode 100644 index 0000000..b2ca9ec --- /dev/null +++ b/kernel/src/panic.c @@ -0,0 +1,33 @@ +#include +#include +#include +#include + +static int crashing = 0; + +void panic(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + vpanic(fmt, ap); + va_end(ap); +} + +void vpanic(const char *fmt, va_list ap) { + static char buf[PANIC_MSG_BUFSZ]; + size_t len; + + cli(); + + if (crashing) { for (;;) __asm__ volatile ("hlt"); } + crashing = true; + + len = vsnprintf(buf, sizeof(buf), fmt, ap); + if (len && buf[len - 1] == '\n') buf[len - 1] = '\0'; + + pr_emerg("--- [ Kernel panic: %s ] ---\n", buf); + //pr_emerg("--- [ End kernel panic: %s ] ---\n", buf); + + // We can add some kind of LED blink or smth later :) + for (;;) __asm__ volatile ("hlt"); +} + diff --git a/kernel/src/pmm.c b/kernel/src/pmm.c index a311e95..f57e5e8 100644 --- a/kernel/src/pmm.c +++ b/kernel/src/pmm.c @@ -2,7 +2,6 @@ #include #include #include -#include #include #include @@ -11,11 +10,11 @@ uint64_t* pmm_head = NULL; size_t pmm_total_mem = 0; int pmm_init(void) { - debugf("[pmm] Physical memory map:\n"); // We're gonna use the loop to also print the memmap + pr_info("[pmm] Physical memory map:\n"); // We're gonna use the loop to also print the memmap for (size_t i = 0; i < bootloader.mm_entry_count; i++) { struct limine_memmap_entry* entry = bootloader.mm_entries[i]; - debugf( + pr_info( "\t%p - %p (%d bytes), type %d\n", entry->base, entry->base + entry->length, entry->length, entry->type ); @@ -25,7 +24,7 @@ int pmm_init(void) { // Limine spec says that it'll be aligned, but just as a sanity check if (entry->base % PAGE_SIZE != 0) { size_t diff = PAGE_SIZE - (entry->base % PAGE_SIZE); - debugf("\t Not 4 kiB aligned, shifting %p -> %p (%d bytes).\n", entry->base, entry->base + diff, diff); + pr_info("\t Not 4 kiB aligned, shifting %p -> %p (%d bytes).\n", entry->base, entry->base + diff, diff); entry->base += diff; entry->length -= diff; } @@ -38,7 +37,7 @@ int pmm_init(void) { } } - debugf("[pmm] %d bytes of available memory.\n", pmm_total_mem); + pr_info("[pmm] %d bytes of available memory.\n", pmm_total_mem); if (pmm_total_mem == 0) return -ENOMEM; return SUCCESS; diff --git a/kernel/src/printk.c b/kernel/src/printk.c new file mode 100644 index 0000000..27c2fbc --- /dev/null +++ b/kernel/src/printk.c @@ -0,0 +1,28 @@ +#include +#include +#include +#include + +uint8_t console_loglevel = CONSOLE_LOGLEVEL; + +int printk(const char *fmt, ...) { + va_list ap; + va_start(ap, fmt); + int ret = vprintk(fmt, ap); + va_end(ap); + return ret; +} + +int vprintk(const char* fmt, va_list ap) { + int loglevel = LOGLEVEL_DEFAULT; + if (*fmt == KERN_SOH_ASCII) { + fmt++; + if (isdigit(*fmt)) loglevel = *fmt++ - '0'; + } + + if (loglevel > console_loglevel) return 0; + + // TODO: debugf("[%4d.%6d] ", seconds, milliseconds); + return vdebugf(fmt, ap); +} + diff --git a/kernel/src/serial.c b/kernel/src/serial.c index b00d8a2..2e32a74 100644 --- a/kernel/src/serial.c +++ b/kernel/src/serial.c @@ -43,16 +43,16 @@ char serial_recv(int dev) { return inb(dev); } -void serial_write(int dev, char* buf, size_t len) { +void serial_write(int dev, const char* buf, size_t len) { for (size_t i = 0; i < len; i++) { if (buf[i] == '\n') serial_send(dev, '\r'); serial_send(dev, buf[i]); } } -void serial_puts(int dev, char* s) { +void serial_puts(int dev, const char* s) { size_t len = 0; - char* p = s; + const char* p = s; while (*p++ != '\0') len++; serial_write(dev, s, len); } @@ -61,7 +61,7 @@ void serial_cls(int dev) { serial_write(dev, "\x1b[H\x1b[J", 6); } -int debugf(char* fmt, ...) { +int debugf(const char* fmt, ...) { va_list args; va_start(args, fmt); int ret = vdebugf(fmt, args); @@ -69,7 +69,7 @@ int debugf(char* fmt, ...) { return ret; } -int vdebugf(char* fmt, va_list args) { +int vdebugf(const char* fmt, va_list args) { char buf[DF_BUF_LEN]; int len = vsnprintf(buf, DF_BUF_LEN, fmt, args); serial_write(COM1, buf, len); diff --git a/kernel/src/vsnprintf.c b/kernel/src/vsnprintf.c index 0556998..60915bd 100644 --- a/kernel/src/vsnprintf.c +++ b/kernel/src/vsnprintf.c @@ -109,7 +109,7 @@ static void fmt_float(char* buf, size_t n, size_t* idx, double v, int prec, int if (left) { while (pad_len--) _putc(buf, n, idx, pad); } } -int vsnprintf(char* buf, size_t n, char* fmt, va_list ap) { +int vsnprintf(char* buf, size_t n, const char* fmt, va_list ap) { size_t idx = 0; for (; *fmt != '\0'; fmt++) { @@ -195,7 +195,7 @@ int vsnprintf(char* buf, size_t n, char* fmt, va_list ap) { return (int)idx; } -int snprintf(char *buf, size_t n, char *fmt, ...) { +int snprintf(char *buf, size_t n, const char *fmt, ...) { va_list ap; va_start(ap, fmt); int ret = vsnprintf(buf, n, fmt, ap);