From 88cc1d75bb0a38144f9ed543c049a8efaa509dd2 Mon Sep 17 00:00:00 2001 From: Nigel Date: Mon, 20 Dec 2021 21:53:57 +0100 Subject: [PATCH 1/6] Re-enabled interrupts from keyboard, Enabled and configured the PIT to throw interrupts at a regular interval --- Makefile | 9 +++---- src/kernel/boot.S | 40 +++++++++++-------------------- src/kernel/gdt/gdtc.cpp | 8 ++----- src/kernel/idt/idt.cpp | 37 +++++++++++++--------------- src/kernel/io.cpp | 2 +- src/kernel/kernel.cpp | 19 ++++++++++++--- src/kernel/kernel.h | 1 + src/kernel/pit.cpp | 53 +++++++++++++++++++++++++++++++++++++++++ src/kernel/pit.h | 18 ++++++++++++++ src/kernel/serial.h | 1 + 10 files changed, 128 insertions(+), 60 deletions(-) create mode 100644 src/kernel/pit.cpp create mode 100644 src/kernel/pit.h diff --git a/Makefile b/Makefile index afa65c7..5ea7845 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)/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)/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 SRC_DIR = src BUILD_DIR = build @@ -23,8 +23,6 @@ all: clean build build: build_kernel iso - - clean_iso: if [[ -a isodir/boot ]] ; then rm root/boot -rd ; fi if [ -f build/barinkOS.iso ] ; then rm build/barinkOS.iso ; fi @@ -36,7 +34,7 @@ iso: clean_iso clean build grub-mkrescue -o build/barinkOS.iso root test: - $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -monitor stdio -display gtk -m 2G -cpu core2duo + $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo build_kernel: $(OBJ_LINK_LIST) $(CC) -T $(SRC_DIR)/kernel//linker.ld -o $(BUILD_DIR)/myos.bin \ @@ -85,3 +83,6 @@ $(BUILD_DIR)/string.o: $(BUILD_DIR)/PhysicalMemoryManager.o: $(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti + +$(BUILD_DIR)/pit.o: + $(CPP) -c $(SRC_DIR)/kernel/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti diff --git a/src/kernel/boot.S b/src/kernel/boot.S index 0c79b10..4b38316 100644 --- a/src/kernel/boot.S +++ b/src/kernel/boot.S @@ -21,6 +21,7 @@ stack_bottom: stack_top: .section .text +.include "./src/kernel/gdt/gdt.s" .include "./src/kernel/irs_table.s" .include "./src/kernel/irq_table.s" .include "./src/kernel/idt/idt.s" @@ -45,34 +46,21 @@ _start: pushl %eax call early_main + + + mov %cr0, %eax + or $1, %eax + mov %eax, %cr0 + + + call kernel_main + + cli - - - -.include "./src/kernel/gdt/gdt.s" - - loadIDT: - #load idt - call init_idt - sti - - # Try enable A20 - # mov $0x2401, %ax - # int $0x15 +1: hlt + jmp 1b - # enable protected mode - mov %cr0, %eax - or $1, %eax - mov %eax, %cr0 - - - call kernel_main +.size _start, . - _start - cli - 1: hlt - jmp 1b - - -.size _start, . - _start \ No newline at end of file diff --git a/src/kernel/gdt/gdtc.cpp b/src/kernel/gdt/gdtc.cpp index f2624bf..9ff30d0 100644 --- a/src/kernel/gdt/gdtc.cpp +++ b/src/kernel/gdt/gdtc.cpp @@ -29,6 +29,8 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne void initGDT(){ + printf("Init GDT!\n"); + // NULL segment add_descriptor(NULL_SEGMENT, 0,0,0,0); @@ -52,10 +54,4 @@ void initGDT(){ LoadGlobalDescriptorTable(); - while (true) - asm volatile("hlt"); - - - - } diff --git a/src/kernel/idt/idt.cpp b/src/kernel/idt/idt.cpp index 3334a3b..8e6fbf8 100644 --- a/src/kernel/idt/idt.cpp +++ b/src/kernel/idt/idt.cpp @@ -1,4 +1,5 @@ #include "idt.h" +#include "../pit.h" //#include "scancodes/set1.h" IDT_entry idt_table[256]; @@ -24,6 +25,8 @@ void irs_handler (registers regs) { } + + @@ -32,36 +35,33 @@ void irs_handler (registers regs) { void irq_handler (registers regs) { - - - if ( regs.int_no != 0) { - kterm_writestring("received interrupt!\n"); - printf("(IRQ) Interrupt number: %d \n", regs.int_no); - - } - - if ( regs.int_no == 1 ){ + + switch (regs.int_no) + { + case 0: + pit_tick++; + break; + case 1: // Keyboard interrupt !! int scan; /*register*/int i; // Read scancode - scan = inb(0x60); // Send ack message! i = inb(0x61); outb(0x61, i|0x80); outb(0x61, i); - kterm_writestring("A key was pressed/released\n"); printf( "Scancode: %x\n", scan); + break; - - } + default: + printf("Received INT: 0x%x\n", regs.int_no); + break; + } - - outb(0x20, 0x20); // send end of interrupt to master if ( regs.int_no > 8 && regs.int_no <= 15) { @@ -76,16 +76,13 @@ void irq_handler (registers regs) { } - - - - void init_idt(){ // Initialise the IDT pointer idt_ptr.length = sizeof(IDT_entry) * 255; idt_ptr.base = (uint32_t)&idt_table; - + printf("Init IDT\n"); + // TODO: Set everything to zero first set_id_entry(0, (uint32_t) irs0 , 0x08, 0x8F); diff --git a/src/kernel/io.cpp b/src/kernel/io.cpp index 8a0861c..e87fd90 100644 --- a/src/kernel/io.cpp +++ b/src/kernel/io.cpp @@ -22,7 +22,7 @@ unsigned int inl_p(unsigned short ){ } -void outb_p(unsigned char , unsigned short ){ +void b_p(unsigned char , unsigned short ){ } void outw(unsigned short , unsigned short ){ diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index d30350d..4a29ddc 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -1,6 +1,8 @@ #include "kernel.h" -#define GB4 524288 #define GB2 262144 + + extern "C" void kernel_main (void); + extern "C" void early_main(unsigned long magic, unsigned long addr){ /** initialize terminal interface */ kterm_init(); @@ -27,19 +29,30 @@ } initGDT(); + init_idt(); + // Enable interrupts + asm volatile("STI"); + + kernel_main(); } extern "C" void kernel_main (void) { - printf("call to init serial\n"); + init_serial(); + + + pit_initialise(); + + + while (true){ //Read time indefinetely read_rtc(); - printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second); + printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d (Ticks: %06d) [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second, pit_tick); delay(1000); } diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index f82f5da..7618358 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -12,6 +12,7 @@ extern "C"{ #include "gdt/gdtc.h" #include "idt/idt.h" +#include "pit.h" #include "io.h" #include "time.h" #include "cpu.h" diff --git a/src/kernel/pit.cpp b/src/kernel/pit.cpp new file mode 100644 index 0000000..585519b --- /dev/null +++ b/src/kernel/pit.cpp @@ -0,0 +1,53 @@ +#include "pit.h" +#include "tty/kterm.h" +uint32_t pit_tick = 0; + + +void pit_initialise() +{ + asm volatile("CLI"); + + printf("init PIT!\n"); + + // clear mask for IRQ 0 + uint8_t value = inb(0x21) & ~(1<< 0); + outb(0x21, value); + + io_wait(); + + const int freq = 500; + + uint32_t divisor = 1193180 / freq; + + outb(PIT_COMMAND, 0x36); + + uint8_t l = (uint8_t) (divisor & 0xFF); + uint8_t h = (uint8_t) ( (divisor>>8) & 0xff); + + outb(PIT_DATA_0, l); + outb(PIT_DATA_0,h); + + + asm volatile("STI"); +} + + +void get_pit_count() +{ + asm volatile ("CLI"); + + outb(PIT_COMMAND, 0); + uint16_t count = inb(PIT_DATA_0); + count |= inb(PIT_DATA_0) << 8; + + printf("PIT count: 0x%x\n", count); + + asm volatile("STI"); + +} + +void set_pit_count() +{ + +} + diff --git a/src/kernel/pit.h b/src/kernel/pit.h new file mode 100644 index 0000000..361ed4b --- /dev/null +++ b/src/kernel/pit.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include "io.h" +#define PIT_DATA_0 0x40 +#define PIT_DATA_1 0x41 +#define PIT_DATA_2 0x42 +#define PIT_COMMAND 0x43 + + +extern uint32_t pit_tick; + + +void pit_initialise(); + + +void get_pit_count(); + +void set_pit_count(); diff --git a/src/kernel/serial.h b/src/kernel/serial.h index ecc82db..3d0b9ad 100644 --- a/src/kernel/serial.h +++ b/src/kernel/serial.h @@ -4,6 +4,7 @@ #include "io.h" #define PORT 0x3f8 static int init_serial() { + printf("Init serial\n"); 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 From 0d8ef065e0cfd78fd8e968dcab62a75919ec706e Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 28 Dec 2021 19:47:32 +0100 Subject: [PATCH 2/6] Interactive supervisor mode To ease the pain of debuggin I can now interact with the system through a very simplistic terminal. Hopefully things can be tested more easily by activating the piece through a simple command. The max characters for a command is 10. To achieve this I have had to make the following changes. - Changed IRQ to update a global status variable - Added a standalone keyboard driver with getKey functions - Changed the main kernel loop to display a prompt - Added a strncmp function to the clib/string file --- Makefile | 6 ++- src/kernel/idt/idt.cpp | 91 ++++++++++++++++++++------------ src/kernel/kernel.cpp | 62 ++++++++++++++++------ src/kernel/kernel.h | 2 + src/kernel/keyboard/keyboard.cpp | 51 ++++++++++++++++++ src/kernel/keyboard/keyboard.h | 34 ++++++++++++ src/libc/include/string.c | 19 +++++++ src/libc/include/string.h | 3 ++ 8 files changed, 215 insertions(+), 53 deletions(-) create mode 100644 src/kernel/keyboard/keyboard.cpp create mode 100644 src/kernel/keyboard/keyboard.h diff --git a/Makefile b/Makefile index 5ea7845..0828ddc 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)/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)/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 SRC_DIR = src BUILD_DIR = build @@ -86,3 +86,7 @@ $(BUILD_DIR)/PhysicalMemoryManager.o: $(BUILD_DIR)/pit.o: $(CPP) -c $(SRC_DIR)/kernel/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti + + +$(BUILD_DIR)/keyboard.o: + $(CPP) -c $(SRC_DIR)/kernel/keyboard/keyboard.cpp -o $(BUILD_DIR)/keyboard.o $(CFLAGS) -fno-exceptions -fno-rtti diff --git a/src/kernel/idt/idt.cpp b/src/kernel/idt/idt.cpp index 8e6fbf8..8fa0fba 100644 --- a/src/kernel/idt/idt.cpp +++ b/src/kernel/idt/idt.cpp @@ -1,6 +1,6 @@ #include "idt.h" #include "../pit.h" -//#include "scancodes/set1.h" +#include "../keyboard/keyboard.h" IDT_entry idt_table[256]; IDT_ptr idt_ptr; @@ -14,7 +14,6 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ }; - void irs_handler (registers regs) { kterm_writestring("received interrupt!\n"); @@ -36,44 +35,61 @@ void irs_handler (registers regs) { void irq_handler (registers regs) { - switch (regs.int_no) - { - case 0: - pit_tick++; - break; - case 1: - // Keyboard interrupt !! + - int scan; - /*register*/int i; + switch (regs.int_no) { + case 0: + pit_tick++; + break; + case 1: + // Keyboard interrupt !! - // Read scancode - scan = inb(0x60); - - // Send ack message! - i = inb(0x61); - outb(0x61, i|0x80); - outb(0x61, i); - printf( "Scancode: %x\n", scan); - break; + int scan; + int i;/*register*/ - default: - printf("Received INT: 0x%x\n", regs.int_no); - break; - } + // Read scancode + scan = inb(0x60); + + // Send ack message! + i = inb(0x61); + outb(0x61, i|0x80); + outb(0x61, i); - outb(0x20, 0x20); // send end of interrupt to master - - if ( regs.int_no > 8 && regs.int_no <= 15) { - outb(0xA0, 0x20); // send end of interrupt to slave - } - - - if( regs.int_no == 13){ - printf(" Error code: %d \n", regs.err_code); + // NOTE: check for special scan codes + // e.g. modifiers etc.. + if( scan < 0x37){ + //printf("Read from IO: 0x%x\n", scan); + keyPress.ScanCode = scan ; + //printf( "[From Interrupt] Scancode: %x\n", keyPress.ScanCode); } + + break; + case 12: + // PS2 Mouse interrupt + printf("Mouse event triggered!"); + //int event = inb(0x60); + break; + + default: + printf("Interrupt happened!"); + printf("Received INT: 0x%x\n", regs.int_no); + break; + } + + outb(0x20, 0x20); // send end of interrupt to master + + if ( regs.int_no > 8 && regs.int_no <= 15) { + outb(0xA0, 0x20); // send end of interrupt to slave + } + + + if( regs.int_no == 13){ + printf(" Error code: %d \n", regs.err_code); + + } + } void init_idt(){ @@ -122,10 +138,15 @@ void init_idt(){ //print_serial("Remapping PIC\n"); PIC_remap(0x20, 0x28); + // clear mask for IRQ 12 + uint8_t value = inb(0x21) & ~(1<< 12); + outb(0x21, value); + + // pic IRQ Table set_id_entry(32, (uint32_t)irq0, 0x08, 0x8E); - set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E); + set_id_entry(33, (uint32_t)irq1, 0x08, 0x8E); // PS2 Keyboard set_id_entry(34, (uint32_t)irq2, 0x08, 0x8E); set_id_entry(35, (uint32_t)irq3, 0x08, 0x8E); set_id_entry(36, (uint32_t)irq4, 0x08, 0x8E); @@ -136,7 +157,7 @@ void init_idt(){ set_id_entry(41, (uint32_t)irq9, 0x08, 0x8E); set_id_entry(42, (uint32_t)irq10, 0x08, 0x8E); set_id_entry(43, (uint32_t)irq11, 0x08, 0x8E); - set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E); + set_id_entry(44, (uint32_t)irq12, 0x08, 0x8E); // PS2 Mouse set_id_entry(45, (uint32_t)irq13, 0x08, 0x8E); set_id_entry(46, (uint32_t)irq14, 0x08, 0x8E); set_id_entry(47, (uint32_t)irq15, 0x08, 0x8E); diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 4a29ddc..274fa30 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -7,13 +7,12 @@ /** initialize terminal interface */ kterm_init(); + // Check Multiboot magic number if (magic != MULTIBOOT_BOOTLOADER_MAGIC){ printf("Invalid magic number: 0x%x\n", magic); return; } - CheckMBT( (multiboot_info_t *) addr); - multiboot_info_t* mbt = (multiboot_info_t*) addr; /* Are mmap_* valid? */ @@ -26,38 +25,67 @@ 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(); init_idt(); // Enable interrupts asm volatile("STI"); + CheckMBT( (multiboot_info_t *) addr); + + kernel_main(); } extern "C" void kernel_main (void) { - - init_serial(); - - - pit_initialise(); - - while (true){ - //Read time indefinetely - read_rtc(); - printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d (Ticks: %06d) [ Formatted as YY-MM-DD h:mm:ss]\r" ,year, month, day, hour, minute, second, pit_tick); - delay(1000); - } - + + printf("SUPERVISOR:>$ " ); + 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("TIME", command , characterCount ) == 0 ) { + read_rtc(); + printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d (Ticks: %06d)\n" ,year, month, day, hour, minute, second, pit_tick); + } else if(strncmp("TEST", command, characterCount) == 0){ + // asm volatile ("MOV $4, %AX ; MOV $0, %BX ; DIV %BX"); // IRS 0 + } + else{ + printf("Unknown command\n"); + } + + + delay(1000); + } + - + } diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 7618358..88b2ef9 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -12,6 +12,8 @@ extern "C"{ #include "gdt/gdtc.h" #include "idt/idt.h" +#include "keyboard/keyboard.h" + #include "pit.h" #include "io.h" #include "time.h" diff --git a/src/kernel/keyboard/keyboard.cpp b/src/kernel/keyboard/keyboard.cpp new file mode 100644 index 0000000..d526ecc --- /dev/null +++ b/src/kernel/keyboard/keyboard.cpp @@ -0,0 +1,51 @@ +#include "keyboard.h" + +KeyPressInfo keyPress {}; + +void KeyHandled(){ + keyPress.ScanCode= 0x00; + keyPress.PressedModifiers = 0x00; +} + + +char getASCIIKey(){ + char keyPressed; + // Wait until a key is pressed + while(keyPress.ScanCode == 0x00) { + asm volatile ("NOP"); + } + + + // Translate keycode to ascii + // Probably a lookup table might be handy + // Until 0x37 + const char* ASCIILookUp = + "\01234567890-=\0\0QWERTYUIOP[]\0\0ASDFGHJKL;\'`\0\\ZXCVBNM,./\0"; + + uint8_t ASCII_Index = keyPress.ScanCode - 3 ; + //printf("ASCII_INDEX: %x\n", ASCII_Index); + keyPressed = ASCIILookUp[ASCII_Index]; + + KeyHandled(); + + return keyPressed; +} + + + +uint8_t getKey(){ + // Wait until a key is pressed + while(keyPress.ScanCode == 0x00){ + asm volatile ("NOP"); + } + + if( keyPress.ScanCode > 0x37){ + keyPress.ScanCode = 0x00; + return 0; + } + + uint8_t ScanCode = keyPress.ScanCode; + // KeyHandled(); + + return ScanCode ; +} \ No newline at end of file diff --git a/src/kernel/keyboard/keyboard.h b/src/kernel/keyboard/keyboard.h new file mode 100644 index 0000000..09ce1bb --- /dev/null +++ b/src/kernel/keyboard/keyboard.h @@ -0,0 +1,34 @@ +#pragma once +#include +#include "../tty/kterm.h" +typedef enum ScanCodeSet{ + None = 0, + ScanCodeSet1 = 1, + ScanCodeSet2 = 2, + ScanCodeSet3 = 3, +}; + +typedef enum Modifiers{ + LSHIFT = 1, + RSHIFT = 2, + + LCTRL = 3, + RCTRL = 4, + + LALT = 5, + RALT = 6 +}; + +struct KeyPressInfo{ + uint8_t PressedModifiers; + uint8_t ScanCode; +}; + + + +extern KeyPressInfo keyPress; + +void KeyHandled(); + +char getASCIIKey(); +uint8_t getKey(); diff --git a/src/libc/include/string.c b/src/libc/include/string.c index 60b96b8..a45162c 100644 --- a/src/libc/include/string.c +++ b/src/libc/include/string.c @@ -6,4 +6,23 @@ size_t strlen(const char* str) { len++; } return len; +} + + + +int strncmp ( const char* str1, const char* str2, size_t num ){ + for( int i = 0; i < num ; i++){ + + if( str1[i] < str2[i]){ + return -1; + } + + if( str1[i] > str2[i] ){ + return 1; + } + + + } + + return 0; } \ No newline at end of file diff --git a/src/libc/include/string.h b/src/libc/include/string.h index 90329e9..fb8d746 100644 --- a/src/libc/include/string.h +++ b/src/libc/include/string.h @@ -1,3 +1,6 @@ #pragma once #include size_t strlen(const char* str); + + +int strncmp ( const char* str1, const char* str2, size_t num ); \ No newline at end of file From 7496299761b4ba5f530dd0e5e1e237b1b30b1a12 Mon Sep 17 00:00:00 2001 From: Nigel Date: Tue, 28 Dec 2021 19:54:10 +0100 Subject: [PATCH 3/6] Basic Intel Exceptions Any interrupt thrown for any Intel defined Exception is not only being caught but displays an appropriate message to the screen. Changes made in src/kernel/idt/idt.cpp --- src/kernel/idt/idt.cpp | 181 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 169 insertions(+), 12 deletions(-) diff --git a/src/kernel/idt/idt.cpp b/src/kernel/idt/idt.cpp index 8fa0fba..74fa3ae 100644 --- a/src/kernel/idt/idt.cpp +++ b/src/kernel/idt/idt.cpp @@ -15,24 +15,181 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ }; void irs_handler (registers regs) { - kterm_writestring("received interrupt!\n"); - printf("(IRS) Interrupt number: %d \n", regs.int_no); - - if( regs.int_no == 13){ - printf(" Error code: %d \n", regs.err_code); - - } + //printf("(IRS) Interrupt number: %d \r", regs.int_no); + switch (regs.int_no) + { + case 0: + // Divide Error #DE + printf("#DE\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + case 1: + // Debug Exception #DB + printf("#DB\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; - - - + case 2: + // NMI Interrupt + printf("#NMI\n"); + break; + + case 3: + // Breakpoint Exception #BP + printf("#BP\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 4: + // Overflow Exception #OF + printf("#OF\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 5: + // BOUND Range Exceeded Exception #BR + printf("#BR\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 6: + // Invalid OpCode Exception #UD + printf("#UD\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 7: + // Device Not Available Exception #NM + printf("#NM\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 8: + // Double Fault Exception #DF + printf("#DF\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + case 9: + // Coprocessor Segment Overrun + printf("Coprocessor Segment overrun!\n"); + break; + + case 10: + // Invalid TSS Exception #TS + printf("#TS\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 11: + // Segment Not Present #NP + printf("#NP\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 12: + // Stack Fault Exception #SS + printf("#SS\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 13: + // General Protection Exception #GP + printf("#GP\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 14: + // Page Fault Exception #PF + printf("#PF\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 16: + // x87 FPU Floating-point Error #MF + printf("#MF\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 17: + // Alignment Check Exception #AC + printf("#AC\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 18: + // Machine-Check Exception #MC + printf("#MC\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 19: + // SIMD Floating-point Exception #XM + printf("#XM\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 20: + // Virtualization Exception #VE + printf("#VE\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + case 21: + // Control Protection Exception #CP + printf("#CP\n"); + printf("EIP: 0x%x\n", regs.eip); + printf("EAX: 0x%x\n", regs.eax); + printf("EBP: 0x%x\n", regs.ebp); + break; + + default: + // PANIC!!! + break; + } + + + } - - void irq_handler (registers regs) { From 97606dbf7187933a9602de4ea7c20fcb547e9721 Mon Sep 17 00:00:00 2001 From: Nigel Date: Wed, 29 Dec 2021 16:15:18 +0100 Subject: [PATCH 4/6] 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 Date: Wed, 29 Dec 2021 16:28:55 +0100 Subject: [PATCH 5/6] Started definition file for a CMOS driver --- src/kernel/drivers/cmos/cmos.cpp | 38 ++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/kernel/drivers/cmos/cmos.cpp diff --git a/src/kernel/drivers/cmos/cmos.cpp b/src/kernel/drivers/cmos/cmos.cpp new file mode 100644 index 0000000..17b3ae6 --- /dev/null +++ b/src/kernel/drivers/cmos/cmos.cpp @@ -0,0 +1,38 @@ +void ReadFromCMOS(unsigned char array[]) +{ + unsigned char tvalue, index; + + for (index = 0; index < 128; index++) + { + asm( + "cli\n\t" // Disable interrupts + "mov al, index\n\t" // Move index address + // since the 0x80 bit of al is not set, NMI is active + "out 0x70,al\n\t" // Copy address to CMOS register + // some kind of real delay here is probably best + "in al,0x71\n\t" // Fetch 1 byte to al + "sti\n\t" // Enable interrupts + "mov tvalue,al\n\t"); + + array[index] = tvalue; + } +} + +void WriteTOCMOS(unsigned char array[]) +{ + unsigned char index; + + for(index = 0; index < 128; index++) + { + unsigned char tvalue = array[index]; + + asm("cli\n\t" // Clear interrupts + "mov al,index\n\t" // move index address + "out 0x70,al\n\t" // copy address to CMOS register + // some kind of real delay here is probably best + "mov al,tvalue\n\t" // move value to al + "out 0x71,al\n\t" // write 1 byte to CMOS + "sti\n\\t" ); // Enable interrupts + + } +} \ No newline at end of file From b4cff3e667be4818a835f1cae28f0b9c65d251ac Mon Sep 17 00:00:00 2001 From: Nigel Date: Sat, 26 Feb 2022 20:44:16 +0100 Subject: [PATCH 6/6] Basic block allocation for physical memory allocation. - 1 block = 4096 bytes : because this will make page fault handling possibly somewhat easier - 1 byte in the bitmap = 8 blocks of physical memory unsure if the allocation is perfect ... guess i'll find out some day if this is actually correct. The bitmap needs 16kb to keep track of 2gb of physical memory. Seems a decent percentage to me. --- Makefile | 11 +- README.md | 3 +- features.md | 37 ++-- src/grub.cfg | 7 +- src/kernel/{boot.S => boot.s} | 0 src/kernel/bootinfo.h | 9 + src/kernel/definitions.h | 11 + src/kernel/kernel.cpp | 205 ++++++++++-------- src/kernel/kernel.h | 12 +- src/kernel/kstructures/bitmap.h | 28 +-- src/kernel/memory/PageDirectory.cpp | 58 +++-- src/kernel/memory/PageDirectory.h | 21 +- src/kernel/memory/PageFrameAllocator.cpp | 38 ---- src/kernel/memory/PageFrameAllocator.h | 20 -- src/kernel/memory/PhysicalMemoryManager.cpp | 118 ---------- src/kernel/memory/PhysicalMemoryManager.h | 34 --- src/kernel/memory/SlabAllocator.h | 33 --- src/kernel/memory/memory.cpp | 142 ++++++++++++ src/kernel/memory/memory.h | 48 ++++ src/kernel/memory/memoryinfo.h | 20 ++ src/kernel/sv-terminal/superVisorTerminal.cpp | 13 +- src/kernel/sv-terminal/superVisorTerminal.h | 5 +- src/libc/include/mem.h | 4 +- todo.md | 21 ++ 24 files changed, 472 insertions(+), 426 deletions(-) rename src/kernel/{boot.S => boot.s} (100%) create mode 100644 src/kernel/bootinfo.h create mode 100644 src/kernel/definitions.h delete mode 100644 src/kernel/memory/PageFrameAllocator.cpp delete mode 100644 src/kernel/memory/PageFrameAllocator.h delete mode 100644 src/kernel/memory/PhysicalMemoryManager.cpp delete mode 100644 src/kernel/memory/PhysicalMemoryManager.h delete mode 100644 src/kernel/memory/SlabAllocator.h create mode 100644 src/kernel/memory/memory.cpp create mode 100644 src/kernel/memory/memory.h create mode 100644 src/kernel/memory/memoryinfo.h diff --git a/Makefile b/Makefile index afdeb22..c1b4aa0 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)/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 +OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/pit.o $(BUILD_DIR)/time.o $(BUILD_DIR)/keyboard.o $(BUILD_DIR)/io.o $(BUILD_DIR)/gdtc.o $(BUILD_DIR)/idt.o $(BUILD_DIR)/pic.o $(BUILD_DIR)/sv-terminal.o $(BUILD_DIR)/string.o SRC_DIR = src BUILD_DIR = build @@ -54,7 +54,7 @@ $(BUILD_DIR)/kterm.o: $(CPP) -c $(SRC_DIR)/kernel/tty/kterm.cpp -o $(BUILD_DIR)/kterm.o $(CFLAGS) -fno-exceptions -fno-rtti $(BUILD_DIR)/boot.o: - $(AS) $(SRC_DIR)/kernel//boot.S -o $(BUILD_DIR)/boot.o + $(AS) $(SRC_DIR)/kernel/boot.s -o $(BUILD_DIR)/boot.o $(BUILD_DIR)/crti.o: $(AS) $(SRC_DIR)/kernel/crti.s -o $(BUILD_DIR)/crti.o @@ -65,8 +65,6 @@ $(BUILD_DIR)/crtn.o: $(BUILD_DIR)/io.o: $(CPP) -c $(SRC_DIR)/kernel/io.cpp -o $(BUILD_DIR)/io.o $(CFLAGS) -fno-exceptions -fno-rtti -$(BUILD_DIR)/PageDirectory.o: - $(CPP) -c $(SRC_DIR)/kernel/memory/PageDirectory.cpp -o $(BUILD_DIR)/PageDirectory.o $(CFLAGS) -fno-exceptions -fno-rtti $(BUILD_DIR)/idt.o: $(CPP) -c $(SRC_DIR)/kernel/idt/idt.cpp -o $(BUILD_DIR)/idt.o $(CFLAGS) -fno-exceptions -fno-rtti @@ -81,8 +79,6 @@ $(BUILD_DIR)/pic.o: $(BUILD_DIR)/string.o: $(CC) -c $(SRC_DIR)/libc/include/string.c -o $(BUILD_DIR)/string.o $(CFLAGS) -std=gnu99 -$(BUILD_DIR)/PhysicalMemoryManager.o: - $(CPP) -c $(SRC_DIR)/kernel/memory/PhysicalMemoryManager.cpp -o $(BUILD_DIR)/PhysicalMemoryManager.o $(CFLAGS) -fno-exceptions -fno-rtti $(BUILD_DIR)/pit.o: $(CPP) -c $(SRC_DIR)/kernel/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti @@ -97,3 +93,6 @@ $(BUILD_DIR)/time.o: $(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 + +$(BUILD_DIR)/memory.o: + $(CPP) -c $(SRC_DIR)/kernel/memory/memory.cpp -o $(BUILD_DIR)/memory.o $(CFLAGS) -fno-exceptions -fno-rtti diff --git a/README.md b/README.md index ee97592..2e5fbb6 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,8 @@ Multiboot information can be read by the kernel. ________________________ ### The goal -Writing a hobby operating system to better understand the basic building blocks of any operating system. +Writing a hobby operating system to better understand the basic building blocks of any operating system.Initially I'd like for my +operating system to be able to run bash. ________________________ ### Operating System Technical specs/details diff --git a/features.md b/features.md index 53b1cf0..b704af2 100644 --- a/features.md +++ b/features.md @@ -1,29 +1,30 @@ # TODO list -## Start planning +## Basics Setup Cross-Compiler \ Multiboot to kernel \ Printing string to the screen \ - Printing values/numbers to the screen (a.k.k itoa) \ + Printing values/numbers to the screen \ + Basic Terminal \ Extend Multiboot implementation \ Output to serial port \ Move to protected mode \ Enabel CMOS clock \ - Time measurement (PIC &| PIT) \ + Time measurement (PIC &| PIT) \ Detect CPU speed \ Interrupt / exception system (API) \ - - Plan your memory map (virtual, and physical) : decide where you want the data to be. \ + PCI support \ + ATA PIO Mode support \ + FAT Filesystem \ + Virtual filesystem \ + Keyboard support ( P/S2 Keyboard) \ + Physical memory management \ + Paging \ + Virtual memory management \ The heap: allocating memory at runtime (malloc and free) is almost impossible to go without. \ Enable SIMD Extensions (SSE) -## Other features I am thinking of: - PCI support \ - ATA PIO Mode support \ - USTAR Filesystem ( For its simplicity this is very likely the first filesystem the OS is going to support) \ - ACPI support ( Or some other basic way to support shutdown, reboot and possibly hibernation ) \ - ATAPI support \ - Keyboard support ( P/S2 Keyboard) \ - Memory Management (MMU) + Hardware Management system + Preemptive multi tasking \ Processes \ Threads @@ -32,9 +33,11 @@ POSIX compliance (partially) \ RPC - for interprocess communication \ Sync primitives - Semaphores, Mutexes, spinlocks et al. \ - Basic Terminal \ - Extend hardware recognition ( CPU codename, memory, ATA harddisk, RAW diskSpace, CPU speed through SMBIOS et al. ) \ + + ACPI support \ + ATAPI support \ + +## Optional Basic Window server/client \ -## Support for more filesystems if I like the challenge in writing these ... - FAT Filesystem \ EXT2 Filesystem + USTAR Filesystem \ diff --git a/src/grub.cfg b/src/grub.cfg index 40431b9..27391d2 100644 --- a/src/grub.cfg +++ b/src/grub.cfg @@ -1,3 +1,8 @@ -menuentry "BarinkOS"{ +GRUB_DEFAULT=0 +GRUB_TIMEOUT=-1 +GRUB_HIDDEN_TIMEOUT=0 +GRUB_HIDDEN_TIMEOUT_QUITE=true + +menuentry "BarinkOS" { multiboot /boot/myos.bin } diff --git a/src/kernel/boot.S b/src/kernel/boot.s similarity index 100% rename from src/kernel/boot.S rename to src/kernel/boot.s diff --git a/src/kernel/bootinfo.h b/src/kernel/bootinfo.h new file mode 100644 index 0000000..575a048 --- /dev/null +++ b/src/kernel/bootinfo.h @@ -0,0 +1,9 @@ +#pragma once +#include "memory/memoryinfo.h" + + +struct BootInfo{ + const char* BootStructureID = "BarinkOS"; + MemoryInfo* memory; + +}; \ No newline at end of file diff --git a/src/kernel/definitions.h b/src/kernel/definitions.h new file mode 100644 index 0000000..1f99d57 --- /dev/null +++ b/src/kernel/definitions.h @@ -0,0 +1,11 @@ +#pragma once +/** + * Kernel definitions + */ + + + +#define __DEBUG__ false +#define KERNEL_VERSION 0 + +#define ARCHITECTURE "I386" diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index 04c2ff1..9e78828 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -1,108 +1,123 @@ #include "kernel.h" -#define GB2 262144 - extern "C" void kernel_main (void); - - extern "C" void early_main(unsigned long magic, unsigned long addr){ - /** - * Initialize terminal interface - * NOTE: This should be done later on , the magic value should be checked first. - */ - kterm_init(); - - /** - * 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; - } +extern "C" void kernel_main (BootInfo* bootinfo) { + init_serial(); + pit_initialise(); - /** - * Show a little banner for cuteness - */ - printf("|=== BarinkOS ===|\n"); + startSuperVisorTerminal(bootinfo); +} - /** - * 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(); - } - - initGDT(); - init_idt(); - // Enable interrupts - asm volatile("STI"); - - - CheckMBT( (multiboot_info_t *) addr); - - - kernel_main(); - +extern "C" void early_main(unsigned long magic, unsigned long addr){ + /** + * Initialize terminal interface + * NOTE: This should be done later on , the magic value should be checked first. + */ + kterm_init(); + + /** + * 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; } - extern "C" void kernel_main (void) { - init_serial(); - pit_initialise(); - - while (true){ - - printf("SUPERVISOR:>$ " ); - 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("TIME", command , characterCount ) == 0 ) { - read_rtc(); - printf( "UTC time: %02d-%02d-%02d %02d:%02d:%02d (Ticks: %06d)\n" ,year, month, day, hour, minute, second, pit_tick); - } else if(strncmp("TEST", command, characterCount) == 0){ - // asm volatile ("MOV $4, %AX ; MOV $0, %BX ; DIV %BX"); // IRS 0 - } - else{ - printf("Unknown command\n"); - } + /** + * Show a little banner for cuteness + */ + printf("|=== BarinkOS ===|\n"); - delay(1000); - } - + /** + * Use the address given as an argument as the pointer + * to a Multiboot information structure. + */ + multiboot_info_t* mbt = (multiboot_info_t*) addr; + /** + * Construct our own bootInfo structure + */ + BootInfo bootinfo = {}; + + /* + 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)) + { - } + /* + Setup Physical memory managment + */ + MemoryInfo meminfo = {}; + bootinfo.memory = &meminfo; + + mapMultibootMemoryMap(bootinfo.memory , mbt); + printf("Memory size: 0x%x bytes\n", bootinfo.memory->TotalMemory ); + + PhysicalMemory memAlloc = PhysicalMemory{}; + memAlloc.setup(bootinfo.memory ); + + /* + Mark already in use sections + */ + + // Mark kernel memory as used + printf("Kernel Begin Pointer: 0x%x, Kernel end pointer: 0x%x\n", kernel_begin , kernel_end ); + + multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr; + + for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){ + + if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){ + + } else{ + printf("allocate region: 0x%x, size : 0x%x bytes\n", (unsigned) mmap->addr,(unsigned) mmap->len ); + memAlloc.allocate_region((unsigned)mmap->addr , (unsigned)mmap->len); + } + + + } + + + printf("allocate region: 0x%x, size : 0x%x bytes\n", kernel_begin, kernel_end - kernel_begin ); + memAlloc.allocate_region(kernel_end, kernel_end - kernel_begin); + + // test alloc_block + + + uint8_t* memory = (uint8_t*) memAlloc.allocate_block(); + printf("Got a new pointer: 0x%x\n", memory); + + uint8_t* memory2 = (uint8_t*) memAlloc.allocate_block(); + printf("Got a new pointer: 0x%x\n", memory2); + + + memAlloc.free_block((void*) memory); + + uint8_t* newBlockPlse = (uint8_t*) memAlloc.allocate_block(); + + + + + // memAlloc.free_block((void*) memory); + + + } + + initGDT(); + init_idt(); + // Enable interrupts + asm volatile("STI"); + + + CheckMBT( (multiboot_info_t *) addr); + + + kernel_main(&bootinfo); + +} diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 63570b5..604c4ff 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -1,14 +1,20 @@ #pragma once -extern "C"{ +extern "C" +{ #include "../libc/include/string.h" } + +#include "definitions.h" + #include "vga/VBE.h" #include "tty/kterm.h" #include "./bootloader/multiboot.h" +#include "bootinfo.h" + +#include "memory/memory.h" +#include "memory/memoryinfo.h" #include "bootcheck.h" -#include "memory/physical/PhysicalMemoryManager.h" -#include "memory/frames/PageFrameAllocator.h" #include "gdt/gdtc.h" #include "idt/idt.h" diff --git a/src/kernel/kstructures/bitmap.h b/src/kernel/kstructures/bitmap.h index e4487fe..165266c 100644 --- a/src/kernel/kstructures/bitmap.h +++ b/src/kernel/kstructures/bitmap.h @@ -13,26 +13,26 @@ inline void bitmap_unset(uint32_t* map , int index) map[index/32] &= ~(1 << (index % 32)); } -inline int bitmap_first_unset( uint32_t* map , int size) +inline uint32_t bitmap_first_unset( uint32_t* map , int map_size) { - uint32_t rem_bits = size % 32; - for(uint32_t i = 0; i < size/32; i++) + for ( int i = 0 ; i < map_size ; i ++ ) { - if(map[i] != 0xFFFFFFFF){ - for(int j = 0; j < 32; j++){ - if(!(map[i] & (1<< j))){ - return (i*32) + j; + // a bit or more is set within this byte! + if( (map[i] & 0xFFFFFFFF) > 0 ){ + + // which bit is set? + for(int j = 0 ; j < 32 ; j++){ + if ( (map[i] & (0x00000001 << j)) > 0) + { + printf("Found bit: byte 0x%x , bit 0x%x\n", i , j); + return (i*32)+j; } } - } - } - if(rem_bits){ - for(uint32_t j = 0; j < rem_bits; j++){ - if(!(map[size/32] & (1 << j ))){ - return size + j; // Original author divided size by 32 and then multiplied it by 32 which is a net zero calculation ?!? - } + } + + } return -1; diff --git a/src/kernel/memory/PageDirectory.cpp b/src/kernel/memory/PageDirectory.cpp index f740680..5e4ab31 100644 --- a/src/kernel/memory/PageDirectory.cpp +++ b/src/kernel/memory/PageDirectory.cpp @@ -1,47 +1,43 @@ #include "PageDirectory.h" -#include + +void PageDirectory::enable() +{ - -void PageDirectory::enable(){ // https://wiki.osdev.org/Setting_Up_Paging //set each entry to not present - int i; - for(i = 0; i < 1024; i++) - { - // This sets the following flags to the pages: - // Supervisor: Only kernel-mode can access them - // Write Enabled: It can be both read from and written to - // Not Present: The page table is not present - this->page_directory[i] = 0x00000002; - } + // int i; + // for(i = 0; i < 1024; i++) + // { + // // This sets the following flags to the pages: + // // Supervisor: Only kernel-mode can access them + // // Write Enabled: It can be both read from and written to + // // Not Present: The page table is not present + // this->page_directory[i] = 0x00000002; + // } - // holds the physical address where we want to start mapping these pages to. - // in this case, we want to map these pages to the very beginning of memory. + // // holds the physical address where we want to start mapping these pages to. + // // in this case, we want to map these pages to the very beginning of memory. - //we will fill all 1024 entries in the table, mapping 4 megabytes - for(unsigned int i = 0; i < 1024; i++) - { - // As the address is page aligned, it will always leave 12 bits zeroed. - // Those bits are used by the attributes ;) - first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present. - } + // //we will fill all 1024 entries in the table, mapping 4 megabytes + // for(unsigned int i = 0; i < 1024; i++) + // { + // // As the address is page aligned, it will always leave 12 bits zeroed. + // // Those bits are used by the attributes ;) + // first_page_table[i] = (i * 0x1000) | 3; // attributes: supervisor level, read/write, present. + // } - // attributes: supervisor level, read/write, present - this->page_directory[0] = ((unsigned int)first_page_table) | 3; + // // attributes: supervisor level, read/write, present + // this->page_directory[0] = ((unsigned int)first_page_table) | 3; + printf("Enable Paging!\n"); loadPageDirectory(this->page_directory); enablePaging(); } -/* -void IdentityPaging(uint32_t *first_pte, vaddr from, int size) + +void PageDirectory::MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t size ) { - from = from & 0xFFFFF000; // Discard the bits we don't want - for (; size > 0; from += 4096, first_pte++) - { - *first_pte = from | 1; // makr page present. - } + } -*/ diff --git a/src/kernel/memory/PageDirectory.h b/src/kernel/memory/PageDirectory.h index a2863d3..c43c8fa 100644 --- a/src/kernel/memory/PageDirectory.h +++ b/src/kernel/memory/PageDirectory.h @@ -1,17 +1,18 @@ #pragma once #include - -extern "C" void loadPageDirectory (uint32_t* addr ); -extern "C" void enablePaging(); -typedef uintptr_t address_t; - - +#include "./memory.h" +#include "./../tty/kterm.h" #define KB 1024 + +typedef uintptr_t address_t; + static const int MAX_PAGES = 1024 * KB; // 4GB , 4kB/page static volatile address_t pmem_stack[MAX_PAGES]; static volatile address_t pmem_stack_top = MAX_PAGES; // top down allocation +extern "C" void loadPageDirectory (uint32_t* addr ); +extern "C" void enablePaging(); struct page_directory_entry {}; struct page_table_entry{}; @@ -21,8 +22,10 @@ struct page_table_entry{}; class PageDirectory { public: void enable (); - + void MapPhysicalToVirtualAddress ( address_t PAddress , address_t VAddress, uint32_t size ); + private: - uint32_t page_directory[1024] __attribute__((aligned(4096))); - uint32_t first_page_table[1024] __attribute__((aligned(4096))); + uint32_t page_directory[1024] __attribute__((aligned(4096))); // align on 4 kiloByte pages + uint32_t first_page_table[1024] __attribute__((aligned(4096))); // align on 4 kiloByte pages + }; \ No newline at end of file diff --git a/src/kernel/memory/PageFrameAllocator.cpp b/src/kernel/memory/PageFrameAllocator.cpp deleted file mode 100644 index f34c282..0000000 --- a/src/kernel/memory/PageFrameAllocator.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "PageFrameAllocator.h" - - -MemoryInfo memInfo {}; -void mapMultibootMemoryMap( multiboot_info_t *mbt){ - printf("mmap_addr = 0x%x, mmap_length = 0x%x\n", - (unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length); - multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr; - - for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){ - - if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){ - memInfo.memorySizeInBytes += mmap->len; - } else { - memInfo.reservedMemoryInBytes += mmap->len; - } - - print_Multiboot_memory_Map(mmap); - - } - uint32_t memorySizeInGiB = memInfo.memorySizeInBytes / 1073741824; - - printf("Available Memory: 0x%x bytes, 0x%x GiB\n", memInfo.memorySizeInBytes, memorySizeInGiB ); - printf("Reserved Memory: 0x%x bytes\n", memInfo.reservedMemoryInBytes ); - -} - -void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap){ - printf( - "size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n", - (unsigned) mmap->size, - (unsigned) (mmap->addr >> 32), - (unsigned) (mmap->addr & 0xffffffff), - (unsigned) (mmap->len >> 32), - (unsigned) (mmap->len & 0xffffffff), - (unsigned) mmap->type - ); -} \ No newline at end of file diff --git a/src/kernel/memory/PageFrameAllocator.h b/src/kernel/memory/PageFrameAllocator.h deleted file mode 100644 index 2b19180..0000000 --- a/src/kernel/memory/PageFrameAllocator.h +++ /dev/null @@ -1,20 +0,0 @@ -#pragma once -#include "../arch/i386/tty/kterm.h" - -#include -#include "../bootloader/multiboot.h" - -struct MemoryInfo{ - uint32_t memorySizeInBytes = 0; - uint32_t reservedMemoryInBytes = 0; -}; - - -extern void *kernel_begin; -extern void *kernel_end; - - - - -void print_Multiboot_memory_Map(multiboot_memory_map_t*); -void mapMultibootMemoryMap(multiboot_info_t*); \ No newline at end of file diff --git a/src/kernel/memory/PhysicalMemoryManager.cpp b/src/kernel/memory/PhysicalMemoryManager.cpp deleted file mode 100644 index 8e894ba..0000000 --- a/src/kernel/memory/PhysicalMemoryManager.cpp +++ /dev/null @@ -1,118 +0,0 @@ -#include "PhysicalMemoryManager.h" - -size_t mem_size = 0; -int used_blocks = 0; -size_t max_blocks = 0; -uint32_t* pmmap = 0; -size_t pmmap_size = 0; - - -void PhysicalMemoryManager_initialise(uint32_t physicalmemorymap_address, size_t size ) -{ - mem_size = size; - max_blocks = KB_TO_BLOCKS(mem_size); - - used_blocks = max_blocks; - - pmmap = (uint32_t*) physicalmemorymap_address; - - if(max_blocks % BLOCKS_PER_WORD) - pmmap_size++; - - memset(pmmap, 0xFF, pmmap_size); -} - -void PhysicalMemoryManager_region_initialise(uint32_t base, size_t size) -{ - size_t blocks = size /BLOCK_SIZE; - uint32_t align = base / BLOCK_SIZE; - - for(size_t i = 0 ; i < blocks; i ++) - { - bitmap_unset(pmmap, align++); - used_blocks--; - } - - bitmap_set(pmmap, 0); - -} - -void PhysicalMemoryManager_region_deinitialise(uint32_t base, size_t size ) -{ - size_t blocks = size / BLOCK_SIZE; - uint32_t align = base / BLOCK_SIZE; - - for(size_t i = 0 ; i < blocks; i++ ) - { - bitmap_set(pmmap, align++); - used_blocks++; - } - - -} - -void PhysicalMemoryManager_initialise_available_regions(uint32_t mmap_, uint32_t mmap_end_) -{ - multiboot_memory_map_t *mmap = (multiboot_memory_map_t*)mmap_; - multiboot_memory_map_t *mmap_end= (multiboot_memory_map_t*) mmap_end_; - - for(int i = 0; mmap < mmap_end ; mmap++, i++) - { - if(mmap->type == MULTIBOOT_MEMORY_AVAILABLE) - { - PhysicalMemoryManager_region_initialise((uint32_t) mmap->addr, (size_t) mmap->len); - } - } - -} - -void PhysicalMemoryManager_deinitialise_kernel() -{ - extern uint8_t kernel_begin; - extern uint8_t kernel_end; - - size_t kernel_size = (size_t) &kernel_end - (size_t) &kernel_begin; - - uint32_t pmmap_size_aligned = pmmap_size; - if(!IS_ALIGNED(pmmap_size_aligned, BLOCK_SIZE)) - { - pmmap_size_aligned = ALIGN(pmmap_size_aligned, BLOCK_SIZE); - } - - PhysicalMemoryManager_region_deinitialise((uint32_t) &kernel_begin, kernel_size); - PhysicalMemoryManager_region_deinitialise((uint32_t) &kernel_end, pmmap_size_aligned); - -} - -void* PhysicalMemoryManager_allocate_block() -{ - if(used_blocks - max_blocks <= 0) - { - return 0; - } - - int p_index = bitmap_first_unset(pmmap, p_index ); - - if(p_index == -1){ - return 0; - } - - bitmap_set(pmmap, p_index); - used_blocks++; - - return (void*) (BLOCK_SIZE * p_index); -} - -void PhysicalMemoryManager_free_block(void* p){ - if(p==0){ - return ; - } - - uint32_t p_addr = (uint32_t) p; - - int index = p_addr / BLOCK_SIZE; - bitmap_unset(pmmap, index); - - used_blocks--; - -} \ No newline at end of file diff --git a/src/kernel/memory/PhysicalMemoryManager.h b/src/kernel/memory/PhysicalMemoryManager.h deleted file mode 100644 index 3adc1eb..0000000 --- a/src/kernel/memory/PhysicalMemoryManager.h +++ /dev/null @@ -1,34 +0,0 @@ -#pragma once - -#include "../bootloader/multiboot.h" -#include -#include -#include "../../libc/include/mem.h" -#include "../kstructures/bitmap.h" - - -#define BLOCK_SIZE 4092 -#define BLOCKS_PER_WORD 32 - -#define KB_TO_BLOCKS(x) (((x) * 1024 ) / BLOCK_SIZE) -#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1)) -#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align)) - - -extern void PhysicalMemoryManager_initialise(uint32_t, size_t); - -extern void PhysicalMemoryManager_region_initialise(uint32_t, size_t); -extern void PhysicalMemoryManager_region_deinitialise(uint32_t,size_t); - -extern void PhysicalMemoryManager_initialise_available_regions(uint32_t, uint32_t); -extern void PhysicalMemoryManager_deinitialise_kernel(); - -extern void* PhysicalMemoryManager_allocate_block(); -extern void PhysicalMemoryManager_free_block(void* p); - - -extern size_t mem_size; -extern int used_blocks; -extern size_t max_blocks; -extern uint32_t* pmmap; -extern size_t pmmap_size ; \ No newline at end of file diff --git a/src/kernel/memory/SlabAllocator.h b/src/kernel/memory/SlabAllocator.h deleted file mode 100644 index b9f00df..0000000 --- a/src/kernel/memory/SlabAllocator.h +++ /dev/null @@ -1,33 +0,0 @@ -#pragma once -/** - * We'll need something to this effect to allocate memory in the kernel - * this will hopefully someday implement a full slab allocator - **/ -enum SlabState { - empty, - partial, - full -}; - -class CacheSlab { - const int SlabSize = 4000; - void* start = 0x0; -}; - - -class Allocator { - - public: - Allocator(); - ~Allocator(); - - void* kmalloc( int size ); - void kfree (void* address); - - private: - CacheSlab** _cache; - - - - -}; \ No newline at end of file diff --git a/src/kernel/memory/memory.cpp b/src/kernel/memory/memory.cpp new file mode 100644 index 0000000..b72e786 --- /dev/null +++ b/src/kernel/memory/memory.cpp @@ -0,0 +1,142 @@ +#include "./memory.h" +uint32_t* memoryBitMap; +/* + +*/ +void PhysicalMemory::setup( MemoryInfo* memory) { + + // calculate the maximum number of blocks + max_blocks = KB_TO_BLOCKS(memory->TotalMemory); + + used_blocks = 0; + + memoryBitMap = (uint32_t*) 0x00a00000; + + + printf("Maximum Number of blocks: 0x%x, Number of bytes for memMap: 0x%x\n", max_blocks , (max_blocks/8)); + + //Size of memory map + uint32_t memMap_size = (max_blocks / 8 ) ; + + printf("Memory Map size: 0x%x\n", memMap_size ); + printf("size of int in bytes: 0x%x \n" , sizeof(int)); + + // Set all places in memory as free + memset(memoryBitMap, 0xFF, memMap_size ); +} + +// NOTE: this can only give blocks of 4kb at a time! +void* PhysicalMemory::allocate_block() { + uint8_t blocks_available = max_blocks - used_blocks; + // Are there any blocks available? + if( blocks_available <= 0) + { + printf("No blocks available. Blocks Delta: 0x%x\n", blocks_available); + return 0; + } + + // Find 1 free block somewhere + int free_block_index = bitmap_first_unset(memoryBitMap, (max_blocks /8) /*memMap Size*/ ); + + + + if(free_block_index == -1) + { + printf("Could not find a good block!\n"); + // Could not find a block + return (void*)0xFFFF; + } + + if(free_block_index == 0) + printf("Somethings wrong!!!\n"); + + // Set the block to be used! + bitmap_unset(memoryBitMap, free_block_index); + // Increase the used_block count! + used_blocks++; + printf("used blocks: 0x%x\n", used_blocks); + // return the pointer to the physical address + return (void*) (BLOCK_SIZE * free_block_index); +} + + +void PhysicalMemory::free_block(void* p) { + // If it is a null pointer we don't need to do anything. + if(p==0) { + return; + } + // calculate the index into the bitmap + int index = ((uint32_t) p) / BLOCK_SIZE; + + // set the block to be free + bitmap_set(memoryBitMap, index); + used_blocks--; + printf("used blocks: 0x%x, after free\n", used_blocks); + +} + + + +void PhysicalMemory::allocate_region(uint32_t startAddress, uint32_t size) { + // every bit should be 4KiB + // every byte is 8*4KiB = 32KiB + + int NumberOfBlocksToAllocate = ( size / 1024) / 4 / 8 + 1; + int startBlock = (startAddress / 1024) / 4 / 8 ; + + // printf("NumberOfBlocksToAllocate: 0x%x\n", NumberOfBlocksToAllocate); + //printf( "start block: 0x%x\n" , startBlock); + for( int i = 0; i < NumberOfBlocksToAllocate; i++) + { + + //printf("ALLOCATE BLOCK: 0x%x\n" , startBlock + i ); + bitmap_unset(memoryBitMap, startBlock+ i); + used_blocks++; + } + + +} +void PhysicalMemory::deallocate_region(uint32_t StartAddress , uint32_t size ) { + // NOT IMPLEMENTED YET +} + + +void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt) { + printf("mmap_addr = 0x%x, mmap_length = 0x%x\n", + (unsigned) mbt->mmap_addr, (unsigned) mbt->mmap_length); + multiboot_memory_map_t *mmap = (multiboot_memory_map_t*) mbt->mmap_addr; + + for (; (unsigned long) mmap < mbt->mmap_addr + mbt->mmap_length; mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + mmap->size + sizeof(mmap->size))){ + + if ( mmap->type == MULTIBOOT_MEMORY_AVAILABLE){ + + memInfo->TotalMemory += mmap->len; + } else { + memInfo->ReservedMemory += mmap->len; + } + + print_Multiboot_memory_Map(mmap); + + } + +} + + +/** + * @brief Debug Verbose functions + * + * @param mmap + */ + +void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap) { + printf( + "size = 0x%x, base_addr = 0x%x%08x, length = 0x%x%08x, type = 0x%x\n", + (unsigned) mmap->size, + (unsigned) (mmap->addr >> 32), + (unsigned) (mmap->addr & 0xffffffff), + (unsigned) (mmap->len >> 32), + (unsigned) (mmap->len & 0xffffffff), + (unsigned) mmap->type + ); +} + diff --git a/src/kernel/memory/memory.h b/src/kernel/memory/memory.h new file mode 100644 index 0000000..2d0d309 --- /dev/null +++ b/src/kernel/memory/memory.h @@ -0,0 +1,48 @@ +#pragma once +#include +#include + +#include "memoryinfo.h" +#include "../bootloader/multiboot.h" +#include "../tty/kterm.h" +#include "../../libc/include/mem.h" +#include "../kstructures/bitmap.h" + +#define BLOCK_SIZE 4092 +#define BLOCKS_PER_WORD 32 // A word is 16 bit in x86 machines according to my google search results! + +#define KB_TO_BLOCKS(x) (x / BLOCK_SIZE) +#define IS_ALIGNED(addr, align) !((addr) & ~((align) - 1)) +#define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align)) + +extern uint32_t kernel_begin; +extern uint32_t kernel_end; + +void initialise_available_regions(uint32_t memoryMapAddr, uint32_t memoryMapLastAddr, uint32_t* memoryBitMap, int* used_blocks); + +extern uint32_t* memoryBitMap; + +class PhysicalMemory +{ + public: + void setup(MemoryInfo* memory); + void destroy(); + void free_block(void* ptr); + void* allocate_block(); + void allocate_region(uint32_t, uint32_t); + void deallocate_region(uint32_t , uint32_t ); + + private: + size_t pmmap_size; + size_t max_blocks; + int used_blocks; +}; + +void mapMultibootMemoryMap( MemoryInfo* memInfo , multiboot_info_t *mbt); + +/** + * @brief Debug Verbose Functions + * + * @param mmap + */ +void print_Multiboot_memory_Map(multiboot_memory_map_t* mmap); diff --git a/src/kernel/memory/memoryinfo.h b/src/kernel/memory/memoryinfo.h new file mode 100644 index 0000000..9bbb626 --- /dev/null +++ b/src/kernel/memory/memoryinfo.h @@ -0,0 +1,20 @@ +#pragma once +#include +#include + +struct MemoryArea{ + void* StartAddress; + size_t Size; + unsigned int type; + MemoryArea* Next; + +}__attribute__((packed)); + +struct MemoryInfo { + uint32_t TotalMemory; + uint32_t ReservedMemory; + MemoryArea* MemoryRegionList; +}__attribute__((packed)); + + + diff --git a/src/kernel/sv-terminal/superVisorTerminal.cpp b/src/kernel/sv-terminal/superVisorTerminal.cpp index 436fad2..b568208 100644 --- a/src/kernel/sv-terminal/superVisorTerminal.cpp +++ b/src/kernel/sv-terminal/superVisorTerminal.cpp @@ -1,6 +1,6 @@ #include "superVisorTerminal.h" -void startSuperVisorTerminal(){ +void startSuperVisorTerminal(BootInfo* bootinfo){ while (true){ printf("SUPERVISOR:>$ " ); @@ -40,7 +40,16 @@ void startSuperVisorTerminal(){ 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("Frames used: 0x%x blocks of 4 KiB\n", 0); + const int bytesInGiB = 1073741824; + int64_t bytesLeft = (bootinfo->memory->TotalMemory % bytesInGiB) / bytesInGiB; + int64_t effectiveNumberOfGib = bootinfo->memory->TotalMemory / bytesInGiB; + + int64_t GiBs = effectiveNumberOfGib + bytesLeft; + + printf("Available Memory: %d bytes, %d GiB\n", bootinfo->memory->TotalMemory, GiBs ); + printf("Reserved Memory: %d bytes\n", bootinfo->memory->ReservedMemory); + //printf("\n\n"); //PrintPhysicalMemoryAllocation( ); diff --git a/src/kernel/sv-terminal/superVisorTerminal.h b/src/kernel/sv-terminal/superVisorTerminal.h index 8f83a15..5d4519d 100644 --- a/src/kernel/sv-terminal/superVisorTerminal.h +++ b/src/kernel/sv-terminal/superVisorTerminal.h @@ -3,6 +3,7 @@ #include "../time.h" #include "../pit.h" #include "../keyboard/keyboard.h" -#include "../memory/physical/PhysicalMemoryManager.h" +#include "../memory/memory.h" +#include "../bootinfo.h" -void startSuperVisorTerminal(); \ No newline at end of file +void startSuperVisorTerminal(BootInfo * ); \ No newline at end of file diff --git a/src/libc/include/mem.h b/src/libc/include/mem.h index 62c4318..75e7cf8 100644 --- a/src/libc/include/mem.h +++ b/src/libc/include/mem.h @@ -1,8 +1,8 @@ inline void* memset (void* ptr, int value, size_t num){ for( int i = 0; i < num; i++ ) { - int* data = (int*)ptr+ i; - *data = value; + unsigned char* data = (unsigned char*)ptr+ i; + *data = (unsigned char)value; } return ptr; } diff --git a/todo.md b/todo.md index e69de29..d927cb1 100644 --- a/todo.md +++ b/todo.md @@ -0,0 +1,21 @@ +# TODO list + +![Todo image](https://camo.githubusercontent.com/c43d969d9d071c8342e9a69cdd6acb433c541f431127738974ce22290c46f2b8/68747470733a2f2f692e696d6775722e636f6d2f4f764d5a4273392e6a7067) + + +This list keeps me focused and organised so I don't forget what +needs to be done. It is a expansion on the features markdown file which describes the features. Here I put things I need to remember +to do on a more in depth level. + +## -- +[ ] Setup paging \ +[ ] HELP command +[ ] Setup a proper HEAP \ +[ ] Setup a proper Stack \ +[ ] Setup KMalloc and KFree \ +[ ] Merge Functioning Feature branches into sandboxKernelDev \ +[ ] Remove merged feature branches \ +[ ] Merge sandboxKernelDev with dev \ +[ ] Remove sandboxKernelDev branch \ +[ ] Implement proper virtual filesystem +