diff options
| author | Alexey Gavrilov <rebovas@yahoo.com> | 2024-03-31 14:39:51 +0700 |
|---|---|---|
| committer | Alexey Gavrilov <rebovas@yahoo.com> | 2024-03-31 14:39:51 +0700 |
| commit | 49cfee4e370892df8404e56d53b04dde196f82f2 (patch) | |
| tree | d309b630a161823c79dab9a48f67a41a40d76b24 | |
| parent | a276644952ed018e77ca64181059434a6bc4ee62 (diff) | |
IDT + uintptr update
| -rw-r--r-- | arch/x86/PrimaryInit.cpp | 17 | ||||
| -rw-r--r-- | arch/x86/PrimaryInit.h | 1 | ||||
| -rwxr-xr-x | arch/x86/gdt/Gdt.cpp | 60 | ||||
| -rwxr-xr-x | arch/x86/gdt/Gdt.h | 27 | ||||
| -rw-r--r-- | arch/x86/idt/Idt.cpp | 130 | ||||
| -rw-r--r-- | arch/x86/idt/Idt.h | 63 | ||||
| -rw-r--r-- | include/types.h | 2 | ||||
| -rw-r--r-- | kernel/boot.s | 2 | ||||
| -rw-r--r-- | kernel/kernel.c | 3 | ||||
| -rw-r--r-- | makefile | 5 |
10 files changed, 266 insertions, 44 deletions
diff --git a/arch/x86/PrimaryInit.cpp b/arch/x86/PrimaryInit.cpp index 7de690e..5359978 100644 --- a/arch/x86/PrimaryInit.cpp +++ b/arch/x86/PrimaryInit.cpp @@ -1,13 +1,28 @@ #include "PrimaryInit.h" +#include "idt/Idt.h" +// Function to test idt work. Should remove +void isr() +{ + out::display << "The kernel has finished" << '\n'; +}; + void PrimaryInitialization::processorInitialize() { - MngGdt mngGdt = MngGdt(); + MngIdt &mngIdt = MngIdt::getInstance(); + MngGdt &mngGdt = MngGdt::getInstance(); mngGdt.addDescriptor(DescSeg32::flatCodeKernel()); mngGdt.addDescriptor(DescSeg32::flatDataKernel()); mngGdt.loadGdt(); + + mngIdt.setDescriptor( + DescInterrupt32::InterruptKernelLong( + (uint32)isr, + mngGdt.getCodeSegmentKernel()), + 0x20); + mngIdt.loadIdt(); }; void PrimaryInitialization::devicesInitialize() diff --git a/arch/x86/PrimaryInit.h b/arch/x86/PrimaryInit.h index 243c731..540ad41 100644 --- a/arch/x86/PrimaryInit.h +++ b/arch/x86/PrimaryInit.h @@ -1,5 +1,6 @@ #include "gdt/Gdt.h" #include "io/VGADisplay.h" +#include "idt/Idt.h" class PrimaryInitialization diff --git a/arch/x86/gdt/Gdt.cpp b/arch/x86/gdt/Gdt.cpp index 21941b4..70f30cd 100755 --- a/arch/x86/gdt/Gdt.cpp +++ b/arch/x86/gdt/Gdt.cpp @@ -2,6 +2,21 @@ uint64 MngGdt::gdt[MngGdt::size]; +bool MngGdt::isInitialize = false; +bool MngGdt::gdtLoaded = false; +MngGdt mngGdt; + +MngGdt::MngGdt() +{ + if(!isInitialize) + { + MemoryOperations::set(gdt, 0, sizeof(uint64) * size); + currIdx = 1; + gdtLoaded = false; + isInitialize = true; + codeSegmentKern = NULL; + } +}; DescSeg32::DescSeg32(uint32 base, uint32 limit, uint8 access, uint8 flags) { @@ -57,59 +72,48 @@ uint64 DescSeg32::flatDataUser() , PAGEGRAN | HIGHSIZE).getDescriptor(); }; -MngGdt::MngGdt() -{ - gdt[0] = 0; - currIdx = 1; - isGdtLoaded = 0; -}; - bool MngGdt::addDescriptor(uint64 desc) { - if(currIdx >= size || currIdx == 0) + if(currIdx >= size or currIdx == 0 or gdtLoaded) { return false; } + if(desc == DescSeg32::flatCodeKernel()) codeSegmentKern = currIdx * 8; this->gdt[currIdx++] = desc; return true; }; bool MngGdt::loadGdt() { - if(isGdtLoaded) + if(gdtLoaded) { return false; } - uint64 pointer = 0; + // Set pointer + uint64 descriptor = 0; uint16 size = sizeof(uint64) * this->size - 1; - uint32 offset = (uint32)((void *)(&gdt)); + uint32 offset = (uint32)(&gdt); - pointer |= offset; - pointer <<= 16; - pointer |= size; + descriptor |= offset; + descriptor <<= 16; + descriptor |= size; - SWITCHTOGDT(pointer); + SWITCHTOGDT(descriptor); - isGdtLoaded = 1; + gdtLoaded = 1; return true; }; -bool MngGdt::getIsGdtLoaded() +// Get static instance of MngGdt initialized once +MngGdt &MngGdt::getInstance() { - return isGdtLoaded; + if(!isInitialize) mngGdt = MngGdt(); + return mngGdt; }; -void MngGdt::operator=(const MngGdt& src) +uint16 MngGdt::getCodeSegmentKernel() { - if(this->isGdtLoaded == 1 || src.isGdtLoaded == 1) - { - return; - } - - // Fix it. Write method to copy from ... to ... - for(int i = 0; i < this->size; i++) this->gdt[i] = src.gdt[i]; - this->isGdtLoaded = src.isGdtLoaded; - this->currIdx = src.currIdx; + return codeSegmentKern; }; diff --git a/arch/x86/gdt/Gdt.h b/arch/x86/gdt/Gdt.h index 6667d93..321d67c 100755 --- a/arch/x86/gdt/Gdt.h +++ b/arch/x86/gdt/Gdt.h @@ -2,6 +2,7 @@ #define GDT_H #include <types.h> +#include <MemoryOperations.h> // Define access options @@ -59,7 +60,7 @@ class DescSeg32 // Segment descriptor #ifdef __cplusplus extern "C" { #endif -extern void SWITCHTOGDT(uint64 pointer); +extern void SWITCHTOGDT(uint64 descriptor); #ifdef __cplusplus }; #endif @@ -67,17 +68,23 @@ extern void SWITCHTOGDT(uint64 pointer); class MngGdt { private: - const static uint8 size = 10; - static uint64 gdt[size]; - uint8 currIdx; - bool isGdtLoaded; + const static uint8 size = 10; + static uint64 gdt[size]; + static bool isInitialize; + static bool gdtLoaded; + uint16 codeSegmentKern; + uint8 currIdx; + MngGdt &operator=(const MngGdt &) = default; public: - MngGdt(); - void operator=(const MngGdt& src); - bool addDescriptor(uint64 desc); // 0 - not set descriptor, 1 - set - bool loadGdt(); // 0 - if GDT is not loaded, 1 - loaded - bool getIsGdtLoaded(); + MngGdt(); + MngGdt(const MngGdt &) = delete; + bool addDescriptor(uint64 desc); // 0 - not set descriptor, 1 - set + bool loadGdt(); // 0 - if GDT is not loaded, 1 - loaded + uint16 getCodeSegmentKernel(); + static MngGdt &getInstance(); }; +extern MngGdt mngGdt; + #endif diff --git a/arch/x86/idt/Idt.cpp b/arch/x86/idt/Idt.cpp new file mode 100644 index 0000000..d489f0e --- /dev/null +++ b/arch/x86/idt/Idt.cpp @@ -0,0 +1,130 @@ +#include "Idt.h" + + +uint64 MngIdt::idt[MngIdt::size]; +bool MngIdt::isInitialize = false; +bool MngIdt::idtLoaded = false; +MngIdt mngIdt; + +DescInterrupt32::DescInterrupt32(uint32 offset, uint16 selector, uint8 attr) +{ + uint8 gateType = attr & 0x0f; + + if((gateType == TSK_GATE and offset != 0) + or gateType < TSK_GATE + or (gateType > TRAP_GATE_16 and gateType < INT_GATE_32) + or gateType > TRAP_GATE_32 + or !(attr & PRESENT_BIT)) + { + offsetLow = 0; + offsetHight = 0; + segmentSelector = 0; + attributes = 0; + } + else + { + offsetLow = offset & 0xffff; + offsetHight = (offset & 0xffff0000) >> 16; + segmentSelector = selector; + attributes = attr; + } +}; + +uint64 DescInterrupt32::getDescriptor() +{ + uint64 desc = 0; + + desc |= offsetLow; + desc |= (uint32)segmentSelector << 16; + desc |= (uint64)attributes << 40; + desc |= (uint64)offsetHight << 48; + + return desc; +}; + +DescInterrupt32 DescInterrupt32::InterruptKernelLong(uint32 offset, uint16 selector) +{ + return DescInterrupt32( + offset, + selector, + PRESENT_BIT | RING_KERN | INT_GATE_32 + ); +}; + +DescInterrupt32 DescInterrupt32::TrapKernelLong(uint32 offset, uint16 selector) +{ + return DescInterrupt32( + offset, + selector, + PRESENT_BIT | RING_KERN | TRAP_GATE_32 + ); +}; + +DescInterrupt32 DescInterrupt32::TaskKernel(uint16 selector) +{ + return DescInterrupt32( + NULL, + selector, + PRESENT_BIT | RING_KERN | TSK_GATE + ); +}; + +MngIdt::MngIdt() +{ + if(!isInitialize) + { + MemoryOperations::set(idt, 0, sizeof(uint64) * size); + currIdx = NULL; + idtLoaded = false; + isInitialize = true; + } +}; + +bool MngIdt::canDescriptorWrite(uint8 idx) +{ + if(idt[idx] or idtLoaded) return false; + else return true; +}; + +bool MngIdt::addDescriptor(DescInterrupt32 desc) +{ + if(!canDescriptorWrite(currIdx)) return false; + + idt[currIdx++] = desc.getDescriptor(); + return true; +}; + +bool MngIdt::setDescriptor(DescInterrupt32 desc, uint8 idx) +{ + if(!canDescriptorWrite(idx)) return false; + + idt[idx] = desc.getDescriptor(); + return true; +}; + +bool MngIdt::loadIdt() +{ + if(idtLoaded) return false; + + //Set descriptor + uint64 descriptor = 0; + uint16 size = sizeof(uint64) * size - 1; + uint32 offset = (uint32)(&idt); + + descriptor |= offset; + descriptor <<= 16; + descriptor |= size; + + // Load descriptor in LDTR + asm ("lidt %0" :: "m"(descriptor)); + + idtLoaded = true; + return true; +}; + +// Get static instance of MngIdt initialized once +MngIdt &MngIdt::getInstance() +{ + if(!isInitialize) mngIdt = MngIdt(); + return mngIdt; +}; diff --git a/arch/x86/idt/Idt.h b/arch/x86/idt/Idt.h new file mode 100644 index 0000000..c90b674 --- /dev/null +++ b/arch/x86/idt/Idt.h @@ -0,0 +1,63 @@ +#ifndef IDT_H +#define IDT_H + + +#include "../gdt/Gdt.h" +#include <MemoryOperations.h> + +// Defines + +// Attributes +#define TSK_GATE 0x5 +#define INT_GATE_16 0x6 +#define TRAP_GATE_16 0x7 +#define INT_GATE_32 0xe +#define TRAP_GATE_32 0xf +#define PRESENT_BIT 0x80 +#define RING_KERN 0 +#define RING_DRIVERSH 0x20 +#define RING_DRIVERSL 0x40 +#define RING_APP 0x60 + +//-------- + +class DescInterrupt32 +{ + private: + uint16 offsetLow; + uint16 segmentSelector; + uint8 attributes; + uint16 offsetHight; + public: + DescInterrupt32() = default; + DescInterrupt32(const DescInterrupt32 &) = default; + DescInterrupt32(uint32 offset, uint16 selector, uint8 attr); + uint64 getDescriptor(); + static DescInterrupt32 InterruptKernelLong(uint32 offset, + uint16 selector); + static DescInterrupt32 TrapKernelLong(uint32 offset, + uint16 selector); + static DescInterrupt32 TaskKernel(uint16 selector); +}; + +class MngIdt +{ + private: + const static uint8 size = 255; + static uint64 idt[size]; + static bool isInitialize; + static bool idtLoaded; + uint8 currIdx; + public: + MngIdt(); + MngIdt(const MngIdt &) = delete; + bool addDescriptor(DescInterrupt32 desc); + bool setDescriptor(DescInterrupt32 desc, uint8 idx); + bool canDescriptorWrite(uint8 idx); + bool loadIdt(); + static MngIdt &getInstance(); +}; + +extern MngIdt mngIdt; + +#endif diff --git a/include/types.h b/include/types.h index f7c0eb6..9fef833 100644 --- a/include/types.h +++ b/include/types.h @@ -12,7 +12,7 @@ typedef unsigned short int uint16; typedef unsigned long uint32; typedef unsigned long long uint64; -#if defined(__x86_64) +#if defined(__x86_64) || defined(__i686) typedef uint64 uintptr; #else typedef uint32 uintptr; diff --git a/kernel/boot.s b/kernel/boot.s index 987cb48..710bb7b 100644 --- a/kernel/boot.s +++ b/kernel/boot.s @@ -10,6 +10,7 @@ align 4 section .bss align 16 +resb 160 stack_bottom: resb 16384 stack_top: @@ -20,6 +21,7 @@ global _start:function (_start.end - _start) _start: mov esp, stack_top call main + int 0x20 cli .hang: hlt jmp .hang diff --git a/kernel/kernel.c b/kernel/kernel.c index 36fb0fd..09152b8 100644 --- a/kernel/kernel.c +++ b/kernel/kernel.c @@ -8,8 +8,8 @@ void main() { SecondaryInitialization init; - init.processorInitialize(); init.devicesInitialize(); + init.processorInitialize(); out::display << "Hello, World!\n"; Rsdp *rsdp = (Rsdp *)StringOperations::findInMemory(Rsdp::signatureString, @@ -29,6 +29,5 @@ void main() madt->getIcs(7), madt->getIcs(8)}; const IoapicStruct *ioapicStruct = (IoapicStruct *)icsEntry[1]; - out::display << '\n'; empty(); }; @@ -2,9 +2,9 @@ CC = i686-elf-g++ LD = ld ASM = nasm # test -O2 flag -CFLAGS = -c -m32 -Wall -ffreestanding -nostdinc -nostdlib +CFLAGS = -c -m32 -Wall -ffreestanding -nostdinc -nostdlib -fno-rtti AFLAGS = -f elf32 -LDFLAGS = -m elf_i386 $(patsubst %,-L%,$(subst :, ,$(LIBS_PATH))) -lgcc -lstdc++ +LDFLAGS = -m elf_i386 $(patsubst %,-L%,$(subst :, ,$(LIBS_PATH))) -lgcc QEMUFLAGS = CFILES = $(shell find ./ -type f \( -name \*.cpp -o -name \*.c \)) @@ -42,6 +42,7 @@ $(AFILES): startbuild: @echo $(OBJ_FILES) + rm -rf $(BDIR) mkdir $(BDIR) @echo "Compile source files..." |
