From 9c5667c4543e5de4c07b48a0d550014a501e72b3 Mon Sep 17 00:00:00 2001 From: Nigel Date: Sat, 28 Oct 2023 21:51:04 +0200 Subject: [PATCH 1/2] Created a proper driver for the serial bus * The driver can write to any of the pre-defined serial COM ports * The driver can read from any of the pre-defined serial COM ports (Untested) --- kernel/Makefile | 8 ++++- kernel/drivers/serial/serial.cpp | 53 +++++++++++++++++++++++------ kernel/drivers/serial/serial.h | 34 ++++++++++++------- kernel/kernel.cpp | 23 ++++++++----- kernel/serial.h | 58 -------------------------------- 5 files changed, 87 insertions(+), 89 deletions(-) delete mode 100644 kernel/serial.h diff --git a/kernel/Makefile b/kernel/Makefile index 8fdb8ad..2e6c7d5 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -34,7 +34,8 @@ OFILES = $(OBJ_DIR)/boot.o \ $(OBJ_DIR)/ataDevice.o \ $(OBJ_DIR)/rsdp.o \ $(OBJ_DIR)/acpi.o \ - $(OBJ_DIR)/fat.o + $(OBJ_DIR)/fat.o \ + $(OBJ_DIR)/serial.o OBJ_LINK_LIST = $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(OFILES) $(CRTEND_OBJ) $(CRTN_OBJ) INTERNAL_OBJS = $(CRTI_OBJ) $(OFILES) $(CRTN_OBJ) @@ -121,6 +122,11 @@ $(OBJ_DIR)/processor.o: $(OBJ_DIR)/fat.o: $(CPP) -c storage/filesystems/FAT/FAT.cpp -o $(OBJ_DIR)/fat.o $(CFLAGS) -fno-exceptions -fno-rtti +$(OBJ_DIR)/serial.o: + $(CPP) -c drivers/serial/serial.cpp -o $(OBJ_DIR)/serial.o $(CFLAGS) -fno-exceptions -fno-rtti + + + # Assembly -> Object files $(OBJ_DIR)/boot.o: $(AS) boot/boot.s -o $(OBJ_DIR)/boot.o diff --git a/kernel/drivers/serial/serial.cpp b/kernel/drivers/serial/serial.cpp index 9d2b981..36e1b3b 100644 --- a/kernel/drivers/serial/serial.cpp +++ b/kernel/drivers/serial/serial.cpp @@ -1,19 +1,52 @@ #include "serial.h" +#include "../../io/io.h" -Serial Serial::init() { - // No clue what to setup yet! +// Initializes communication according to the spec given +Serial::Serial(SerialConfig config) { + port = config.port; + // Disable interrupts + outb(config.port + 1, 0x00); - return Serial(); + // Enable DLAB + outb(config.port + 3, 0x80); + + // set the baudrate + outb(config.port + 0, 0x03); + outb(config.port + 1, 0x00); + + // configure for 8bits, no parity, one stop bit + outb(config.port + 3, 0x03); + + // Enable FIFO, clear them, with 14-byte threshhold + outb(config.port + 2, 0xC7); + // Enable IRQ's, RTS/DSR set + outb(config.port + 4, 0x0B ); + // Set in loopback mode, test the serial chip. + outb(config.port + 4, 0x1E); + + // TEST + outb(config.port + 0 , 0xAE); + + if(inb(config.port + 0) != 0xAE) + return ; // FAIL + + outb(config.port + 4, 0x0F); + return ; } -void Serial::print(){ - // Do nothing! +void Serial::write(void* data, int len) { + while (is_transmit_empty() == 0); // Wait for transmit queue to be free + for (int i = 0; i < len ; i++){ + outb(port, ((uint8_t*)data)[i]); + } } -Serial::Serial(){ - // Do nothing! +char Serial::read() { + return inb(port); } -Serial::~Serial(){ - // Do nothing! -} \ No newline at end of file +int Serial::is_transmit_empty() { + return inb(port + 5) & 0x20; +} + + diff --git a/kernel/drivers/serial/serial.h b/kernel/drivers/serial/serial.h index 80101e5..09bef54 100644 --- a/kernel/drivers/serial/serial.h +++ b/kernel/drivers/serial/serial.h @@ -1,19 +1,29 @@ #pragma once +// For now these are the standard +// serial ports we can talk to +enum SERIALPORT { + COM1 = 0x3F8, + COM2 = 0x2F8, + COM3 = 0x3E8, + COM4 = 0x2E8 +}; -class Serial { +struct SerialConfig { + SERIALPORT port; + char baud_rate_lo ; + char baud_rate_hi; +}; + + +class Serial { public: - static Serial init(); - - void print(); + Serial (SerialConfig config ); - private: - const int COM1 = 0x3F8; - const int COM2 = 0x2F8; - const int COM3 = 0x3E8; - const int COM4 = 0x2E8; + char read(); + void write(void* data, int length); - - Serial(); - ~Serial(); + private: + SERIALPORT port; + int is_transmit_empty(); }; \ No newline at end of file diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index 4375be3..e91bc87 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -12,12 +12,11 @@ #include "i386/processor.h" #include "terminal/kterm.h" #include "interrupts/idt.h" -#include "serial.h" #include "storage/vfs/vfs.h" #include "storage/filesystems/FAT/FAT.h" #include "acpi/acpi.h" #include "memory/VirtualMemoryManager.h" - +#include "drivers/serial/serial.h" extern BootInfoBlock* BIB; extern "C" void LoadGlobalDescriptorTable(); @@ -40,20 +39,16 @@ void initBootDrive(){ extern "C" void kernel () { - init_serial(); kterm_init(); - print_serial("kterm initialized...\n"); setup_tss(); initGDT(); initidt(); LoadGlobalDescriptorTable(); flush_tss(); printf("Memory setup complete!\n"); - print_serial("Memory initialized....\n"); // Enable interrupts asm volatile("STI"); initHeap(); - print_serial("Heap initialized...\n"); //pit_initialise(); @@ -64,11 +59,23 @@ extern "C" void kernel () initBootDrive(); VirtualFileSystem::initialize(); - print_serial("Run test!"); + + // Test new serial driver + SerialConfig debug_com1_config{ + COM1, + 0x03, + 0x00 + }; + Serial com1 = Serial(debug_com1_config); + + com1.write((void*)"Hello world!\n", 14); + #define VFS_EXAMPLE #ifdef VFS_EXAMPLE auto fontFile = VirtualFileSystem::open("/FONT PSF", 0); - printf("Size of font file: %d bytes", fontFile->root->size); // COOL This Works like a charm + printf("Size of font file: %d bytes\n", fontFile->root->size); // COOL This Works like a charm + + #endif #ifdef USERMODE_RELEASE diff --git a/kernel/serial.h b/kernel/serial.h deleted file mode 100644 index 1ede93e..0000000 --- a/kernel/serial.h +++ /dev/null @@ -1,58 +0,0 @@ -#pragma once - -#include "terminal/kterm.h" -#include "io/io.h" -#define PORT 0x3f8 -static int init_serial() { - -#ifdef __VERBOSE__ - printf("Init Serial\n"); -#endif - - outb(PORT + 1, 0x00); // Disable all interrupts - outb(PORT + 3, 0x80); // Enable DLAB (set baud rate divisor) - outb(PORT + 0, 0x03); // Set divisor to 3 (lo byte) 38400 baud - outb(PORT + 1, 0x00); // (hi byte) - outb(PORT + 3, 0x03); // 8 bits, no parity, one stop bit - outb(PORT + 2, 0xC7); // Enable FIFO, clear them, with 14-byte threshold - outb(PORT + 4, 0x0B); // IRQs enabled, RTS/DSR set - 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) - - // Check if serial is faulty (i.e: not same byte as sent) - if(inb(PORT + 0) != 0xAE) { - return 1; - } - - // If serial is not faulty set it in normal operation mode - // (not-loopback with IRQs enabled and OUT#1 and OUT#2 bits enabled) - outb(PORT + 4, 0x0F); - return 0; -} - -inline int is_transmit_empty() { - return inb(PORT + 5) & 0x20; -} - -inline void write_serial(char a) { - while (is_transmit_empty() == 0); - - outb(PORT,a); -} - -inline int serial_received() { - return inb(PORT + 5) & 1; -} - -inline char read_serial() { - while (serial_received() == 0); - - return inb(PORT); -} - -inline void print_serial(const char* string ){ - for(size_t i = 0; i < strlen(string); i ++){ - write_serial(string[i]); - } -} - -- 2.39.5 From 6086b04054025c75fa681d00db2f7a3d1a928dcc Mon Sep 17 00:00:00 2001 From: Nigel Date: Sat, 28 Oct 2023 22:28:21 +0200 Subject: [PATCH 2/2] Added klog as a new logging system * The logging system sends the message to both VGA and serial * The serial print uses color to indicate the category of the message Message Categories | Colours Debug Green Info Blue Error Red --- kernel/Makefile | 6 +++-- kernel/kernel.cpp | 23 +++++++++---------- kernel/klog.cpp | 58 +++++++++++++++++++++++++++++++++++++++++++++++ kernel/klog.h | 12 ++++++++++ 4 files changed, 85 insertions(+), 14 deletions(-) create mode 100644 kernel/klog.cpp create mode 100644 kernel/klog.h diff --git a/kernel/Makefile b/kernel/Makefile index 2e6c7d5..cdfab63 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -35,7 +35,8 @@ OFILES = $(OBJ_DIR)/boot.o \ $(OBJ_DIR)/rsdp.o \ $(OBJ_DIR)/acpi.o \ $(OBJ_DIR)/fat.o \ - $(OBJ_DIR)/serial.o + $(OBJ_DIR)/serial.o \ + $(OBJ_DIR)/klog.o OBJ_LINK_LIST = $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(OFILES) $(CRTEND_OBJ) $(CRTN_OBJ) INTERNAL_OBJS = $(CRTI_OBJ) $(OFILES) $(CRTN_OBJ) @@ -125,7 +126,8 @@ $(OBJ_DIR)/fat.o: $(OBJ_DIR)/serial.o: $(CPP) -c drivers/serial/serial.cpp -o $(OBJ_DIR)/serial.o $(CFLAGS) -fno-exceptions -fno-rtti - +$(OBJ_DIR)/klog.o: + $(CPP) -c klog.cpp -o $(OBJ_DIR)/klog.o $(CFLAGS) -fno-exceptions -fno-rtti # Assembly -> Object files $(OBJ_DIR)/boot.o: diff --git a/kernel/kernel.cpp b/kernel/kernel.cpp index e91bc87..4ac7889 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -16,7 +16,8 @@ #include "storage/filesystems/FAT/FAT.h" #include "acpi/acpi.h" #include "memory/VirtualMemoryManager.h" -#include "drivers/serial/serial.h" +#include "klog.h" + extern BootInfoBlock* BIB; extern "C" void LoadGlobalDescriptorTable(); @@ -45,9 +46,14 @@ extern "C" void kernel () initidt(); LoadGlobalDescriptorTable(); flush_tss(); - printf("Memory setup complete!\n"); + + + print_info("Memory setup complete!\n"); // Enable interrupts asm volatile("STI"); + + + initHeap(); //pit_initialise(); @@ -59,16 +65,9 @@ extern "C" void kernel () initBootDrive(); VirtualFileSystem::initialize(); - - // Test new serial driver - SerialConfig debug_com1_config{ - COM1, - 0x03, - 0x00 - }; - Serial com1 = Serial(debug_com1_config); - - com1.write((void*)"Hello world!\n", 14); + print_dbg("Hello debug!\n"); + print_info("Hello info!\n"); + print_err("Hello error!\n"); #define VFS_EXAMPLE #ifdef VFS_EXAMPLE diff --git a/kernel/klog.cpp b/kernel/klog.cpp new file mode 100644 index 0000000..df954b8 --- /dev/null +++ b/kernel/klog.cpp @@ -0,0 +1,58 @@ +// +// Created by nigel on 10/28/23. +// +#include "klog.h" +#include "terminal/kterm.h" +#include + +const char* ForeGroundColourReset = "\e[39m"; +void print_dbg(const char* message, ...){ + auto **arg = (unsigned char**)&message; + // Send it to the VGA + printf(message, arg); + + // Now send the message to the serial + Serial com1= Serial({ + COM1, + 0x03, + 0x00 + }); + + const char* ForeGroundColour = "\e[32m"; + com1.write((void*)ForeGroundColour, strlen(ForeGroundColour)); + com1.write((void*)message, strlen(message)); + com1.write((void*)ForeGroundColourReset, strlen(ForeGroundColourReset)); + +} + + +void print_info(const char* message, ...){ + auto **arg = (unsigned char**)&message; + // Send it to the VGA + printf(message, arg); + + Serial com1 = Serial({ + COM1, + 0x03, + 0x00 + }); + + const char* ForeGroundColour = "\e[34m"; + com1.write((void*)ForeGroundColour, strlen(ForeGroundColour)); + com1.write((void*)message, strlen(message)); + com1.write((void*)ForeGroundColourReset, strlen(ForeGroundColourReset)); +} +void print_err(const char* message, ...){ + auto **arg = (unsigned char**)&message; + // Send it to the VGA + printf(message, arg); + Serial com1 = Serial({ + COM1, + 0x03, + 0x00 + }); + const char* ForeGroundColour = "\e[31m"; + com1.write((void*)ForeGroundColour, strlen(ForeGroundColour)); + com1.write((void*)message, strlen(message)); + com1.write((void*)ForeGroundColourReset, strlen(ForeGroundColourReset)); +} diff --git a/kernel/klog.h b/kernel/klog.h new file mode 100644 index 0000000..d121dc3 --- /dev/null +++ b/kernel/klog.h @@ -0,0 +1,12 @@ +// +// Created by nigel on 10/28/23. +// +#pragma once + +#include "drivers/serial/serial.h" + + + +void print_dbg(const char* message, ...); +void print_info(const char* message, ...); +void print_err(const char* message, ...); -- 2.39.5