From 97606dbf7187933a9602de4ea7c20fcb547e9721 Mon Sep 17 00:00:00 2001 From: Nigel Date: Wed, 29 Dec 2021 16:15:18 +0100 Subject: [PATCH] Clean up of debugging logs and new commands. As this project grows it becomes important to keep things properly organised. In this commit I've put some effort into making the kernel.cpp file more consise and thus improve its readability. Certain parts of the code have gotten their own definition file where before it was only a header file. - Moving the Supervisor Terminal into its own definition file. - Subtracting debugging messages with preprocessor ifdef's - Time and Date is now not just a header but has its own proper definition file - Banner is displayed when booting up - Terminal has a couple new commands Commmand Description =================|||||=================================================== DATE (was TIME) Displays the curren time, date and ticks VERSION Displays system version information MEMORY Displays memory information --- Makefile | 11 +- src/kernel/bootcheck.h | 35 ++-- src/kernel/disk.h | 17 -- src/kernel/gdt/gdtc.cpp | 3 +- src/kernel/idt/idt.cpp | 4 +- src/kernel/kernel.cpp | 39 +++-- src/kernel/kernel.h | 21 +-- src/kernel/pit.cpp | 5 +- src/kernel/serial.h | 6 +- src/kernel/sv-terminal/superVisorTerminal.cpp | 74 ++++++++ src/kernel/sv-terminal/superVisorTerminal.h | 8 + src/kernel/time.cpp | 111 ++++++++++++ src/kernel/time.h | 160 ++---------------- 13 files changed, 289 insertions(+), 205 deletions(-) delete mode 100644 src/kernel/disk.h create mode 100644 src/kernel/sv-terminal/superVisorTerminal.cpp create mode 100644 src/kernel/sv-terminal/superVisorTerminal.h create mode 100644 src/kernel/time.cpp diff --git a/Makefile b/Makefile index 0828ddc..afdeb22 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ CC = ${HOME}/opt/cross/bin/i686-elf-gcc CPP = ${HOME}/opt/cross/bin/i686-elf-g++ CFLAGS = -ffreestanding -O2 -Wall -Wextra -OFILES = $(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/string.o +OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/PhysicalMemoryManager.o $(BUILD_DIR)/io.o $(BUILD_DIR)/PageDirectory.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o $(BUILD_DIR)/PageFrameAllocator.o SRC_DIR = src BUILD_DIR = build @@ -33,7 +33,7 @@ iso: clean_iso clean build cp src/grub.cfg root/boot/grub/grub.cfg grub-mkrescue -o build/barinkOS.iso root -test: +run: all $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo build_kernel: $(OBJ_LINK_LIST) @@ -90,3 +90,10 @@ $(BUILD_DIR)/pit.o: $(BUILD_DIR)/keyboard.o: $(CPP) -c $(SRC_DIR)/kernel/keyboard/keyboard.cpp -o $(BUILD_DIR)/keyboard.o $(CFLAGS) -fno-exceptions -fno-rtti + + +$(BUILD_DIR)/time.o: + $(CPP) -c $(SRC_DIR)/kernel/time.cpp -o $(BUILD_DIR)/time.o $(CFLAGS) -fno-exceptions -fno-rtti + +$(BUILD_DIR)/sv-terminal.o: + $(CPP) -c $(SRC_DIR)/kernel/sv-terminal/superVisorTerminal.cpp -o $(BUILD_DIR)/sv-terminal.o $(CFLAGS) -fno-exceptions -fno-rtti diff --git a/src/kernel/bootcheck.h b/src/kernel/bootcheck.h index 028eeba..62765a5 100644 --- a/src/kernel/bootcheck.h +++ b/src/kernel/bootcheck.h @@ -10,66 +10,81 @@ void CheckMBT ( multiboot_info_t* mbt ){ /* Set MBI to the addresss of the multiboot information structure*/ multiboot_info_t * mbi = (multiboot_info_t *) mbt; +#ifdef __VERBOSE__ /* Print out the flags */ printf("flags = 0x%x\n", (unsigned) mbi->flags); - +#endif /* Are mem_* valid? */ if ( CHECK_FLAG(mbi->flags,0)){ - printf("mem_lower = %uKB, mem_upper = %uKB\n"); + // Do nothing } /* is boot device valid ? */ - if (CHECK_FLAG (mbi->flags, 1)){ + if (CHECK_FLAG (mbi->flags, 1)) + { +#ifdef __VERBOSE__ printf("boot_device = 0x0%x\n", (unsigned) mbi->boot_device); +#endif } /* is the command line passed? */ - if (CHECK_FLAG ( mbi->flags,2)){ + if (CHECK_FLAG ( mbi->flags,2)) + { +#ifdef __VERBOSE__ printf("cmdline = %s\n", (char *) mbi->cmdline); +#endif } /* Are mods_* valid? */ if(CHECK_FLAG ( mbi->flags, 3)){ multiboot_module_t *mod; uint32_t i; - +#ifdef __VERBOSE__ printf("mods count = %d, mods_addr = 0x%x\n", (int) mbi->mods_count, (int) mbi->mods_addr); for(i = 0, mod = (multiboot_module_t *) mbi->mods_addr; i < mbi->mods_count; i++ , mod++){ printf(" mod start = 0x%x, mod_end = 0x%x, cmdline = %s\n", (unsigned) mod->mod_start, (unsigned) mod->mod_end, (char*) mod->cmdline); } +#endif } /* Bits 4 and 5 are mutually exclusive! */ - if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)){ + if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG(mbi->flags, 5)) + { +#ifdef __VERBOSE__ printf("Both bits 4 and 5 are set.\n"); +#endif return; } /* Is the symbol table of a.out valid? */ if (CHECK_FLAG(mbi->flags, 4)){ multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym); - +#ifdef __VERBOSE__ printf( "multiboot_aout_symbol_table: tabsize = 0x%0x, strsize = 0x%x, addr = 0x%x\n", (unsigned) multiboot_aout_sym->tabsize, (unsigned) multiboot_aout_sym->strsize, (unsigned) multiboot_aout_sym->addr); - +#endif } /* Is the section header table of ELF valid? */ if (CHECK_FLAG(mbi->flags, 5)){ multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec); - +#ifdef __VERBOSE__ printf("multiboot_elf_sec: num = %u, size = 0x%x, addr = 0x%x, shnd = 0x%x\n", + (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size, (unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx); +#endif } /* Draw diagonal blue line */ if (CHECK_FLAG (mbt->flags, 12)){ - printf("Can draw!"); +#ifdef __VERBOSE__ + printf("Can draw!\n"); +#endif } diff --git a/src/kernel/disk.h b/src/kernel/disk.h deleted file mode 100644 index 7ba3925..0000000 --- a/src/kernel/disk.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -// Let's write an ATA PIO | ATA driver for now. Mostly to show that I can in theory interact with a -// storage device - -// PRIMARY_ATA_BUS -// 0x1F0 through 0x1F7 - -// SECONDARY_ATA_BUS -// 0x170 through 0x177 - -#define DEVICE_CONTROL_REGISTER 0x3F6 -#define DEVICE_CONTROL_ALTERNATE 0x376 - - -// IRQ14 Primary bus interrupt -// IRQ15 Secondary bus interrupt diff --git a/src/kernel/gdt/gdtc.cpp b/src/kernel/gdt/gdtc.cpp index 9ff30d0..c2d7ac6 100644 --- a/src/kernel/gdt/gdtc.cpp +++ b/src/kernel/gdt/gdtc.cpp @@ -29,8 +29,9 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne void initGDT(){ +#ifdef __VERBOSE__ printf("Init GDT!\n"); - +#endif // NULL segment add_descriptor(NULL_SEGMENT, 0,0,0,0); diff --git a/src/kernel/idt/idt.cpp b/src/kernel/idt/idt.cpp index 74fa3ae..393902b 100644 --- a/src/kernel/idt/idt.cpp +++ b/src/kernel/idt/idt.cpp @@ -254,8 +254,10 @@ void init_idt(){ idt_ptr.length = sizeof(IDT_entry) * 255; idt_ptr.base = (uint32_t)&idt_table; +#ifdef __VERBOSE__ printf("Init IDT\n"); - +#endif + // TODO: Set everything to zero first set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8F); diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 274fa30..04c2ff1 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -4,28 +4,45 @@ extern "C" void kernel_main (void); extern "C" void early_main(unsigned long magic, unsigned long addr){ - /** initialize terminal interface */ + /** + * Initialize terminal interface + * NOTE: This should be done later on , the magic value should be checked first. + */ kterm_init(); - // Check Multiboot magic number + /** + * Check Multiboot magic number + * NOTE: Printf call should not be a thing this early on ... + */ if (magic != MULTIBOOT_BOOTLOADER_MAGIC){ printf("Invalid magic number: 0x%x\n", magic); return; } - multiboot_info_t* mbt = (multiboot_info_t*) addr; + /** + * Show a little banner for cuteness + */ + printf("|=== BarinkOS ===|\n"); - /* Are mmap_* valid? */ - if (CHECK_FLAG(mbt->flags, 6)){ + + /** + * Use the address given as an argument as the pointer + * to a Multiboot information structure. + */ + multiboot_info_t* mbt = (multiboot_info_t*) addr; + + /* + If we got a memory map from our bootloader we + should be parsing it to find out the memory regions available. + */ + if (CHECK_FLAG(mbt->flags, 6)) + { + printf("Preliminary results mmap scan:\n"); + mapMultibootMemoryMap(mbt); + PhysicalMemoryManager_initialise( mbt->mmap_addr, GB2/* Seriously dangerous hardcoded memory value*/); PhysicalMemoryManager_initialise_available_regions(mbt->mmap_addr, mbt->mmap_addr + mbt->mmap_length); PhysicalMemoryManager_deinitialise_kernel(); - extern uint8_t* kernel_begin; - extern uint8_t* kernel_end; - - printf("Kernel MemoryMap:\n"); - printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end); - printf("Frames used: 0x%x blocks of 4 KiB\n", used_blocks); } initGDT(); diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 88b2ef9..63570b5 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -7,30 +7,21 @@ extern "C"{ #include "./bootloader/multiboot.h" #include "bootcheck.h" -#include "memory/PhysicalMemoryManager.h" +#include "memory/physical/PhysicalMemoryManager.h" +#include "memory/frames/PageFrameAllocator.h" #include "gdt/gdtc.h" #include "idt/idt.h" -#include "keyboard/keyboard.h" - #include "pit.h" #include "io.h" -#include "time.h" #include "cpu.h" #include "serial.h" +#include "time.h" +#include "sv-terminal/superVisorTerminal.h" + #define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) -#define PANIC(message) { return; } +#define PANIC(message) {return;} -/* This needs to be moved! */ -/** - * simple delay function - **/ -void delay(int t){ - volatile int i,j; - for(i=0;i$ " ); + int characterCount = 0; + char command[10] = ""; + + // NOTE: lets just show a kernel prompt + uint8_t ScanCode = getKey(); + while( ScanCode != 0x1C ) + { + char character = getASCIIKey(); + kterm_put(character ); + // wHAT THE HELL + + if( characterCount < 10 ){ + command[characterCount] = character; + characterCount++; + } + + ScanCode = getKey(); + } + printf("\n"); + KeyHandled(); + + + if ( strncmp("DATE", command , characterCount ) == 0 ) + { + read_rtc(); + printf("======= Time & Date ==========\n"); + printf(" - Date: %02d-%02d-%02d\n",day, month, year); + printf(" - Time: %02d:%02d:%02d\n" , hour, minute, second); + printf(" - Ticks: %09d\n", pit_tick); + } + else if( strncmp ("MEMORY" , command , characterCount) == 0 ) + { + // Show memory layout + printf("========= Memory ==========\n"); + printf("Kernel MemoryMap:\n"); + printf("kernel: 0x%x - 0x%x\n", &kernel_begin , &kernel_end); + printf("Frames used: 0x%x blocks of 4 KiB\n", used_blocks); + //printf("\n\n"); + //PrintPhysicalMemoryAllocation( ); + + + } + else if(strncmp("TEST", command, characterCount) == 0) + { + // TEST #DE exception + asm volatile ("MOV $4, %AX ; MOV $0, %BX ; DIV %BX"); // IRS 0 + } + else if (strncmp("VERSION", command , characterCount) == 0) + { + // Show version information + printf("========= Version ========\n"); + printf("Kernel v%d\n", 0); + + } + else if(strncmp("CLEAR", command, characterCount) == 0) + { + kterm_init(); + printf("|=== BarinkOS ===|\n"); + } + else + { + printf("Unknown command\n"); + } + + + delay(1000); + } +} \ No newline at end of file diff --git a/src/kernel/sv-terminal/superVisorTerminal.h b/src/kernel/sv-terminal/superVisorTerminal.h new file mode 100644 index 0000000..8f83a15 --- /dev/null +++ b/src/kernel/sv-terminal/superVisorTerminal.h @@ -0,0 +1,8 @@ +#pragma once +#include "../tty/kterm.h" +#include "../time.h" +#include "../pit.h" +#include "../keyboard/keyboard.h" +#include "../memory/physical/PhysicalMemoryManager.h" + +void startSuperVisorTerminal(); \ No newline at end of file diff --git a/src/kernel/time.cpp b/src/kernel/time.cpp new file mode 100644 index 0000000..325aece --- /dev/null +++ b/src/kernel/time.cpp @@ -0,0 +1,111 @@ +#include "time.h" + +// Set by ACPI table parsing code if possible +int century_register = 0x00; +unsigned char second; +unsigned char minute; +unsigned char hour; +unsigned char day; +unsigned char month; +unsigned int year; + + +int get_update_in_progress_flag() { + outb(cmos_address, 0x0A); + return (inb(cmos_data) & 0x80); +} + +unsigned char get_RTC_register(int reg) { + outb(cmos_address, reg); + return inb(cmos_data); +} + +void read_rtc() { + unsigned char century; + unsigned char last_second; + unsigned char last_minute; + unsigned char last_hour; + unsigned char last_day; + unsigned char last_month; + unsigned char last_year; + unsigned char last_century; + unsigned char registerB; + + // Note: This uses the "read registers until you get the same values twice in a row" technique + // to avoid getting dodgy/inconsistent values due to RTC updates + + while (get_update_in_progress_flag()); // Make sure an update isn't in progress + second = get_RTC_register(0x00); + minute = get_RTC_register(0x02); + hour = get_RTC_register(0x04); + day = get_RTC_register(0x07); + month = get_RTC_register(0x08); + year = get_RTC_register(0x09); + if(century_register != 0) { + century = get_RTC_register(century_register); + } else { + century = 21; + } + + do { + last_second = second; + last_minute = minute; + last_hour = hour; + last_day = day; + last_month = month; + last_year = year; + last_century = century; + + while (get_update_in_progress_flag()); // Make sure an update isn't in progress + second = get_RTC_register(0x00); + minute = get_RTC_register(0x02); + hour = get_RTC_register(0x04); + day = get_RTC_register(0x07); + month = get_RTC_register(0x08); + year = get_RTC_register(0x09); + if(century_register != 0) { + century = get_RTC_register(century_register); + } + } while( (last_second != second) || (last_minute != minute) || (last_hour != hour) || + (last_day != day) || (last_month != month) || (last_year != year) || + (last_century != century) ); + + registerB = get_RTC_register(0x0B); + + // Convert BCD to binary values if necessary + + if (!(registerB & 0x04)) { + second = (second & 0x0F) + ((second / 16) * 10); + minute = (minute & 0x0F) + ((minute / 16) * 10); + hour = ( (hour & 0x0F) + (((hour & 0x70) / 16) * 10) ) | (hour & 0x80); + day = (day & 0x0F) + ((day / 16) * 10); + month = (month & 0x0F) + ((month / 16) * 10); + year = (year & 0x0F) + ((year / 16) * 10); + if(century_register != 0) { + century = (century & 0x0F) + ((century / 16) * 10); + } + } + + // Convert 12 hour clock to 24 hour clock if necessary + + if (!(registerB & 0x02) && (hour & 0x80)) { + hour = ((hour & 0x7F) + 12) % 24; + } + + // Calculate the full (4-digit) year + + if(century_register != 0) { + year += century * 100; + } else { + year += (CURRENT_YEAR / 100) * 100; + if(year < CURRENT_YEAR) year += 100; + } +} + + +void delay(int t){ + volatile int i,j; + for(i=0;i