3 Commits
dev ... Temp

Author SHA1 Message Date
b3392eb322 WIP: drivers and boot 2025-11-16 20:41:20 +01:00
6086b04054 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
2023-10-28 22:28:21 +02:00
9c5667c454 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)
2023-10-28 21:51:04 +02:00
12 changed files with 298 additions and 145 deletions

View File

@ -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

View File

@ -59,6 +59,10 @@ _start:
movl $(boot_page_table - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 0
movl $(boot_page_table - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 768 * 4
# movl source, destination
movl $(boot_page_directory - 0xC0000000 + 0x003), boot_page_directory - 0xC0000000 + 1024 * 4
# Set cr3 to the address of the boot_page_directory
movl $(boot_page_directory - 0xC0000000), %ecx
movl %ecx, %cr3
@ -98,7 +102,7 @@ isPaging:
call prekernelSetup
# Unmap the identity mapping as it is now unnecessary
# movl $0, boot_page_directory + 0
movl $0, boot_page_directory + 0
call kernel

View File

@ -0,0 +1,35 @@
#include "rtl8139.h"
#include "../io/io.h"
rtl8139::rtl8139(){
}
rtl8139::~rtl8139(){
}
void rtl8139::Wake(){
outb(ioaddr + CONFIG_1, 0x0);
}
void rtl8139::Reset(){
outb(ioaddr + CMD_OFFSET, 0x10);
// Wait for the reset procedure
while((inb(ioaddr + CMD_OFFSET) & 0x10) != 0) continue;
}
void rtl8139::Sleep(){
}
void rtl8139::Receive(){
}
void rtl8139::Transmit(){
}

View File

@ -0,0 +1,35 @@
#pragma once
#define MAC05_OFFSET 0x00 // size 6
#define MAC07_OFFSET 0x08 // size 8
#define RBSTART_OFFSET 0x30 // size 4
#define CMD_OFFSET 0x37 // size 1
#define IMR_OFFSET 0x3C // size 2
#define ISR_OFFSET 0x3E // size 2
#define CONFIG_1 0x52
// Copyright © Nigel Barink 2023
// Information source: https://wiki.osdev.org/RTL8139
// Get me some networking !! XD
class NetworkDevice {
protected:
};
class rtl8139 : public NetworkDevice {
public:
rtl8139();
~rtl8139();
void Wake();
void Reset();
void Sleep();
void Receive();
void Transmit();
private:
int ioaddr ;
};

View File

@ -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!
int Serial::is_transmit_empty() {
return inb(port + 5) & 0x20;
}

View File

@ -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
};
struct SerialConfig {
SERIALPORT port;
char baud_rate_lo ;
char baud_rate_hi;
};
class Serial {
public:
static Serial init();
Serial (SerialConfig config );
void print();
char read();
void write(void* data, int length);
private:
const int COM1 = 0x3F8;
const int COM2 = 0x2F8;
const int COM3 = 0x3E8;
const int COM4 = 0x2E8;
Serial();
~Serial();
SERIALPORT port;
int is_transmit_empty();
};

View File

@ -4,7 +4,7 @@
#include "../i386/processor.h"
#include "../memory/VirtualMemoryManager.h"
#include "../syscalls.h"
#include "../klog.h"
IDT_entry idt_table[256];
IDT_ptr idt_ptr;
@ -91,7 +91,6 @@ void irs_handler (registers* regs) {
printf("EIP: 0x%x\n", regs->eip);
printf("EAX: 0x%x\n", regs->eax);
printf("EBP: 0x%x\n", regs->ebp);
while(true);
break;
case 9:

View File

@ -1,23 +1,22 @@
/*
Copyright © Nigel Barink 2023
*/
#include "memory/memory.h"
#include "memory/KernelHeap.h"
#include "memory/gdt/gdtc.h"
#include "memory/TaskStateSegment.h"
#include "supervisorterminal/superVisorTerminal.h"
#include "drivers/vga/VBE.h"
#include "pci/pci.h"
#include "drivers/pit/pit.h"
#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 "drivers/pit/pit.h"
#include "drivers/vga/VBE.h"
#include "i386/processor.h"
#include "interrupts/idt.h"
#include "klog.h"
#include "memory/KernelHeap.h"
#include "memory/TaskStateSegment.h"
#include "memory/VirtualMemoryManager.h"
#include "memory/gdt/gdtc.h"
#include "memory/memory.h"
#include "pci/pci.h"
#include "storage/filesystems/FAT/FAT.h"
#include "storage/vfs/vfs.h"
#include "supervisorterminal/superVisorTerminal.h"
#include "terminal/kterm.h"
extern BootInfoBlock *BIB;
extern "C" void LoadGlobalDescriptorTable();
@ -37,38 +36,57 @@ void initBootDrive(){
printf("Part1: %d, Part2: %d, Part3: %d\n", part1, part2, part3);
ATAPIO::Identify(ATAPIO_PORT::Primary, DEVICE_DRIVE::MASTER);
}
extern uint32_t *boot_page_directory;
extern "C" void kernel() {
while (true) {
__asm__ __volatile__("NOP");
};
// kterm_init();
uint32_t cr3;
__asm__ __volatile__("mov %%cr3, %%eax\n\t"
"mov %%eax, %0\n\t"
: "=m"(cr3)
:
: "%eax");
printf("value of cr3: 0x%x\n", cr3);
// printf("page directory entry : 0x%x\n" , boot_page_directory[1023]);
while (true)
;
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();
pit_initialise();
//ACPI::initialize();
//PCI::Scan();
PCI::Scan();
processor::initialize();
processor::enable_protectedMode();
initBootDrive();
VirtualFileSystem::initialize();
print_serial("Run test!");
print_dbg("Hello debug!\n");
print_info("Hello info!\n");
print_err("Hello error!\n");
ACPI::initialize();
#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
@ -78,5 +96,4 @@ extern "C" void kernel ()
startSuperVisorTerminal();
#endif
}

58
kernel/klog.cpp Normal file
View File

@ -0,0 +1,58 @@
//
// Created by nigel on 10/28/23.
//
#include "klog.h"
#include "terminal/kterm.h"
#include <CoreLib/Memory.h>
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));
}

12
kernel/klog.h Normal file
View File

@ -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, ...);

View File

@ -53,7 +53,7 @@ extern "C" void prekernelSetup ( unsigned long magic, multiboot_info_t* mbi)
if(mmap->type == MULTIBOOT_MEMORY_ACPI_RECLAIMABLE)
allocate_region(mmap->addr, mmap->len);
// memory map
Immediate_Map(mmap->addr , mmap->addr);
Immediate_Map(PADDR_TO_VADDR(mmap->addr) , mmap->addr);
if(mmap->type == MULTIBOOT_MEMORY_RESERVED)
allocate_region(mmap->addr, mmap->len);
if(mmap->type == MULTIBOOT_MEMORY_NVS)

View File

@ -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]);
}
}