diff --git a/kernel/Makefile b/kernel/Makefile index 8fdb8ad..cdfab63 100644 --- a/kernel/Makefile +++ b/kernel/Makefile @@ -34,7 +34,9 @@ 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_DIR)/klog.o OBJ_LINK_LIST = $(CRTI_OBJ) $(CRTBEGIN_OBJ) $(OFILES) $(CRTEND_OBJ) $(CRTN_OBJ) INTERNAL_OBJS = $(CRTI_OBJ) $(OFILES) $(CRTN_OBJ) @@ -121,6 +123,12 @@ $(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 + +$(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: $(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..4ac7889 100644 --- a/kernel/kernel.cpp +++ b/kernel/kernel.cpp @@ -12,11 +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 "klog.h" extern BootInfoBlock* BIB; @@ -40,20 +40,21 @@ 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"); + + + print_info("Memory setup complete!\n"); // Enable interrupts asm volatile("STI"); + + + initHeap(); - print_serial("Heap initialized...\n"); //pit_initialise(); @@ -64,11 +65,16 @@ extern "C" void kernel () initBootDrive(); VirtualFileSystem::initialize(); - print_serial("Run test!"); + print_dbg("Hello debug!\n"); + print_info("Hello info!\n"); + print_err("Hello error!\n"); + #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/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, ...); 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]); - } -} -