diff --git a/Makefile b/Makefile index 173bd5c..6b85a09 100644 --- a/Makefile +++ b/Makefile @@ -9,9 +9,8 @@ OFILES = \ $(BUILD_DIR)/boot.o \ $(BUILD_DIR)/kterm.o \ $(BUILD_DIR)/kernel.o \ -$(BUILD_DIR)/PhysicalMemoryManager.o \ +$(BUILD_DIR)/memory.o \ $(BUILD_DIR)/io.o \ -$(BUILD_DIR)/PageDirectory.o \ $(BUILD_DIR)/gdtc.o \ $(BUILD_DIR)/idt.o \ $(BUILD_DIR)/pci.o \ @@ -21,6 +20,11 @@ $(BUILD_DIR)/pcidevice.o \ $(BUILD_DIR)/atapiDevice.o \ $(BUILD_DIR)/ataDevice.o \ $(BUILD_DIR)/rsdp.o \ +$(BUILD_DIR)/pit.o \ +$(BUILD_DIR)/time.o \ +$(BUILD_DIR)/keyboard.o \ +$(BUILD_DIR)/sv-terminal.o \ + SRC_DIR = src @@ -39,8 +43,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 @@ -77,7 +79,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 @@ -88,8 +90,6 @@ $(BUILD_DIR)/crtn.o: $(BUILD_DIR)/io.o: $(CPP) -c $(SRC_DIR)/kernel/drivers/IO/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 @@ -122,3 +122,20 @@ $(BUILD_DIR)/ataDevice.o: $(BUILD_DIR)/rsdp.o: $(CPP) -c $(SRC_DIR)/kernel/drivers/ACPI/rsdp.cpp -o $(BUILD_DIR)/rsdp.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 + + +$(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 + +$(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 1cd6063..6e37240 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,8 @@ Correctly identified our ATAPI device 🎉 ________________________ ### 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 155b5b5..e7db7af 100644 --- a/features.md +++ b/features.md @@ -1,18 +1,25 @@ # 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) @@ -24,6 +31,8 @@ ATAPI support \ Keyboard support ( P/S2 Keyboard) \ Memory Management (MMU) + Hardware Management system + Preemptive multi tasking \ Processes \ Threads @@ -32,9 +41,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 81% rename from src/kernel/boot.S rename to src/kernel/boot.s index ee4698e..78f5912 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/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/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/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/drivers/IO/io.cpp b/src/kernel/drivers/IO/io.cpp index 80e16d3..e3e259b 100644 --- a/src/kernel/drivers/IO/io.cpp +++ b/src/kernel/drivers/IO/io.cpp @@ -23,7 +23,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/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 diff --git a/src/kernel/gdt/gdtc.cpp b/src/kernel/gdt/gdtc.cpp index d02d0fd..c2d7ac6 100644 --- a/src/kernel/gdt/gdtc.cpp +++ b/src/kernel/gdt/gdtc.cpp @@ -29,6 +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); @@ -52,6 +55,4 @@ void initGDT(){ LoadGlobalDescriptorTable(); - - } diff --git a/src/kernel/idt/idt.cpp b/src/kernel/idt/idt.cpp index 3334a3b..393902b 100644 --- a/src/kernel/idt/idt.cpp +++ b/src/kernel/idt/idt.cpp @@ -1,5 +1,6 @@ #include "idt.h" -//#include "scancodes/set1.h" +#include "../pit.h" +#include "../keyboard/keyboard.h" IDT_entry idt_table[256]; IDT_ptr idt_ptr; @@ -13,78 +14,249 @@ 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) { - - - if ( regs.int_no != 0) { - kterm_writestring("received interrupt!\n"); - printf("(IRQ) Interrupt number: %d \n", regs.int_no); - - } - - if ( regs.int_no == 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); + + switch (regs.int_no) { + case 0: + pit_tick++; + break; + case 1: + // Keyboard interrupt !! + + int scan; + int i;/*register*/ + + // Read scancode + scan = inb(0x60); + + // Send ack message! + i = inb(0x61); + outb(0x61, i|0x80); + outb(0x61, i); + + // 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); + } - - outb(0x20, 0x20); // send end of interrupt to master + break; + case 12: + // PS2 Mouse interrupt + printf("Mouse event triggered!"); + //int event = inb(0x60); + break; - 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); + 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(){ // Initialise the IDT pointer 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 @@ -125,10 +297,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); @@ -139,7 +316,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 9e1a416..b9ab239 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -167,11 +167,6 @@ } - - - - - wait_until_shutdown(); } @@ -179,35 +174,118 @@ - extern "C" void early_main(unsigned long magic, unsigned long addr){ - /** initialize terminal interface */ - kterm_init(); + - 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? */ - if (CHECK_FLAG(mbt->flags, 6)){ - 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); - } - - initGDT(); - - - 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; } + /** + * 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"); + + + init_serial(); + pit_initialise(); + + + CheckMBT( (multiboot_info_t *) addr); + + startSuperVisorTerminal(&bootinfo); + + kernel_main(); + +} + + diff --git a/src/kernel/kernel.h b/src/kernel/kernel.h index 3dad1ef..26f6fa5 100644 --- a/src/kernel/kernel.h +++ b/src/kernel/kernel.h @@ -1,5 +1,6 @@ #pragma once -extern "C"{ +extern "C" +{ #include "../libc/include/string.h" } @@ -8,14 +9,19 @@ extern "C"{ #include "tty/kterm.h" #include "./bootloader/multiboot.h" +#include "bootinfo.h" + +#include "memory/memory.h" +#include "memory/memoryinfo.h" #include "bootcheck.h" -#include "memory/PhysicalMemoryManager.h" #include "gdt/gdtc.h" #include "idt/idt.h" #include "drivers/IO/io.h" #include "time.h" +#include "pit.h" + #include "cpu.h" #include "serial.h" #include "drivers/IO/PCI/pci.h" @@ -28,17 +34,10 @@ extern "C"{ #include "drivers/ACPI/rsdp.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 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/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/pit.cpp b/src/kernel/pit.cpp new file mode 100644 index 0000000..d2b6527 --- /dev/null +++ b/src/kernel/pit.cpp @@ -0,0 +1,54 @@ +#include "pit.h" +#include "tty/kterm.h" +uint32_t pit_tick = 0; + + +void pit_initialise() +{ + asm volatile("CLI"); + +#ifdef __VERBOSE__ + printf("Init PIT!\n"); +#endif + // 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..0bc988f --- /dev/null +++ b/src/kernel/pit.h @@ -0,0 +1,18 @@ +#pragma once +#include +#include "drivers/IO/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 edc2185..6b4cce5 100644 --- a/src/kernel/serial.h +++ b/src/kernel/serial.h @@ -3,7 +3,12 @@ #include "tty/kterm.h" #include "drivers/IO/io.h" #define PORT 0x3f8 -inline static int init_serial() { +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 diff --git a/src/kernel/sv-terminal/superVisorTerminal.cpp b/src/kernel/sv-terminal/superVisorTerminal.cpp new file mode 100644 index 0000000..3e0c8d5 --- /dev/null +++ b/src/kernel/sv-terminal/superVisorTerminal.cpp @@ -0,0 +1,89 @@ +#include "superVisorTerminal.h" + +void startSuperVisorTerminal(BootInfo* bootinfo) +{ + bool isRunning = true; + while (isRunning){ + + 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("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", 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( ); + + + } + 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 if(strncmp("FAT", command, characterCount) == 0){ + isRunning = false; + continue; + } + 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..5d4519d --- /dev/null +++ b/src/kernel/sv-terminal/superVisorTerminal.h @@ -0,0 +1,9 @@ +#pragma once +#include "../tty/kterm.h" +#include "../time.h" +#include "../pit.h" +#include "../keyboard/keyboard.h" +#include "../memory/memory.h" +#include "../bootinfo.h" + +void startSuperVisorTerminal(BootInfo * ); \ 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 str2[i] ){ + return 1; + } + + + } + + return 0; +} 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 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 +