summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexey Gavrilov <rebovas@yahoo.com>2024-03-31 14:39:51 +0700
committerAlexey Gavrilov <rebovas@yahoo.com>2024-03-31 14:39:51 +0700
commit49cfee4e370892df8404e56d53b04dde196f82f2 (patch)
treed309b630a161823c79dab9a48f67a41a40d76b24
parenta276644952ed018e77ca64181059434a6bc4ee62 (diff)
IDT + uintptr update
-rw-r--r--arch/x86/PrimaryInit.cpp17
-rw-r--r--arch/x86/PrimaryInit.h1
-rwxr-xr-xarch/x86/gdt/Gdt.cpp60
-rwxr-xr-xarch/x86/gdt/Gdt.h27
-rw-r--r--arch/x86/idt/Idt.cpp130
-rw-r--r--arch/x86/idt/Idt.h63
-rw-r--r--include/types.h2
-rw-r--r--kernel/boot.s2
-rw-r--r--kernel/kernel.c3
-rw-r--r--makefile5
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();
};
diff --git a/makefile b/makefile
index 1b43240..ef46637 100644
--- a/makefile
+++ b/makefile
@@ -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..."