From 520104a43a6a621507755c55208b809df926cad3 Mon Sep 17 00:00:00 2001 From: Nigel Date: Wed, 8 Feb 2023 14:07:44 +0100 Subject: [PATCH] Moved reading file from disk to its own super visor terminal command - Updated gdt assembly - Updated Interrupt service request handlers - Improved virtual memory manager - NOTE: we're dependent on identity mappings for the heap to work --- Makefile | 12 +- features.md | 2 +- source/kernel/boot/boot.s | 2 +- source/kernel/drivers/acpi/acpi.cpp | 14 + source/kernel/drivers/acpi/acpi.h | 13 + source/kernel/drivers/acpi/rsdp.h | 2 - source/kernel/drivers/ide/sampleIDE.h | 4 +- source/kernel/drivers/pci/pci.cpp | 6 +- source/kernel/drivers/pci/pci.h | 2 - source/kernel/gdt/gdt.s | 19 -- source/kernel/gdt/gdtc.cpp | 58 ---- source/kernel/gdt/gdtc.h | 27 -- source/kernel/interrupts/idt/idt.cpp | 179 +++++------ source/kernel/interrupts/idt/idt.h | 2 +- source/kernel/irs_table.s | 286 ++++-------------- source/kernel/kernel.cpp | 229 +++----------- source/kernel/kernel.h | 39 +-- source/kernel/memory/KernelHeap.cpp | 18 +- source/kernel/memory/VirtualMemoryManager.cpp | 53 +++- source/kernel/memory/VirtualMemoryManager.h | 2 +- source/kernel/memory/gdt/gdtc.cpp | 21 +- source/kernel/memory/gdt/gdtc.h | 11 +- .../supervisorterminal/superVisorTerminal.cpp | 174 ++++++++++- 23 files changed, 474 insertions(+), 701 deletions(-) create mode 100644 source/kernel/drivers/acpi/acpi.cpp create mode 100644 source/kernel/drivers/acpi/acpi.h delete mode 100644 source/kernel/gdt/gdt.s delete mode 100644 source/kernel/gdt/gdtc.cpp delete mode 100644 source/kernel/gdt/gdtc.h diff --git a/Makefile b/Makefile index 24dba1d..e4bb2ff 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 -Og -ggdb -Wall -Wextra -OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/paging.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 $(BUILD_DIR)/prekernel.o $(BUILD_DIR)/cpu.o $(BUILD_DIR)/KHeap.o $(BUILD_DIR)/pci.o $(BUILD_DIR)/pcidevice.o $(BUILD_DIR)/atapiDevice.o $(BUILD_DIR)/ataDevice.o $(BUILD_DIR)/rsdp.o +OFILES =$(BUILD_DIR)/boot.o $(BUILD_DIR)/kterm.o $(BUILD_DIR)/kernel.o $(BUILD_DIR)/memory.o $(BUILD_DIR)/paging.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 $(BUILD_DIR)/prekernel.o $(BUILD_DIR)/cpu.o $(BUILD_DIR)/KHeap.o $(BUILD_DIR)/pci.o $(BUILD_DIR)/pcidevice.o $(BUILD_DIR)/atapiDevice.o $(BUILD_DIR)/ataDevice.o $(BUILD_DIR)/rsdp.o $(BUILD_DIR)/acpi.o SRC_DIR = source BUILD_DIR = build @@ -36,12 +36,12 @@ run: all virtualboxvm --startvm "BarinkOS_test" debug: all objcopy --only-keep-debug build/myos.bin kernel.sym - $(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -s -d int + $(EMULATOR) -cdrom build/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -s -d int -no-shutdown -no-reboot test: - $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo + $(EMULATOR) -kernel $(BUILD_DIR)/myos.bin -serial stdio -vga std -display gtk -m 2G -cpu core2duo -d int -no-shutdown -no-reboot test_iso: - $(EMULATOR) -boot d -cdrom $(BUILD_DIR)/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo + $(EMULATOR) -boot d -cdrom $(BUILD_DIR)/barinkOS.iso -serial stdio -vga std -display gtk -m 2G -cpu core2duo -d int -no-reboot -no-shutdown test_disk: $(EMULATOR) -boot d -drive format=raw,file=build/disk.img -serial stdio -vga std -display gtk -m 2G -cpu core2duo @@ -97,6 +97,9 @@ $(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)/acpi.o: + $(CPP) -c $(SRC_DIR)/kernel/drivers/acpi/acpi.cpp -o $(BUILD_DIR)/acpi.o $(CFLAGS) -fno-exceptions -fno-rtti + $(BUILD_DIR)/pit.o: $(CPP) -c $(SRC_DIR)/kernel/drivers/pit/pit.cpp -o $(BUILD_DIR)/pit.o $(CFLAGS) -fno-exceptions -fno-rtti @@ -126,6 +129,7 @@ $(BUILD_DIR)/cpu.o: $(CPP) -c $(SRC_DIR)/kernel/cpu.cpp -o $(BUILD_DIR)/cpu.o $(CFLAGS) -fno-exceptions -fno-rtti + # Assembly -> Object files $(BUILD_DIR)/boot.o: $(AS) $(SRC_DIR)/kernel/boot/boot.s -o $(BUILD_DIR)/boot.o diff --git a/features.md b/features.md index 1d33930..577e666 100644 --- a/features.md +++ b/features.md @@ -29,7 +29,6 @@ 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 @@ -49,3 +48,4 @@ Basic Window server/client \ EXT2 Filesystem USTAR Filesystem \ + FAT16 Filesystem \ diff --git a/source/kernel/boot/boot.s b/source/kernel/boot/boot.s index 18e50ca..6013482 100644 --- a/source/kernel/boot/boot.s +++ b/source/kernel/boot/boot.s @@ -83,7 +83,7 @@ isPaging: call prekernelSetup # Unmap the identity mapping as it is now unnecessary - movl $0, boot_page_directory + 0 + # movl $0, boot_page_directory + 0 # Reload cr3 to force tlb flush movl %cr3, %ecx diff --git a/source/kernel/drivers/acpi/acpi.cpp b/source/kernel/drivers/acpi/acpi.cpp new file mode 100644 index 0000000..6366d6f --- /dev/null +++ b/source/kernel/drivers/acpi/acpi.cpp @@ -0,0 +1,14 @@ +#include "acpi.h" +RSDPTR* ACPI::rsd_ptr; +RSDT* ACPI::rsd_table; + + + +void ACPI::initialize(){ + + // Find the Root System Description Pointer + ACPI::rsd_ptr = FindRSD(); + printRSD(rsd_ptr); + // Get the Root System Description Table + ACPI::rsd_table = getRSDT(rsd_ptr); +} \ No newline at end of file diff --git a/source/kernel/drivers/acpi/acpi.h b/source/kernel/drivers/acpi/acpi.h new file mode 100644 index 0000000..66fe8d9 --- /dev/null +++ b/source/kernel/drivers/acpi/acpi.h @@ -0,0 +1,13 @@ +#pragma once +#include "rsdp.h" +class ACPI { + public: + static void initialize(); + + // In the future ACPI might start + // doing more systems initialization + + private: + static RSDPTR* rsd_ptr; + static RSDT* rsd_table; +}; \ No newline at end of file diff --git a/source/kernel/drivers/acpi/rsdp.h b/source/kernel/drivers/acpi/rsdp.h index 925b50d..eb5a87a 100644 --- a/source/kernel/drivers/acpi/rsdp.h +++ b/source/kernel/drivers/acpi/rsdp.h @@ -27,8 +27,6 @@ struct RSDT{ uint32_t PointerToSDT[]; // Length of array : (header.Length - sizeof(header))/ 4 }__attribute__((packed)); - -//NOTE: only scans EBDA enough to find RSD PTR in QEMU RSDPTR* FindRSD(); void printRSD(RSDPTR* rsd); diff --git a/source/kernel/drivers/ide/sampleIDE.h b/source/kernel/drivers/ide/sampleIDE.h index 3976ac3..5be1cf9 100644 --- a/source/kernel/drivers/ide/sampleIDE.h +++ b/source/kernel/drivers/ide/sampleIDE.h @@ -155,7 +155,7 @@ inline void init_IDE( uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3, // 3- Detect ATA-ATAPI Devices: -void DetectDevices(){ +inline void DetectDevices(){ int i, j, k, count = 0; for (i = 0; i < 2; i++) @@ -228,7 +228,7 @@ void DetectDevices(){ } -void Detect_IO_Ports(uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3, uint32_t BAR4){ +inline void Detect_IO_Ports(uint32_t BAR0, uint32_t BAR1,uint32_t BAR2, uint32_t BAR3, uint32_t BAR4){ // 1 Detect I/O Ports which interface an IDE Controller // Based on the implementation within serenity diff --git a/source/kernel/drivers/pci/pci.cpp b/source/kernel/drivers/pci/pci.cpp index c7ba0ac..e45314c 100644 --- a/source/kernel/drivers/pci/pci.cpp +++ b/source/kernel/drivers/pci/pci.cpp @@ -185,7 +185,11 @@ void PrintPCIDeviceInfo (PCIBusAddress& PCIDeviceAddress) } void PCI_Enumerate(){ - int devicesFound = 0; + + + int devicesFound = 0; + + printf("Start finding devices, Found: %d devices"); // loop through all possible busses, devices and their functions; for( int bus = 0 ; bus < 256 ; bus++) { diff --git a/source/kernel/drivers/pci/pci.h b/source/kernel/drivers/pci/pci.h index 272e0f4..7e60de4 100644 --- a/source/kernel/drivers/pci/pci.h +++ b/source/kernel/drivers/pci/pci.h @@ -10,8 +10,6 @@ extern const char* ClassCodeTable [0x13]; - - // Note: this could be used to make the api for receiving PCI class codes a bit // nicer. struct ClassCodes { diff --git a/source/kernel/gdt/gdt.s b/source/kernel/gdt/gdt.s deleted file mode 100644 index 95859c2..0000000 --- a/source/kernel/gdt/gdt.s +++ /dev/null @@ -1,19 +0,0 @@ -.global LoadGlobalDescriptorTable - - LoadGlobalDescriptorTable: - lgdt gdtDescriptor - - movw $16, %ax - movw %ax, %ds - movw %ax, %es - movw %ax, %fs - movw %ax, %gs - movw %ax, %ss - - jmp $8,$flush - - flush: - ret - - - diff --git a/source/kernel/gdt/gdtc.cpp b/source/kernel/gdt/gdtc.cpp deleted file mode 100644 index 5547dee..0000000 --- a/source/kernel/gdt/gdtc.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include "gdtc.h" -#include "../terminal/kterm.h" - -#define NULL_SEGMENT 0 -#define KERNEL_CODE_SEGMENT 1 -#define KERNEL_DATA_SEGMENT 2 -#define USER_CODE_SEGMENT 3 -#define USER_DATA_SEGMENT 4 - -SegmentDescriptor GlobalDescriptorTable[5]; -GlobalDescriptorTableDescriptor gdtDescriptor; - -void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ){ - GlobalDescriptorTable[which].base_low = (base & 0xFFFF ); - GlobalDescriptorTable[which].base_middle = (base >> 6) & 0xFF; - GlobalDescriptorTable[which].base_high = (base >> 24) & 0xFF; - - GlobalDescriptorTable[which].limit_low = (limit & 0xFFFF); - GlobalDescriptorTable[which].granularity = ((limit >> 16) & 0x0F); - - GlobalDescriptorTable[which].granularity |= (granularity & 0xF0); - GlobalDescriptorTable[which].access = access; - - -} - - - - -void initGDT(){ - -#ifdef __VERBOSE__ - printf("Init GDT!\n"); -#endif - // NULL segment - add_descriptor(NULL_SEGMENT, 0,0,0,0); - - // Kernel Code Segment - add_descriptor(KERNEL_CODE_SEGMENT, 0, 0xFFFFFFFF, 0x9A, 0xCF); - - // Kernel Data Segment - add_descriptor(KERNEL_DATA_SEGMENT, 0, 0xFFFFFFFF, 0x92, 0xCF); - - // User Code Segment - // TODO: - - // User Data Segement - // TODO: - - // init Gdt Descriptor - gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1); - gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable; - - - - LoadGlobalDescriptorTable(); - -} diff --git a/source/kernel/gdt/gdtc.h b/source/kernel/gdt/gdtc.h deleted file mode 100644 index 548bc5e..0000000 --- a/source/kernel/gdt/gdtc.h +++ /dev/null @@ -1,27 +0,0 @@ -#include - - -struct SegmentDescriptor { - unsigned short limit_low; - unsigned short base_low; - unsigned char base_middle; - unsigned char access; - unsigned char granularity; - unsigned char base_high; -}__attribute__((packed)); - - -struct GlobalDescriptorTableDescriptor{ - unsigned short limit; - unsigned int base; -}__attribute__((packed)); - -extern SegmentDescriptor GlobalDescriptorTable[]; -extern GlobalDescriptorTableDescriptor gdtDescriptor; - - -void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ); - - -extern "C" void LoadGlobalDescriptorTable(); -void initGDT(); diff --git a/source/kernel/interrupts/idt/idt.cpp b/source/kernel/interrupts/idt/idt.cpp index abb9940..3000fae 100644 --- a/source/kernel/interrupts/idt/idt.cpp +++ b/source/kernel/interrupts/idt/idt.cpp @@ -2,8 +2,7 @@ #include "../../drivers/pit/pit.h" #include "../../drivers/ps-2/keyboard.h" #include "../../cpu.h" -#include "../../drivers/ps-2/keyboard.h" - +#include "../../memory/VirtualMemoryManager.h" IDT_entry idt_table[256]; IDT_ptr idt_ptr; @@ -17,25 +16,25 @@ void set_id_entry (uint8_t num , uint32_t base, uint16_t sel, uint8_t flags){ }; -void irs_handler (registers regs) { +void irs_handler (registers* regs) { uint32_t FaultingAddress; //printf("(IRS) Interrupt number: %d \r", regs.int_no); - switch (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); + 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); + printf("EIP: 0x%x\n", regs->eip); + printf("EAX: 0x%x\n", regs->eax); + printf("EBP: 0x%x\n", regs->ebp); break; case 2: @@ -46,49 +45,50 @@ void irs_handler (registers regs) { 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); + 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); + 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); + 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); + 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); + 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); + printf("EIP: 0x%x\n", regs->eip); + printf("EAX: 0x%x\n", regs->eax); + printf("EBP: 0x%x\n", regs->ebp); + while(true); break; case 9: @@ -99,64 +99,74 @@ void irs_handler (registers regs) { 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); + printf("EIP: 0x%x\n", regs->eip); + printf("EAX: 0x%x\n", regs->eax); + printf("EBP: 0x%x\n", regs->ebp); + __asm__("cli;" "1: hlt;" "jmp 1b;"); 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); + 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); + printf("EIP: 0x%x\n", regs->eip); + printf("EAX: 0x%x\n", regs->eax); + printf("EBP: 0x%x\n", regs->ebp); break; - case 13: + case 13:{ // General Protection Exception #GP printf("#GP\n"); - printf("Accessing memory caused a general protectuion exception.\n"); - - printf("Fault due to entry at index: %d", (regs.err_code >> 3 & 0xFFF ) ); + printf("Accessing memory caused a general protection exception.\n"); + printf("Faulting instruction at addres: 0x%x\n", regs->eip ); + printf("Error code: 0x%x\n", regs->err_code); - if(regs.err_code & 0x3 >> 1 == 0 ){ - printf("* Index references GDT"); - } - if(regs.err_code & 0x3 >> 1 == 1 ){ - printf("* Index references IDT"); - } + if (regs->err_code != 0){ + printf("Fault due to entry at index: 0x%x (%d)\n", (regs->err_code >> 3 & 0xFFF ) , regs->err_code); - if(regs.err_code & 0x3 >> 1 == 2 ){ - printf("* Index references LDT"); - } - if(regs.err_code & 0x3 >> 1 == 4 ){ - printf("* Index references IDT"); - } + uint8_t table = regs->err_code >> 1 & 0x3 ; + + if(table == 0 ){ + printf("* Index references GDT\n"); + } + if(table == 1 ){ + printf("* Index references IDT\n"); + } - if( regs.err_code & 0x1) - { - printf("* Originated externally!"); + if(table == 2 ){ + printf("* Index references LDT\n"); + } + + if(table == 3 ){ + printf("* Index references IDT\n"); + } + + if( regs->err_code & 0x1) + { + printf("* Originated externally!\n"); + } } __asm__("cli;" "1: hlt;" "jmp 1b;"); + } break; case 14: // Page Fault Exception #PF printf("#PF\n"); - + #define ALIGN(addr, align) (((addr) & ~((align) - 1)) + (align)) FaultingAddress = GetCR2(); + printf("Accessing the linear address 0x%x resulted in a page fault!\n\n", FaultingAddress); // Error code of 32 bits are on the stack @@ -174,89 +184,86 @@ void irs_handler (registers regs) { printf("REASON: \n\n"); - if (regs.err_code & PF_ERR_PRESENT_BIT ){ + if (regs->err_code & PF_ERR_PRESENT_BIT ){ printf("* Page protection violation!\n"); } else{ printf("* Page not-present!\n"); + Immediate_Map(FaultingAddress, FaultingAddress - 0xC0000000); + } - if(regs.err_code & PF_ERR_WRITE_BIT){ + if(regs->err_code & PF_ERR_WRITE_BIT){ printf("* Write access violation!\n"); } else{ printf("* Read access violation!\n"); } - if(regs.err_code & PF_ERR_USER_BIT){ + if(regs->err_code & PF_ERR_USER_BIT){ printf("* Violation from user-space (CPL=3)\n"); } - if(regs.err_code & PF_ERR_INSTRUCTION_FETCH_BIT){ + if(regs->err_code & PF_ERR_INSTRUCTION_FETCH_BIT){ printf("* Caused by an instruction fetch. \n"); } - /* - Check the error code to figure out what happened here - */ + __asm__("cli;" "1: hlt;" "jmp 1b;"); - - - 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); + 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); + 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); + 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); + 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); + 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); + 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; } - + } diff --git a/source/kernel/interrupts/idt/idt.h b/source/kernel/interrupts/idt/idt.h index 94e409f..e2a0bd5 100644 --- a/source/kernel/interrupts/idt/idt.h +++ b/source/kernel/interrupts/idt/idt.h @@ -36,7 +36,7 @@ extern "C" { void irq_handler (registers regs); - void irs_handler (registers regs); + void irs_handler (registers* regs); extern void irs0 (); extern void irs1 (); diff --git a/source/kernel/irs_table.s b/source/kernel/irs_table.s index 4beda70..a9c8cb8 100644 --- a/source/kernel/irs_table.s +++ b/source/kernel/irs_table.s @@ -1,234 +1,63 @@ +.code32 /* * Interupt handlers */ -.globl irs0 -irs0: - cli - push $0 - push $0 - jmp irs_common +.macro ISR_NOERRORCODE NAME, VECTOR + .globl irs\NAME + irs\NAME: + cli + push $0 + push \VECTOR + jmp irs_common +.endm -.globl irs1 -irs1: - cli - push $0 - push $1 - jmp irs_common +.macro ISR_ERROCODE NAME, VECTOR + .globl irs\NAME + irs\NAME: + cli + push \VECTOR + jmp irs_common +.endm -.globl irs2 -irs2: - cli - push $0 - push $2 - jmp irs_common -.globl irs3 -irs3: - cli - push $0 - push $3 - jmp irs_common +ISR_NOERRORCODE 0 $0 +ISR_NOERRORCODE 1 $1 +ISR_NOERRORCODE 2 $2 +ISR_NOERRORCODE 3 $3 +ISR_NOERRORCODE 4 $4 +ISR_NOERRORCODE 5 $5 +ISR_NOERRORCODE 6 $6 +ISR_NOERRORCODE 7 $7 +ISR_NOERRORCODE 8 $8 +ISR_NOERRORCODE 9 $9 +ISR_NOERRORCODE 10 $10 +ISR_NOERRORCODE 11 $11 +ISR_NOERRORCODE 12 $12 +ISR_NOERRORCODE 13 $13 +ISR_NOERRORCODE 14 $14 +ISR_NOERRORCODE 15 $15 +ISR_NOERRORCODE 16 $16 +ISR_NOERRORCODE 17 $17 +ISR_NOERRORCODE 18 $18 +ISR_NOERRORCODE 19 $19 +ISR_NOERRORCODE 20 $20 +ISR_NOERRORCODE 21 $21 +ISR_NOERRORCODE 22 $22 +ISR_NOERRORCODE 23 $23 +ISR_NOERRORCODE 24 $24 +ISR_NOERRORCODE 25 $25 +ISR_NOERRORCODE 26 $26 +ISR_NOERRORCODE 27 $27 +ISR_NOERRORCODE 28 $28 +ISR_NOERRORCODE 29 $29 +ISR_NOERRORCODE 30 $30 +ISR_NOERRORCODE 31 $31 -.globl irs4 -irs4: - cli - push $0 - push $4 - jmp irs_common - -.globl irs5 -irs5: - cli - push $0 - push $5 - jmp irs_common - -.globl irs6 -irs6: - cli - push $0 - push $6 - jmp irs_common - -.globl irs7 -irs7: - cli - push $0 - push $7 - jmp irs_common - -.globl irs8 -irs8: - cli - push $0 - push $8 - jmp irs_common - -.globl irs9 -irs9: - cli - push $0 - push $9 - jmp irs_common - -.globl irs10 -irs10: - cli - push $0 - push $10 - jmp irs_common - -.globl irs11 -irs11: - cli - push $0 - push $11 - jmp irs_common - -.globl irs12 -irs12: - cli - push $0 - push $12 - jmp irs_common - -.globl irs13 -irs13: - cli - push $13 - jmp irs_common - -.globl irs14 -irs14: - cli - push $0 - push $14 - jmp irs_common - -.globl irs15 -irs15: - cli - push $0 - push $15 - jmp irs_common - -.globl irs16 -irs16: - cli - push $0 - push $16 - jmp irs_common - -.globl irs17 -irs17: - cli - push $0 - push $17 - jmp irs_common - -.globl irs18 -irs18: - cli - push $0 - push $18 - jmp irs_common - -.globl irs19 -irs19: - cli - push $0 - push $19 - jmp irs_common - -.globl irs20 -irs20: - cli - push $0 - push $20 - jmp irs_common - -.globl irs21 -irs21: - cli - push $0 - push $21 - jmp irs_common - -.globl irs22 -irs22: - cli - push $0 - push $22 - jmp irs_common - -.globl irs23 -irs23: - cli - push $0 - push $23 - jmp irs_common - -.globl irs24 -irs24: - cli - push $0 - push $24 - jmp irs_common - -.globl irs25 -irs25: - cli - push $0 - push $25 - jmp irs_common - -.globl irs26 -irs26: - cli - push $0 - push $26 - jmp irs_common - -.globl irs27 -irs27: - cli - push $0 - push $27 - jmp irs_common - -.globl irs28 -irs28: - cli - push $0 - push $28 - jmp irs_common - -.globl irs29 -irs29: - cli - push $0 - push $29 - jmp irs_common - -.globl irs30 -irs30: - cli - push $0 - push $30 - jmp irs_common - -.globl irs31 -irs31: - cli - push $0 - push $31 - jmp irs_common irs_common: pusha # Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax - mov %ds, %ax push %eax @@ -239,17 +68,20 @@ irs_common: mov %ax, %es mov %ax, %fs mov %ax, %gs + + mov %esp, %eax + push %eax call irs_handler - + pop %eax - - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs + pop %ebx // reload ther orignal data segment descriptor + mov %bx, %ds + mov %bx, %es + mov %bx, %fs + mov %bx, %gs popa - add $8, %esp # cleans push error and irs code - sti + add $12, %esp # cleans push error and irs code + iret # pops 5 things at once: CS, EIP, EFLAGS, SS, and ESP diff --git a/source/kernel/kernel.cpp b/source/kernel/kernel.cpp index 685b344..b83f2a6 100644 --- a/source/kernel/kernel.cpp +++ b/source/kernel/kernel.cpp @@ -1,37 +1,46 @@ -extern "C"{ - #include "../lib/include/string.h" + +extern "C" +{ + #include "../lib/include/string.h" } -#include "definitions.h" #include "prekernel/bootstructure.h" -#include "drivers/vga/VBE.h" -#include "drivers/pit/pit.h" - +#include "memory/memory.h" +#include "memory/memoryinfo.h" #include "memory/memory.h" #include "memory/VirtualMemoryManager.h" #include "memory/KernelHeap.h" #include "memory/gdt/gdtc.h" -#include "drivers/acpi/rsdp.h" -#include "drivers/ide/ide.h" -#include "drivers/ata/ataDevice.h" -#include "PartitionTable/MBR/MasterBootRecord.h" -#include "interrupts/idt/idt.h" -#include "filesystem/FAT/BiosParameterBlock.h" -#include "filesystem/FAT/DirectoryEntry.h" +#include "supervisorterminal/superVisorTerminal.h" + #include "drivers/io/io.h" +#include "drivers/vga/VBE.h" #include "drivers/pci/pci.h" -#include "cpu.h" -#include "serial.h" -#include "time.h" +#include "drivers/pit/pit.h" + #include "terminal/kterm.h" -#include "supervisorterminal/superVisorTerminal.h" +#include "prekernel/multiboot.h" +#include "bootinfo.h" -extern "C" void kernel_main (); -void ProcessBootInfo(); +#include "bootcheck.h" + +#include "interrupts/idt/idt.h" +#include "time.h" +#include "cpu.h" +#include "serial.h" +#include "time.h" +#include "definitions.h" + + + + +/* + Copyright © Nigel Barink 2023 +*/ extern "C" void kernel_main () { @@ -40,152 +49,6 @@ extern "C" void kernel_main () */ printf("|=== BarinkOS ===|\n"); startSuperVisorTerminal(); - - RSDPTR* rsd = FindRSD(); - RSDT* rsd_table = getRSDT(rsd); - - - // Enumerate the PCI bus - PCI_Enumerate(); - TestIDEController(); - - int devNumber = 0 ; - for ( auto device : ide_devices){ - if (!device.Reserved) - continue; - printf("Device %d\n" , devNumber); - printf (" Device on Channel: (0x%x) %s\n" ,device.Channel, device.Channel == 0 ? "Primary" : "Secondary"); - printf (" Device drive:(0x%x) %s\n" , device.Drive, device.Drive? "Slave" : "Master"); - printf (" Device Type:(0x%x) %s\n" , device.Type, device.Type ? "ATAPI" : "ATA"); - devNumber ++; - - } - - enum BUS_PORT { - Primary= 0x1f0, - Secondary = 0x170 - }; - - - - ATA_DEVICE::Identify((uint16_t) BUS_PORT::Primary, DEVICE_DRIVE::MASTER); - - const int C = 0; - const int H = 0; - const int HPC = 16; - const int SPT = 63; - - int S = 1; - uint32_t LBA = (C*HPC+H) * SPT + (S-1); - printf("LBA: %d\n" , LBA); - uint16_t buffer [256]; - - - ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, LBA, buffer); - - MBR* mbr = (MBR*) buffer; - - printf("BootSector: 0x%x\n", mbr->ValidBootsector ); - for( int i = 0 ; i < 4 ; i ++){ - PartitionTableEntry PT = mbr->TableEntries[i]; - - printf("Partition %d [ %d sectors, PartitionType: %x, 0x%x, \nLBA Start: 0x%x ]\n" , - i, PT.Number_sectors_inPartition, PT.PartitionType, mbr->uniqueID, PT.LBA_partition_start ); - } - - // Find the BiosParameter block - uint16_t biosparameterblock[256]; - ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, mbr->TableEntries[0].LBA_partition_start, biosparameterblock); - - BiosParameterBlock* bpb = (BiosParameterBlock*) biosparameterblock; - - - printf("\nBPB: Bytes per Sector %d\n", bpb->BytesPerSector ); - printf("OEM ID: %s\n", bpb->OEM_id); - printf("Bytes per sector: %d\n", bpb->BytesPerSector); - printf("Sectors per cluster: %d\n", bpb->SectorsPerCluster); - printf("Reserved sectors: %d\n", bpb->ReservedSectors); - printf("Number of FAT: %d\n", bpb->NumberOfFileAllocationTables); - printf("Number of Dir entries: %d\n", bpb->NumberOfDirectoryEntries); - printf("Total Sectors in volume: %d\n", bpb->TotalSectorsInLogicalVolume); - printf("Sectors per FAT: %d\n", bpb->NumberOfSectorsPerFAT); - - - - - /** - * @brief File Allocation Table - */ - - - uint32_t FATAddress = mbr->TableEntries[0].LBA_partition_start + bpb->ReservedSectors ; - uint16_t FAT[256]; - ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, FATAddress, FAT ); - - // Show data in terminal - for(int i = 0; i < 256; i++ ) { - printf("%x ", FAT[i]); - } - kterm_put('\n'); - - - uint32_t RootDirectoryRegion = FATAddress + ( bpb->NumberOfFileAllocationTables * bpb->NumberOfSectorsPerFAT ); - uint32_t DataRegion = RootDirectoryRegion + ((bpb->NumberOfDirectoryEntries * 32) / bpb->BytesPerSector ); - - uint16_t data2 [256]; - ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, RootDirectoryRegion, data2 ); - DirectoryEntry* RootDirectory = (DirectoryEntry*) data2; - // List files in root - for(int i= 0; i < bpb->NumberOfDirectoryEntries ; i++ ) - { - DirectoryEntry* entry = (DirectoryEntry*)((uint32_t) RootDirectory + (i * sizeof(DirectoryEntry))); - - if( entry->filename[0] == (uint8_t) 0x00 ) - break; // There are no more entries in this directory or the entry is free - - if( entry->attribute & 0x01 == 0x01 || entry->attribute & 0x20 == 0x20) - continue; // Skip listing if hidden or Achieve flag is set - - // Print the filename; - for( int n = 0; n < 8; n++ ){ - if(entry->filename[n] == 0x20) - break; - kterm_put(entry->filename[n]); - }kterm_put('\n'); - - for( int n = 0; n < 3; n++){ - kterm_put(entry->Extension[n]); - }kterm_put('\n'); - - printf("Attribute: %x \n" , entry->attribute); - printf("FileSize: %d Bytes\n", entry->FilesizeInBytes); - - if( entry->FilesizeInBytes != 0x0 || entry->attribute & 0x8 == 0x0){ - printf("Show contents"); - - printf( "Start cluster of the file: 0x%x\n" , entry->StartingCluster); - - printf("IS it only 1 cluster? %s\n" , FAT[i] == 0xFFFF? "Yes": "No" ); - - uint32_t sector = DataRegion + ((entry->StartingCluster - 0x02 ) * bpb->SectorsPerCluster); - - - uint16_t dataBlob [256]; - ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, sector, dataBlob ); - for( int n = 0; n < 256; n++) - { - kterm_put(dataBlob[n] & 0x00ff); - - kterm_put(dataBlob[n] >> 8); - }kterm_put('\n'); - - - } - - printf("======================\n"); - - - } } @@ -198,38 +61,26 @@ extern "C" void early_main() initGDT(); init_idt(); - + // Enable interrupts asm volatile("STI"); - - - initHeap(); - - printf("TRY ALLOCATING 4 BYTES\n"); - uint32_t* MyVariable = (uint32_t*) malloc(4); // allocate 4 bytes using my heap - free(MyVariable); - - // test heap allocation - struct KernelInfo { - int bar; - bool foo; - }; - - KernelInfo* MyInfo = (KernelInfo*) malloc(sizeof(KernelInfo)); - - MyInfo->bar = 6; - MyInfo->foo = false; - printf("bar contains %d\n", MyInfo->bar); - free(MyInfo); - - + initHeap(); printf("Enable Protected mode and jump to kernel main\n"); + + // Set the protected bit of control register 0 + // this will put the CPU into protected mode + // NOTE: This should really be a assembly procedure + // We cant directly write to control register 0 + // therefor we copy the value of control register 0 into eax + // once we are done manipulating the value we write the value in + // eax back to control register 0 + asm volatile("mov %cr0, %eax "); asm volatile("or $1, %eax"); - asm volatile("mov %eax, %cr0"); // re-enable protected mode ? + asm volatile("mov %eax, %cr0"); pit_initialise(); diff --git a/source/kernel/kernel.h b/source/kernel/kernel.h index ae769df..0b861f8 100644 --- a/source/kernel/kernel.h +++ b/source/kernel/kernel.h @@ -1,43 +1,8 @@ #pragma once -extern "C" -{ - #include "../lib/include/string.h" -} - - -#include "drivers/VGA/VBE.h" -#include "terminal/kterm.h" - -#include "./boot/multiboot.h" -#include "bootinfo.h" - -#include "memory/memory.h" -#include "memory/memoryinfo.h" -#include "bootcheck.h" - -#include "gdt/gdtc.h" -#include "interrupts/idt/idt.h" - -#include "drivers/IO/io.h" -#include "time.h" -#include "drivers/pit/pit.h" - -#include "cpu.h" -#include "serial.h" -#include "drivers/IO/PCI/pci.h" -#include "drivers/ide/ide.h" -#include "./drivers/IO/ata/ataDevice.h" -#include "./PartitionTable/MBR/MasterBootRecord.h" -#include "./filesystem/FAT/BiosParameterBlock.h" -#include "./filesystem/FAT/ExtendBootRecord.h" -#include "./filesystem/FAT/DirectoryEntry.h" -#include "drivers/ACPI/rsdp.h" - - -#include "time.h" -#include "supervisorterminal/superVisorTerminal.h" #define CHECK_FLAG(flags, bit) ((flags) & (1 <<(bit))) #define PANIC(message) {return;} + + diff --git a/source/kernel/memory/KernelHeap.cpp b/source/kernel/memory/KernelHeap.cpp index adfd2b6..4483d2d 100644 --- a/source/kernel/memory/KernelHeap.cpp +++ b/source/kernel/memory/KernelHeap.cpp @@ -63,26 +63,24 @@ void free(void* addr) void initHeap() { - // put the start of our kernel heap 1 page after the kernel_end address - // Lets calculate the address - printf("FIND SUITABLE HEAP_ADDRESS\n"); - uint32_t alligned_k_end = (uint32_t) &kernel_end + ((uint32_t)&kernel_end % BLOCK_SIZE == 0 ? 4096 : 0); - uint32_t HEAP_ADDRESS = (uint32_t) alligned_k_end + 4096; - printf("HEAP_ADDRESS: 0x%x\n", HEAP_ADDRESS); - - // NOTE: we can't check if the mapping has failed or not here! - AllocatePage(HEAP_ADDRESS); - start = (heap_block*) HEAP_ADDRESS; + void* HEAP_ADDRESS = allocate_block(); + printf("0x%x HEAP Paddr\n", HEAP_ADDRESS); + + Immediate_Map((uint32_t)HEAP_ADDRESS + 0xC0000000, (uint32_t)HEAP_ADDRESS ); + start = (heap_block*) ((uint32_t)HEAP_ADDRESS + 0xC0000000); heap_size = 4096; printf("Clear heap\n"); // Clear the heap printf("set at 0x%x %d bytes to zero\n", start , heap_size); + memset((void*)start, 0x00, heap_size /4); + printf("Init first heap block\n"); // initialzie start->Size = heap_size - sizeof(heap_block); + start->Used = false; } \ No newline at end of file diff --git a/source/kernel/memory/VirtualMemoryManager.cpp b/source/kernel/memory/VirtualMemoryManager.cpp index 3ce9260..e866b28 100644 --- a/source/kernel/memory/VirtualMemoryManager.cpp +++ b/source/kernel/memory/VirtualMemoryManager.cpp @@ -1,7 +1,8 @@ #include "VirtualMemoryManager.h" #define ALIGN(addr, align) (((addr) & ~((align) - 1 )) + (align)) -extern uint32_t boot_page_directory[1024] ; +extern uint32_t boot_page_directory[1024] ; // points to the wrong location + extern uint32_t boot_page_table[1024]; @@ -26,29 +27,28 @@ void AllocatePage(uint32_t vaddr) { printf("Directory entry is marked as present\n"); uint32_t* page_table = (uint32_t*)((boot_page_directory[PageDirectoryEntryIndex]) & 0xFFFFE000) ; - page_table = (uint32_t*) ((uint32_t)page_table + 0xC0000000); // Add kernel offset - printf("Page table address: 0x%x\n", (uint32_t)page_table); + //page_table = (uint32_t*) ((uint32_t)page_table + 0xC0000000); // Add kernel offset + printf("Page table address: 0x%x\n", (uint32_t)&page_table); // check if the page table entry is marked as present if ( page_table[PageTableEntryIndex] & 0x1 ) { printf("page already present!\n"); - return; } else{ printf("Mapping a physical page.\n"); // Map the entry to a physical page - page_table[PageTableEntryIndex] = (uint32_t)(allocate_block() + 0x3); - flush_cr3(); + page_table[PageTableEntryIndex] = (uint32_t)allocate_block() | 0x3; } } else { printf("Mapping a new page directory entry with a page table\n"); // mark the page table as present and allocate a physical block for it - boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)(allocate_block() + 0x3); - flush_cr3(); + boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)allocate_block() | 0x3; } + asm ("cli; invlpg (%0); sti" :: "r" (vaddr) : "memory" ); + } @@ -74,12 +74,45 @@ void FreePage(uint32_t vaddr ) void Immediate_Map ( uint32_t vaddr, uint32_t paddr) { - uint32_t page_aligned_address = ALIGN(vaddr, 4096); - + printf("map 0x%x to 0x%x\n", paddr, vaddr); // allocate a page at virtual address int PageDirectoryEntryIndex = vaddr >> 22; int PageTableEntryIndex = (vaddr >> 12) & 0x1FFF; + printf("Map address at PDE 0x%x PTE 0x%x\n", PageDirectoryEntryIndex, PageTableEntryIndex); + + if ((boot_page_directory - 0xC0000000)[PageDirectoryEntryIndex] & 0x1 ) + { + printf("Directory entry is marked as present\n"); + + } else { + printf("Mapping a new page directory entry with a page table\n"); + // mark the page table as present and allocate a physical block for it + + void* new_page_dir = allocate_block(); + printf("New page directory address 0x%x\n", new_page_dir); + boot_page_directory[PageDirectoryEntryIndex] = (uint32_t)new_page_dir | 0x3; + + } + + printf("PDE found at : 0x%x\n", (uint32_t) &boot_page_directory[PageDirectoryEntryIndex]); + uint32_t* page_table = (uint32_t*)(boot_page_directory[PageDirectoryEntryIndex] & 0xFFFFE000) ; + //page_table = (uint32_t*) ((uint32_t)page_table - 0xC0000000); // remove kernel offset + printf("Page table address: 0x%x\n", (uint32_t)page_table); + + // check if the page table entry is marked as present + if ( page_table[PageTableEntryIndex] & 0x1 ) + { + printf("page already present!\n"); + printf("Entry found at addr: 0x%x\n", &(page_table[PageTableEntryIndex])); + } else{ + printf("Mapping a physical page.\n"); + // Map the entry to a physical page + page_table[PageTableEntryIndex] = (uint32_t)(paddr | 0x3); + } + + + asm ("cli; invlpg (%0); sti" :: "r" (vaddr) : "memory" ); } void Immediate_Unmap(uint32_t vaddr) diff --git a/source/kernel/memory/VirtualMemoryManager.h b/source/kernel/memory/VirtualMemoryManager.h index ef80ffe..f4da57a 100644 --- a/source/kernel/memory/VirtualMemoryManager.h +++ b/source/kernel/memory/VirtualMemoryManager.h @@ -9,7 +9,7 @@ void SetupVMM(); void AllocatePage(uint32_t v_addr ); void FreePage(uint32_t v_addr); -void Immediate_Map(uint32_t p_addr, uint32_t v_addr); +void Immediate_Map(uint32_t vaddr, uint32_t paddr); void Immediate_Unmap (uint32_t v_addr); // void Demand_map(uint32_t p_addr, uint32_t v_addr); diff --git a/source/kernel/memory/gdt/gdtc.cpp b/source/kernel/memory/gdt/gdtc.cpp index 32b8ea3..55e0b92 100644 --- a/source/kernel/memory/gdt/gdtc.cpp +++ b/source/kernel/memory/gdt/gdtc.cpp @@ -6,9 +6,13 @@ #define KERNEL_DATA_SEGMENT 2 #define USER_CODE_SEGMENT 3 #define USER_DATA_SEGMENT 4 +#define TASK_STATE_SEGMENT 5 -SegmentDescriptor GlobalDescriptorTable[5]; +SegmentDescriptor GlobalDescriptorTable[6]; GlobalDescriptorTableDescriptor gdtDescriptor; +tss32 TaskStateSegment = {}; + + void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ){ GlobalDescriptorTable[which].base_low = (base & 0xFFFF ); @@ -21,7 +25,6 @@ void add_descriptor(int which , unsigned long base, unsigned long limit, unsigne GlobalDescriptorTable[which].granularity |= (granularity & 0xF0); GlobalDescriptorTable[which].access = access; - } @@ -29,9 +32,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); @@ -42,16 +45,18 @@ void initGDT(){ add_descriptor(KERNEL_DATA_SEGMENT, 0, 0xFFFFFFFF, 0x92, 0xCF); // User Code Segment - // TODO: + add_descriptor(USER_CODE_SEGMENT, 0, 0xFFFFFFFF, 0xFA, 0xCF); // User Data Segement - // TODO: + add_descriptor(USER_DATA_SEGMENT, 0, 0xFFFFFFFF, 0xF2, 0xCF); + + // Task Segment Descriptor + add_descriptor(TASK_STATE_SEGMENT, (unsigned long)&TaskStateSegment, sizeof(TaskStateSegment), 0x89, 0x0); // init Gdt Descriptor gdtDescriptor.limit = ((sizeof(SegmentDescriptor ) * 5 ) - 1); - gdtDescriptor.base = (unsigned int) &GlobalDescriptorTable; + gdtDescriptor.base = (unsigned int) (&GlobalDescriptorTable); - printf("GDT at address 0x%x, with an size of 0x%x bytes\n" , (unsigned int)GlobalDescriptorTable, sizeof(GlobalDescriptorTable)); LoadGlobalDescriptorTable(); diff --git a/source/kernel/memory/gdt/gdtc.h b/source/kernel/memory/gdt/gdtc.h index 548bc5e..adca78e 100644 --- a/source/kernel/memory/gdt/gdtc.h +++ b/source/kernel/memory/gdt/gdtc.h @@ -1,6 +1,5 @@ +#pragma once #include - - struct SegmentDescriptor { unsigned short limit_low; unsigned short base_low; @@ -10,14 +9,16 @@ struct SegmentDescriptor { unsigned char base_high; }__attribute__((packed)); +struct tss32 { + uint64_t bits; + uint8_t other_bits :5; +}__attribute__((packed)); struct GlobalDescriptorTableDescriptor{ unsigned short limit; unsigned int base; -}__attribute__((packed)); +}__attribute__((packed)) ; -extern SegmentDescriptor GlobalDescriptorTable[]; -extern GlobalDescriptorTableDescriptor gdtDescriptor; void add_descriptor(int which , unsigned long base, unsigned long limit, unsigned char access, unsigned char granularity ); diff --git a/source/kernel/supervisorterminal/superVisorTerminal.cpp b/source/kernel/supervisorterminal/superVisorTerminal.cpp index 51aeff9..73ee676 100644 --- a/source/kernel/supervisorterminal/superVisorTerminal.cpp +++ b/source/kernel/supervisorterminal/superVisorTerminal.cpp @@ -1,4 +1,10 @@ #include "superVisorTerminal.h" +#include "../drivers/ata/ataDevice.h" +#include "../drivers/acpi/acpi.h" +#include "../drivers/ide/ide.h" +#include "../PartitionTable/MBR/MasterBootRecord.h" +#include "../filesystem/FAT/BiosParameterBlock.h" +#include "../filesystem/FAT/DirectoryEntry.h" bool isRunning = true; void startSuperVisorTerminal(){ while (isRunning){ @@ -24,7 +30,7 @@ void startSuperVisorTerminal(){ } printf("\n"); KeyHandled(); - + if ( strncmp("DATE", command , characterCount ) == 0 ) { @@ -34,7 +40,7 @@ void startSuperVisorTerminal(){ printf(" - Time: %02d:%02d:%02d\n" , hour, minute, second); printf(" - Ticks: %09d\n", pit_tick); } - else if( strncmp ("MEMORY" , command , characterCount) == 0 ) + if( strncmp ("MEMORY" , command , characterCount) == 0 ) { // Show memory layout printf("========= Memory ==========\n"); @@ -51,33 +57,181 @@ void startSuperVisorTerminal(){ //printf("Reserved Memory: %d bytes\n", bootinfo->memory->ReservedMemory); } - else if(strncmp("TEST", command, characterCount) == 0) + 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) + 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) + if(strncmp("CLEAR", command, characterCount) == 0) { kterm_init(); printf("|=== BarinkOS ===|\n"); } - else if(strncmp("FAT", command, characterCount) == 0){ - isRunning = false; + if(strncmp("FAT", command, characterCount) == 0) + { + printf("ACPI initialize!\n"); + ///ACPI::initialize(); + + // Enumerate the PCI bus + printf("PCI Enumeration\n"); + PCI_Enumerate(); + printf("TEST IDE Controller"); + TestIDEController(); + + int devNumber = 0 ; + for ( auto device : ide_devices){ + if (!device.Reserved) + continue; + printf("Device %d\n" , devNumber); + printf (" Device on Channel: (0x%x) %s\n" ,device.Channel, device.Channel == 0 ? "Primary" : "Secondary"); + printf (" Device drive:(0x%x) %s\n" , device.Drive, device.Drive? "Slave" : "Master"); + printf (" Device Type:(0x%x) %s\n" , device.Type, device.Type ? "ATAPI" : "ATA"); + devNumber ++; + + } + + enum BUS_PORT { + Primary= 0x1f0, + Secondary = 0x170 + }; + + + + ATA_DEVICE::Identify((uint16_t) BUS_PORT::Primary, DEVICE_DRIVE::MASTER); + + const int C = 0; + const int H = 0; + const int HPC = 16; + const int SPT = 63; + + int S = 1; + uint32_t LBA = (C*HPC+H) * SPT + (S-1); + printf("LBA: %d\n" , LBA); + uint16_t buffer [256]; + + + ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, LBA, buffer); + + MBR* mbr = (MBR*) buffer; + + printf("BootSector: 0x%x\n", mbr->ValidBootsector ); + for( int i = 0 ; i < 4 ; i ++){ + PartitionTableEntry PT = mbr->TableEntries[i]; + + printf("Partition %d [ %d sectors, PartitionType: %x, 0x%x, \nLBA Start: 0x%x ]\n" , + i, PT.Number_sectors_inPartition, PT.PartitionType, mbr->uniqueID, PT.LBA_partition_start ); + } + + // Find the BiosParameter block + uint16_t biosparameterblock[256]; + ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, mbr->TableEntries[0].LBA_partition_start, biosparameterblock); + + BiosParameterBlock* bpb = (BiosParameterBlock*) biosparameterblock; + + + printf("\nBPB: Bytes per Sector %d\n", bpb->BytesPerSector ); + printf("OEM ID: %s\n", bpb->OEM_id); + printf("Bytes per sector: %d\n", bpb->BytesPerSector); + printf("Sectors per cluster: %d\n", bpb->SectorsPerCluster); + printf("Reserved sectors: %d\n", bpb->ReservedSectors); + printf("Number of FAT: %d\n", bpb->NumberOfFileAllocationTables); + printf("Number of Dir entries: %d\n", bpb->NumberOfDirectoryEntries); + printf("Total Sectors in volume: %d\n", bpb->TotalSectorsInLogicalVolume); + printf("Sectors per FAT: %d\n", bpb->NumberOfSectorsPerFAT); + + /** + * @brief File Allocation Table + */ + + + uint32_t FATAddress = mbr->TableEntries[0].LBA_partition_start + bpb->ReservedSectors ; + uint16_t FAT[256]; + ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, FATAddress, FAT ); + + // Show data in terminal + for(int i = 0; i < 256; i++ ) { + printf("%x ", FAT[i]); + } + kterm_put('\n'); + + + uint32_t RootDirectoryRegion = FATAddress + ( bpb->NumberOfFileAllocationTables * bpb->NumberOfSectorsPerFAT ); + uint32_t DataRegion = RootDirectoryRegion + ((bpb->NumberOfDirectoryEntries * 32) / bpb->BytesPerSector ); + + uint16_t data2 [256]; + ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, RootDirectoryRegion, data2 ); + DirectoryEntry* RootDirectory = (DirectoryEntry*) data2; + // List files in root + for(int i= 0; i < bpb->NumberOfDirectoryEntries ; i++ ) + { + DirectoryEntry* entry = (DirectoryEntry*)((uint32_t) RootDirectory + (i * sizeof(DirectoryEntry))); + + if( entry->filename[0] == (uint8_t) 0x00 ) + break; // There are no more entries in this directory or the entry is free + + if( entry->attribute & 0x01 == 0x01 || entry->attribute & 0x20 == 0x20) + continue; // Skip listing if hidden or Achieve flag is set + + // Print the filename; + for( int n = 0; n < 8; n++ ){ + if(entry->filename[n] == 0x20) + break; + kterm_put(entry->filename[n]); + }kterm_put('\n'); + + for( int n = 0; n < 3; n++){ + kterm_put(entry->Extension[n]); + }kterm_put('\n'); + + printf("Attribute: %x \n" , entry->attribute); + printf("FileSize: %d Bytes\n", entry->FilesizeInBytes); + + if( entry->FilesizeInBytes != 0x0 || entry->attribute & 0x8 == 0x0){ + printf("Show contents"); + + printf( "Start cluster of the file: 0x%x\n" , entry->StartingCluster); + + printf("IS it only 1 cluster? %s\n" , FAT[i] == 0xFFFF? "Yes": "No" ); + + uint32_t sector = DataRegion + ((entry->StartingCluster - 0x02 ) * bpb->SectorsPerCluster); + + + uint16_t dataBlob [256]; + ATA_DEVICE::Read(BUS_PORT::Primary, DEVICE_DRIVE::MASTER, sector, dataBlob ); + for( int n = 0; n < 256; n++) + { + kterm_put(dataBlob[n] & 0x00ff); + + kterm_put(dataBlob[n] >> 8); + }kterm_put('\n'); + + + } + + printf("======================\n"); + + + } continue; } - else - { - printf("Unknown command\n"); + + + + if(strncmp("glg", command, characterCount) == 0){ + printf("Why???"); } + printf("executed command: %s\n", command); + + delay(1000); } } \ No newline at end of file