From f9dece59ce18485a88ab971a73e7ab8d1db68747 Mon Sep 17 00:00:00 2001 From: Tomas Date: Mon, 17 Feb 2025 21:02:10 +0100 Subject: [PATCH] Got basic tty driver & implemented Stack Smash Protector --- defaults.mk | 2 +- kernel/include/kernel.h | 44 +++++++++++++++++++++++++++++++--- kernel/include/tty.h | 10 ++++---- kernel/makefile | 8 +++---- kernel/src/kernel.c | 6 ++++- kernel/src/ssp.c | 14 +++++++++++ kernel/src/tty.c | 52 +++++++++++++++++++++++++++++++++-------- makefile | 2 +- 8 files changed, 114 insertions(+), 24 deletions(-) create mode 100644 kernel/src/ssp.c diff --git a/defaults.mk b/defaults.mk index af87d1c..9aba905 100644 --- a/defaults.mk +++ b/defaults.mk @@ -10,7 +10,7 @@ MAKE = make # Flags HOSTCCFLAGS = -Wall -Wextra -Wpedantic -Os -std=c17 CCFLAGS = -Wall -Wextra -Wpedantic -Wno-pointer-arith\ - -ffreestanding -fno-stack-protector -fno-builtin -fno-pie -fcommon\ + -ffreestanding -fstack-protector -fno-builtin -fno-pie -fcommon\ -O2 -std=c17 -nostdinc -nostdlib -z notext -march=i386 -m32 LDFLAGS = -melf_i386 ASFLAGS = diff --git a/kernel/include/kernel.h b/kernel/include/kernel.h index babe17c..88130d7 100644 --- a/kernel/include/kernel.h +++ b/kernel/include/kernel.h @@ -1,6 +1,33 @@ #ifndef _KERNEL_H #define _KERNEL_H +// Null definition +#define NULL ((void*)0) + +/* + * Variable arguments + */ +typedef void* va_list; +#define va_start(ap, param) (void)((ap) = (char*)(&(param) + 1)) +#define va_end(ap) (void)((ap) = 0) +#define va_arg(ap, type) (((type*)((ap) = ((ap) + sizeof(type))))[-1]) + +/* + * Utility macros + */ +#define ARRAY_SIZE(_a) (sizeof((_a)) / sizeof((_a)[0])) +#define BIT(_n) (1UL << (_n)) +#define BIT_MASK(_n) (BIT(_n) - 1) +#define ALIGN(_x, _a) __ALIGN_MASK((_x), (typeof(_x))(_a) - 1) +#define __ALIGN_MASK(_x, _m) (((_x) + (_m)) & ~(_m)) +#define container_of(_p, _t, _m) \ + ((_t*)((char*)(_p) - offsetof(_t, _m))) +#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))) + /* * Attribute definitions */ @@ -20,18 +47,29 @@ /* * Standard int types */ -// Unsigned typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long uint64_t; -// Signed typedef signed char int8_t; typedef signed short int16_t; typedef signed int int32_t; typedef signed long int64_t; -// Size typedef uint32_t size_t; typedef int32_t ssize_t; +typedef uint32_t uintptr_t; +typedef int32_t intptr_t; + +/* + * Logging and errors + */ +// TODO: Logging with printk() +// TODO: Log levels & pr_*() wrappers for printk() +#define BUG() (panic("BUG()")) +#define WARN() NULL +#define BUG_ON(_e) ((_e) ? BUG() : NULL) +#define WARN_ON(_e) ((_e) ? WARN() : NULL) +// TODO: Write a panic() +#define panic(_s) while(1); #endif diff --git a/kernel/include/tty.h b/kernel/include/tty.h index 1500210..e9ee1c4 100644 --- a/kernel/include/tty.h +++ b/kernel/include/tty.h @@ -2,13 +2,15 @@ #define _TTY_H /* VGA Text mode */ +#define VGA_ATTR(_fg, _bg) ((_fg) | ((_bg) << 4) #define VGA_WIDTH 80 #define VGA_HEIGHT 25 #define VGA_MEMORY 0xb8000 -int tty_init(void); -int tty_write(char* buf, size_t len); -int tty_putc(char c); -int tty_puts(char* s); +void tty_init(void); +void tty_clear(void); +void tty_setattr(uint8_t attr); +void tty_putc(char c); +void tty_puts(char* s); #endif diff --git a/kernel/makefile b/kernel/makefile index 4da91f6..2f2e59d 100644 --- a/kernel/makefile +++ b/kernel/makefile @@ -5,8 +5,8 @@ BIN = ./bin INC = ./include SRCS_C = $(wildcard $(SRC)/*.c) SRCS_S = $(wildcard $(SRC)/*.s) -OBJS_C = $(patsubst $(SRC)/%.c, $(BIN)/%.o, $(SRCS_C)) -OBJS_S = $(patsubst $(SRC)/%.s, $(BIN)/%.o, $(SRCS_S)) +OBJS_C = $(patsubst $(SRC)/%.c, $(BIN)/%.c.o, $(SRCS_C)) +OBJS_S = $(patsubst $(SRC)/%.s, $(BIN)/%.s.o, $(SRCS_S)) OUT = ./kernel.elf LINKER = ./linker.ld @@ -15,11 +15,11 @@ all: $(OUT) $(OUT): $(OBJS_C) $(OBJS_S) $(LD) $(LDFLAGS) -T$(LINKER) -o $@ $^ -$(BIN)/%.o: $(SRC)/%.c +$(BIN)/%.c.o: $(SRC)/%.c @mkdir -p $(dir $@) $(CC) $(CCFLAGS) -I$(INC) -c -o $@ $^ -$(BIN)/%.o: $(SRC)/%.s +$(BIN)/%.s.o: $(SRC)/%.s @mkdir -p $(dir $@) $(AS) $(ASFLAGS) -felf32 -o $@ $^ diff --git a/kernel/src/kernel.c b/kernel/src/kernel.c index fed6b12..b3a62a7 100644 --- a/kernel/src/kernel.c +++ b/kernel/src/kernel.c @@ -1,9 +1,13 @@ #include #include +#define _hlt() while (1) __asm__ volatile ("cli; hlt"); + __noreturn void kmain(void) { tty_init(); - printk("Hello, World!\n"); + tty_puts("Hello, World!\n"); + + _hlt(); } diff --git a/kernel/src/ssp.c b/kernel/src/ssp.c new file mode 100644 index 0000000..762eebc --- /dev/null +++ b/kernel/src/ssp.c @@ -0,0 +1,14 @@ +/* + * Stack Smash Protector + * Source: https://wiki.osdev.org/Stack_Smashing_Protector +*/ +#include + +// TODO: Make this randomized +#define STACK_CHK_GUARD 0x27a1abd8 + +uintptr_t __stack_chk_guard = STACK_CHK_GUARD; +__noreturn void __stack_chk_fail(void) { + panic("Stack smashing detected!"); +} + diff --git a/kernel/src/tty.c b/kernel/src/tty.c index 2504a9f..82bec4d 100644 --- a/kernel/src/tty.c +++ b/kernel/src/tty.c @@ -12,20 +12,52 @@ void tty_init(void) { ctx.row = 0; ctx.col = 0; ctx.attr = 0x07; - ctx.buf = (u8*)VGA_MEMORY; + ctx.buf = (uint8_t*)VGA_MEMORY; + tty_clear(); +} - for (size_t y = 0; y < VGA_HEIGHT; y++) { - for (size_t x = 0; x < VGA_WIDTH; x++) { - size_t i = (y * VGA_WIDTH + x) * 2; - ctx.buf[i] = ' '; - ctx.buf[i + 1] = ctx.attr; - } +void tty_clear(void) { + for (int i = 0; i < VGA_WIDTH * VGA_HEIGHT; i++) { + ctx.buf[i * 2] = ' '; + ctx.buf[i * 2 + 1] = ctx.attr; } } -int tty_write(char* buf, size_t len) {} +void tty_setattr(uint8_t attr) { + ctx.attr = attr; +} -int tty_putc(char c) {} +// TODO: +void tty_scroll(void) { + ctx.row = 0; + ctx.col = 0; + tty_clear(); +} -int tty_puts(char* s) {} +void tty_putat(char c, size_t row, size_t col) { + size_t i = row * VGA_WIDTH + col; + ctx.buf[i * 2] = c; + ctx.buf[i * 2 + 1] = ctx.attr; +} + +void tty_putc(char c) { + if (c == '\n') { + ctx.col = 0; + ctx.row++; + if (ctx.row >= VGA_HEIGHT) tty_scroll(); + return; + } + + tty_putat(c, ctx.row, ctx.col++); + if (ctx.col >= VGA_WIDTH) { + ctx.col = 0; + ctx.row++; + } + + if (ctx.row >= VGA_HEIGHT) tty_scroll(); +} + +void tty_puts(char* s) { + while (*s != '\0') tty_putc(*s++); +} diff --git a/makefile b/makefile index f585576..ed4d98b 100644 --- a/makefile +++ b/makefile @@ -14,7 +14,7 @@ clean: qemu: qemu-system-x86_64\ - -kernel ./kernel/kernel.elf + -kernel ./kernel/kernel.elf\ -m 256M -accel tcg -monitor stdio -net none\ -rtc base=localtime,clock=host,driftfix=slew\ -audiodev pipewire,id=audio0 -machine pcspk-audiodev=audio0