From 336b4e1152f26dbb70d3b5ad81bd880e25243add Mon Sep 17 00:00:00 2001 From: nub31 Date: Sun, 24 Aug 2025 00:29:04 +0200 Subject: [PATCH] ... --- grub.cfg | 3 +- makefile | 14 +++---- src/kernel.c | 5 ++- src/print.c | 97 -------------------------------------------- src/print.h | 40 ------------------- src/stdint.h | 17 ++++++++ src/vga.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/vga.h | 38 ++++++++++++++++++ 8 files changed, 178 insertions(+), 147 deletions(-) delete mode 100644 src/print.c delete mode 100644 src/print.h create mode 100644 src/stdint.h create mode 100644 src/vga.c create mode 100644 src/vga.h diff --git a/grub.cfg b/grub.cfg index edb10eb..c2b4861 100644 --- a/grub.cfg +++ b/grub.cfg @@ -1,3 +1,4 @@ menuentry "nub-os" { - multiboot2 /boot/kernel.bin + multiboot2 /boot/kernel + boot } diff --git a/makefile b/makefile index 36dd030..2efd707 100644 --- a/makefile +++ b/makefile @@ -1,7 +1,7 @@ CC = i386-elf-gcc LD = i386-elf-ld -CFLAGS = -ffreestanding -m32 +CFLAGS = -Werror -Wall -pedantic -std=c23 -ffreestanding -m32 all: .build/nub-os.iso @@ -11,20 +11,20 @@ clean: build-dir: mkdir .build 2>/dev/null || true -.build/nub-os.iso: build-dir .build/kernel.bin +.build/nub-os.iso: build-dir .build/kernel mkdir -p .build/iso/boot/grub cp grub.cfg .build/iso/boot/grub - cp .build/kernel.bin .build/iso/boot/ + cp .build/kernel .build/iso/boot/ grub-mkrescue -o .build/nub-os.iso .build/iso/ -.build/kernel.bin: build-dir .build/boot.o .build/kernel.o .build/print.o - $(LD) -Ttext 0x100000 -o .build/kernel.bin .build/boot.o .build/kernel.o .build/print.o +.build/kernel: build-dir .build/boot.o .build/kernel.o .build/vga.o + $(LD) -Ttext 0x100000 -o .build/kernel .build/boot.o .build/kernel.o .build/vga.o .build/kernel.o: build-dir src/kernel.c $(CC) $(CFLAGS) -c -o .build/kernel.o src/kernel.c -.build/print.o: build-dir src/print.c - $(CC) $(CFLAGS) -c -o .build/print.o src/print.c +.build/vga.o: build-dir src/vga.c + $(CC) $(CFLAGS) -c -o .build/vga.o src/vga.c .build/boot.o: build-dir src/boot.asm nasm -f elf32 -o .build/boot.o src/boot.asm \ No newline at end of file diff --git a/src/kernel.c b/src/kernel.c index 3839370..1f86461 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -1,6 +1,7 @@ -#include "print.h" +#include "vga.h" void kernel_main(void) { - print("Welcome to nub OS\n"); + vga_reset(); + vga_print("Welcome to nub OS\n"); } \ No newline at end of file diff --git a/src/print.c b/src/print.c deleted file mode 100644 index 61e6cd4..0000000 --- a/src/print.c +++ /dev/null @@ -1,97 +0,0 @@ -#include "print.h" -#include - -#define ROWS 25 -#define COLUMNS 80 -#define BUF_SIZE ((ROWS * COLUMNS) * 2) - -#define BUF_START 0xb8000 -#define BUF_END (BUF_START + BUF_SIZE) - -typedef struct -{ - uint8_t character; - uint8_t color; -} vga_char; - -static vga_char* vga_buffer = (vga_char*)BUF_START; -static int cursor_row = 0; -static int cursor_col = 0; - -void scroll(void) -{ - for (int row = 1; row < ROWS; row++) - { - for (int col = 0; col < COLUMNS; col++) - { - vga_buffer[(row - 1) * COLUMNS + col] = vga_buffer[row * COLUMNS + col]; - } - } - - for (int col = 0; col < COLUMNS; col++) - { - vga_buffer[(ROWS - 1) * COLUMNS + col] = (vga_char){ ' ', FG_WHITE | BG_BLACK << 4 }; - } -} - -void put_char(char c, FG_COLOR fg_color, BG_COLOR bg_color) -{ - if (c == '\n') - { - cursor_col = 0; - cursor_row++; - } - else - { - uint8_t color = fg_color | bg_color << 4; - vga_buffer[cursor_row * COLUMNS + cursor_col] = (vga_char){ c, color }; - cursor_col++; - } - - if (cursor_col >= COLUMNS) - { - cursor_col = 0; - cursor_row++; - } - - if (cursor_row >= ROWS) - { - scroll(); - cursor_row = ROWS - 1; - } -} - -void print(const char* string) -{ - print_clr(string, FG_WHITE, BG_BLACK); -} - -void print_clr(const char* string, FG_COLOR fg_color, BG_COLOR bg_color) -{ - for (int i = 0; string[i]; i++) - { - put_char(string[i], fg_color, bg_color); - } -} - -void clear_screen(void) -{ - uint8_t color = FG_WHITE | BG_BLACK << 4; - - for (int i = 0; i < ROWS * COLUMNS; i++) - { - vga_buffer[i] = (vga_char){ ' ', color }; - } - - cursor_row = 0; - cursor_col = 0; -} - -void set_cursor_position(int row, int col) -{ - if (row >= 0 && row < ROWS && col >= 0 && col < COLUMNS) - { - cursor_row = row; - cursor_col = col; - } -} \ No newline at end of file diff --git a/src/print.h b/src/print.h deleted file mode 100644 index e3d0df9..0000000 --- a/src/print.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once -#include - -typedef enum -{ - FG_BLACK = 0x0, - FG_BLUE = 0x1, - FG_GREEN = 0x2, - FG_CYAN = 0x3, - FG_RED = 0x4, - FG_MAGENTA = 0x5, - FG_BROWN = 0x6, - FG_LIGHT_GRAY = 0x7, - FG_DARK_GRAY = 0x8, - FG_LIGHT_BLUE = 0x9, - FG_LIGHT_GREEN = 0xA, - FG_LIGHT_CYAN = 0xB, - FG_LIGHT_RED = 0xC, - FG_LIGHT_MAGENTA = 0xD, - FG_YELLOW = 0xE, - FG_WHITE = 0xF, -} FG_COLOR; - -typedef enum -{ - BG_BLACK = 0x0, - BG_BLUE = 0x1, - BG_GREEN = 0x2, - BG_CYAN = 0x3, - BG_RED = 0x4, - BG_MAGENTA = 0x5, - BG_BROWN = 0x6, - BG_LIGHT_GRAY = 0x7, -} BG_COLOR; - -void put_char(char c, FG_COLOR fg_color, BG_COLOR bg_color); -void print(const char* string); -void print_clr(const char* string, FG_COLOR fg_color, BG_COLOR bg_color); -void clear_screen(void); -void set_cursor_position(int row, int col); \ No newline at end of file diff --git a/src/stdint.h b/src/stdint.h new file mode 100644 index 0000000..30aa547 --- /dev/null +++ b/src/stdint.h @@ -0,0 +1,17 @@ +#pragma once + +typedef signed char int8_t; +typedef unsigned char uint8_t; + +typedef signed short int16_t; +typedef unsigned short uint16_t; + +typedef signed long int int32_t; +typedef unsigned long int uin32_t; + +typedef signed long long int int64_t; +typedef unsigned long long int uin64_t; + +#define bool uint8_t; +#define true 1 +#define false 0 \ No newline at end of file diff --git a/src/vga.c b/src/vga.c new file mode 100644 index 0000000..edf2041 --- /dev/null +++ b/src/vga.c @@ -0,0 +1,111 @@ +#include "vga.h" + +#define ROWS 25 +#define COLUMNS 80 + +typedef struct +{ + uint8_t character; + uint8_t color; +} vga_char; + +vga_char* vga_buffer = (vga_char*)0xb8000; +uint8_t cursor_row = 0; +uint8_t cursor_col = 0; + +void vga_set_char(uint8_t row, uint8_t col, vga_char character) +{ + vga_buffer[COLUMNS * row + col] = character; +} + +vga_char vga_char_at(uint8_t row, uint8_t col) +{ + return vga_buffer[COLUMNS * row + col]; +} + +void vga_reset(void) +{ + for (uint8_t row = 0; row < ROWS; row++) + { + for (uint8_t col = 0; col < COLUMNS; col++) + { + vga_char character = { .character = ' ', .color = vga_default_color() }; + vga_set_char(row, col, character); + } + } + + cursor_row = 0; + cursor_col = 0; +} + +void vga_set_cursor_position(uint8_t row, uint8_t col) +{ + if (row < ROWS && col < COLUMNS) + { + cursor_row = row; + cursor_col = col; + } +} + +void vga_print_char(char character, vga_color_t color) +{ + switch (character) + { + case '\n': + { + cursor_row += 1; + cursor_col = 0; + break; + } + case '\r': + { + cursor_col = 0; + break; + } + default: + { + vga_char c = { .character = character, .color = color }; + vga_set_char(cursor_row, cursor_col, c); + cursor_col += 1; + break; + } + } + + if (cursor_col >= COLUMNS) + { + cursor_col = 0; + cursor_row += 1; + } + + if (cursor_row >= ROWS) + { + for (uint8_t row = 1; row < ROWS; row++) + { + for (uint8_t col = 0; col < COLUMNS; col++) + { + vga_set_char(row, col, vga_char_at(row - 1, col)); + } + } + + for (uint8_t col = 0; col < COLUMNS; col++) + { + vga_char character = { .character = ' ', .color = vga_default_color() }; + vga_set_char(ROWS - 1, col, character); + }; + + cursor_row = ROWS - 1; + } +} + +void vga_print_colored(const char* string, vga_color_t color) +{ + for (uint8_t i = 0; string[i] != '\0'; i++) + { + vga_print_char(string[i], color); + } +} + +void vga_print(const char* string) +{ + vga_print_colored(string, vga_default_color()); +} \ No newline at end of file diff --git a/src/vga.h b/src/vga.h new file mode 100644 index 0000000..51070a5 --- /dev/null +++ b/src/vga.h @@ -0,0 +1,38 @@ +#pragma once + +#include "stdint.h" + +#define VGA_BLACK 0 +#define VGA_BLUE 1 +#define VGA_GREEN 2 +#define VGA_CYAN 3 +#define VGA_RED 4 +#define VGA_MAGENTA 5 +#define VGA_BROWN 6 +#define VGA_LIGHT_GRAY 7 +#define VGA_DARK_GRAY 8 +#define VGA_LIGHT_BLUE 9 +#define VGA_LIGHT_GREEN 10 +#define VGA_LIGHT_CYAN 11 +#define VGA_LIGHT_RED 12 +#define VGA_LIGHT_MAGENTA 13 +#define VGA_YELLOW 14 +#define VGA_WHITE 15 + +typedef uint8_t vga_color_t; + +void vga_reset(void); +void vga_set_cursor_position(uint8_t row, uint8_t col); + +void vga_print_colored(const char* string, vga_color_t color); +void vga_print(const char* string); + +static inline vga_color_t vga_color(vga_color_t fg_color, vga_color_t bg_color) +{ + return fg_color | bg_color << 4; +} + +static inline vga_color_t vga_default_color() +{ + return vga_color(VGA_LIGHT_GRAY, VGA_BLACK); +} \ No newline at end of file