summaryrefslogtreecommitdiff
path: root/Source
diff options
context:
space:
mode:
Diffstat (limited to 'Source')
-rw-r--r--Source/Kernel/Core/.kmain.wtf.cpp.swpbin12288 -> 12288 bytes
-rw-r--r--Source/Kernel/Core/CMem.ns.h2
-rw-r--r--Source/Kernel/Core/Sys.ns.cpp16
-rw-r--r--Source/Kernel/Core/Sys.ns.h3
-rw-r--r--Source/Kernel/Core/common.wtf.h4
-rw-r--r--Source/Kernel/Core/cppsupport.wtf.cpp6
-rw-r--r--Source/Kernel/Core/kmain.wtf.cpp67
-rw-r--r--Source/Kernel/Core/loader.wtf.asm31
-rw-r--r--Source/Kernel/DeviceManager/Dev.ns.cpp51
-rw-r--r--Source/Kernel/DeviceManager/Dev.ns.h19
-rw-r--r--Source/Kernel/DeviceManager/Disp.ns.cpp (renamed from Source/Kernel/DisplayManager/Disp.ns.cpp)0
-rw-r--r--Source/Kernel/DeviceManager/Disp.ns.h (renamed from Source/Kernel/DisplayManager/Disp.ns.h)0
-rw-r--r--Source/Kernel/DeviceManager/Time.ns.cpp19
-rw-r--r--Source/Kernel/DeviceManager/Time.ns.h14
-rw-r--r--Source/Kernel/Devices/Device.proto.h16
-rw-r--r--Source/Kernel/Devices/Display/Display.proto.h3
-rw-r--r--Source/Kernel/Devices/Display/VGATextOutput.class.cpp9
-rw-r--r--Source/Kernel/Devices/Display/VGATextOutput.class.h3
-rw-r--r--Source/Kernel/Devices/Timer.class.cpp56
-rw-r--r--Source/Kernel/Devices/Timer.class.h26
-rw-r--r--Source/Kernel/Library/Bitset.class.cpp62
-rw-r--r--Source/Kernel/Library/Bitset.class.h31
-rw-r--r--Source/Kernel/Library/OrderedArray.class.cpp54
-rw-r--r--Source/Kernel/Library/OrderedArray.class.h29
-rw-r--r--Source/Kernel/Library/String.class.cpp261
-rw-r--r--Source/Kernel/Library/String.class.h47
-rw-r--r--Source/Kernel/Library/Vector.class.cpp103
-rw-r--r--Source/Kernel/Library/Vector.class.h35
-rw-r--r--Source/Kernel/Makefile17
-rw-r--r--Source/Kernel/Map.txt770
-rwxr-xr-xSource/Kernel/Melon.kebin21251 -> 47469 bytes
-rw-r--r--Source/Kernel/MemoryManager/GDT.ns.cpp34
-rw-r--r--Source/Kernel/MemoryManager/GDT.ns.h24
-rw-r--r--Source/Kernel/MemoryManager/GDT.wtf.asm17
-rw-r--r--Source/Kernel/MemoryManager/Mem.ns.cpp240
-rw-r--r--Source/Kernel/MemoryManager/Mem.ns.h24
-rw-r--r--Source/Kernel/MemoryManager/PageAlloc.ns.cpp68
-rw-r--r--Source/Kernel/MemoryManager/PageAlloc.ns.h12
-rw-r--r--Source/Kernel/MemoryManager/PageDirectory.class.cpp53
-rw-r--r--Source/Kernel/MemoryManager/PageDirectory.class.h35
-rw-r--r--Source/Kernel/MemoryManager/PhysMem.ns.cpp79
-rw-r--r--Source/Kernel/MemoryManager/PhysMem.ns.h19
-rw-r--r--Source/Kernel/Ressources/logo.cd14
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.cpp176
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.h32
-rw-r--r--Source/Kernel/SyscallManager/IDT.wtf.asm117
-rw-r--r--Source/Kernel/VTManager/VT.ns.cpp32
-rw-r--r--Source/Kernel/VTManager/VT.ns.h14
-rw-r--r--Source/Kernel/VTManager/VirtualTerminal.class.cpp18
-rw-r--r--Source/Kernel/VTManager/VirtualTerminal.class.h1
50 files changed, 2583 insertions, 180 deletions
diff --git a/Source/Kernel/Core/.kmain.wtf.cpp.swp b/Source/Kernel/Core/.kmain.wtf.cpp.swp
index bf1668b..27008ec 100644
--- a/Source/Kernel/Core/.kmain.wtf.cpp.swp
+++ b/Source/Kernel/Core/.kmain.wtf.cpp.swp
Binary files differ
diff --git a/Source/Kernel/Core/CMem.ns.h b/Source/Kernel/Core/CMem.ns.h
index 98e0b10..f0c15da 100644
--- a/Source/Kernel/Core/CMem.ns.h
+++ b/Source/Kernel/Core/CMem.ns.h
@@ -3,6 +3,8 @@
#ifndef DEF_CMEM_NS_H
#define DEF_CMEM_NS_H
+//This namespace contains basic memory managment functions
+
namespace CMem {
u8int *memcpy(u8int *dest, const u8int *src, int count);
u8int *memset(u8int *dest, u8int val, int count);
diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp
index 361dda6..5cd1c28 100644
--- a/Source/Kernel/Core/Sys.ns.cpp
+++ b/Source/Kernel/Core/Sys.ns.cpp
@@ -2,7 +2,7 @@
#include <Core/common.wtf.h>
#include <VTManager/VirtualTerminal.class.h>
-#define DEBUGVT(x) VirtualTerminal *x = new VirtualTerminal(5, 46, 0, 15); x->map(); x->put('\n');
+#define DEBUGVT(x) VirtualTerminal *x = new VirtualTerminal(4, 46, 0, 15); x->map(); x->put('\n');
using namespace CMem;
@@ -40,7 +40,15 @@ void bochs_output(char *message, char *file, u32int line) {
outb(0xE9, '\n');
}
-//TODO : make PANIC output a visible message
+void bochs_output_hex(u32int i) {
+ char hexdigits[] = "0123456789ABCDEF";
+ outb(0xE9, '0');
+ outb(0xE9, 'x');
+ for (u32int j = 0; j < 8; j++) {
+ outb(0xE9, hexdigits[(i & 0xF0000000) >> 28]);
+ i = i << 4;
+ }
+}
//Used by PANIC() macro (see common.wtf.h)
void panic(char *message, char *file, u32int line) {
@@ -49,7 +57,7 @@ void panic(char *message, char *file, u32int line) {
DEBUGVT(vt);
bochs_output("PANIC : ", file, line);
bochs_output(message, file, 0);
- *vt << " PANIC : " << message << "\n In " << file << ":" << (s32int)line << "\n";
+ *vt << " PANIC : " << message << "\n In " << file << ":" << (s32int)line;
while (1) asm volatile("hlt"); //Enter infinite loop for halt
}
@@ -61,7 +69,7 @@ void panic_assert(char *file, u32int line, char *desc) {
DEBUGVT(vt);
bochs_output("ASSERTION FAILED : ", file, line);
bochs_output(desc, file, 0);
- *vt << " ASSERTION FAILED : " << desc << "\n In " << file << ":" << (s32int)line << "\n";
+ *vt << " ASSERTION FAILED : " << desc << "\n In " << file << ":" << (s32int)line;
while (1) asm volatile("hlt"); //Enter infinite loop for halt
}
diff --git a/Source/Kernel/Core/Sys.ns.h b/Source/Kernel/Core/Sys.ns.h
index 9a2975e..69dcc42 100644
--- a/Source/Kernel/Core/Sys.ns.h
+++ b/Source/Kernel/Core/Sys.ns.h
@@ -4,6 +4,8 @@
#ifndef DEF_SYS_NS_H
#define DEF_SYS_NS_H
+//This file contains system-relative functions
+
namespace Sys {
void outb(u16int port, u8int value);
u8int inb(u16int port);
@@ -11,6 +13,7 @@ namespace Sys {
void panic(char* message, char *file, u32int line);
void panic_assert(char* file, u32int line, char *desc);
void bochs_output(char* message, char *file, u32int line);
+ void bochs_output_hex(u32int i);
void reboot();
}
diff --git a/Source/Kernel/Core/common.wtf.h b/Source/Kernel/Core/common.wtf.h
index 617a73c..86b0d9e 100644
--- a/Source/Kernel/Core/common.wtf.h
+++ b/Source/Kernel/Core/common.wtf.h
@@ -3,6 +3,8 @@
#include <Config.h>
+//This file is very important : it contains type definitions, macro definitions and new/delete implementations.
+
#define NULL 0
typedef unsigned int u32int;
@@ -20,8 +22,10 @@ typedef char s8int;
#ifdef OPT_DEBUG
#define DEBUG(m) Sys::bochs_output(m, __FILE__, __LINE__)
+#define DEBUG_HEX(m) Sys::bochs_output_hex(m);
#else
#define DEBUG(m)
+#define DEBUG_HEX(m)
#endif
#include <MemoryManager/Mem.ns.h>
diff --git a/Source/Kernel/Core/cppsupport.wtf.cpp b/Source/Kernel/Core/cppsupport.wtf.cpp
index 77feed3..d495dff 100644
--- a/Source/Kernel/Core/cppsupport.wtf.cpp
+++ b/Source/Kernel/Core/cppsupport.wtf.cpp
@@ -1,4 +1,6 @@
-extern "C" void __cxa_pure_virtual() {}
+//This file just contains a few methods required for some C++ things to work
-void *__dso_handle;
+extern "C" void __cxa_pure_virtual() {} //Required when using abstract classes
+
+void *__dso_handle; //Required when using global objects
extern "C" int __cxa_atexit(void (*f)(void*), void *p, void *d) { return 0; }
diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp
index e201a07..9e2004e 100644
--- a/Source/Kernel/Core/kmain.wtf.cpp
+++ b/Source/Kernel/Core/kmain.wtf.cpp
@@ -1,9 +1,18 @@
+//This file contains the kernel's main procedure
+
#include <Core/common.wtf.h>
#include <Core/multiboot.wtf.h>
#include <Devices/Display/VGATextOutput.class.h>
-#include <DisplayManager/Disp.ns.h>
+#include <Devices/Timer.class.h>
+#include <DeviceManager/Disp.ns.h>
+#include <DeviceManager/Dev.ns.h>
#include <VTManager/VirtualTerminal.class.h>
+#include <MemoryManager/PhysMem.ns.h>
+#include <MemoryManager/PageAlloc.ns.h>
+#include <MemoryManager/GDT.ns.h>
+#include <SyscallManager/IDT.ns.h>
+#include <Library/String.class.h>
#include <Ressources/logo.cd>
@@ -15,28 +24,68 @@ void kmain(multiboot_info_t* mbd, u32int magic) {
DEBUG("Entering kmain.");
Mem::placementAddress = (u32int)&end;
+ mbd->cmdline += 0xC0000000; mbd->mods_addr += 0xC0000000; //Take stuff into acount
+ module_t *mods = (module_t*)mbd->mods_addr;
+ for (u32int i = 0; i < mbd->mods_count; i++) {
+ mods[i].mod_start += 0xC0000000;
+ mods[i].mod_end += 0xC0000000;
+ if (mods[i].mod_end > Mem::placementAddress)
+ Mem::placementAddress = mods[i].mod_end + 0x1000;
+ }
VGATextOutput *vgaout = new VGATextOutput();
Disp::setDisplay(vgaout);
+ if (magic != MULTIBOOT_BOOTLOADER_MAGIC) {
+ PANIC("Error with multiboot header.");
+ }
+
+ VirtualTerminal *melonLogoVT = new VirtualTerminal(melonLogoLines, melonLogoCols, 7, 0);
for (int i = 0; i < melonLogoLines; i++) {
- int startCol = (Disp::textCols() / 2) - (melonLogoCols / 2);
for (int j = 0; j < melonLogoCols; j++) {
- Disp::putChar(i + 2, j + startCol, melonLogo[i][j], 0x07);
+ melonLogoVT->putChar(i, j, melonLogo[i][j]);
}
}
+ melonLogoVT->map(2);
VirtualTerminal *kvt = new VirtualTerminal(12, 40, 0, 2);
kvt->map(melonLogoLines + 4);
- *kvt << "Kernel initializing in HIGHER HALF!\n";
+ *kvt << "* Kernel initializing in HIGHER HALF!\n";
- *kvt << "Lower ram : " << (s32int)mbd->mem_lower << "k, upper : " << (s32int)mbd->mem_upper << "k.\n";
+ *kvt << "- Lower ram : " << (s32int)mbd->mem_lower << "k, upper : " << (s32int)mbd->mem_upper << "k.\n";
+ *kvt << "- Kernel command line : " << (u32int)mbd->cmdline << "\n";
+ *kvt << "- Modules@" << (u32int)mbd->mods_addr << ", mbd@" << (u32int)mbd << "\n";
+ *kvt << "- Placement address : " << (u32int)Mem::placementAddress << "\n";
- if (magic != MULTIBOOT_BOOTLOADER_MAGIC) {
- PANIC("Error with multiboot header.");
- }
+ *kvt << "> Loading IDT...";
+ IDT::init();
+
+ *kvt << "OK.\n> Initializing paging...";
+ u32int totalRam = ((mbd->mem_upper + 1024) * 1024);
+ PhysMem::initPaging(totalRam);
+
+ *kvt << "OK.\n- Total ram : " << (s32int)(totalRam / 1024) << "k.\n";
+ GDT::init();
+ *kvt << "> GDT OK. Cleaning page directory...";
+ PhysMem::removeTemporaryPages();
+
+ *kvt << "OK.\n> Creating heap...";
+ Mem::createHeap();
+ *kvt << "OK.\n";
+ *kvt << "- Free frames : " << (s32int)PhysMem::free() << "/" <<
+ (s32int)PhysMem::total();
+
+ *kvt << "\n> Registering vgaout...";
+ Dev::registerDevice(vgaout);
+
+ *kvt << "OK.\n> Initializing PIT...";
+ Dev::registerDevice(new Timer());
+
+ *kvt << "OK.\n";
+
+ asm volatile("sti");
- while(1);
+ //PANIC("END OF KMAIN");
}
diff --git a/Source/Kernel/Core/loader.wtf.asm b/Source/Kernel/Core/loader.wtf.asm
index c5248e9..8d7b076 100644
--- a/Source/Kernel/Core/loader.wtf.asm
+++ b/Source/Kernel/Core/loader.wtf.asm
@@ -1,5 +1,5 @@
-global loader ; making entry point visible to linker
-extern kmain ; kmain is defined elsewhere
+[GLOBAL loader] ; making entry point visible to linker
+[EXTERN kmain] ; kmain is defined in kmain.wtf.cpp
; setting up the Multiboot header - see GRUB docs for details
MODULEALIGN equ 1<<0 ; align loaded modules on page boundaries
@@ -18,9 +18,9 @@ MultiBootHeader:
; reserve initial kernel stack space
STACKSIZE equ 0x4000 ; that's 16k.
-extern start_ctors, end_ctors, start_dtors, end_dtors
+extern start_ctors, end_ctors, start_dtors, end_dtors ; these are required for global objects
-loader:
+loader: ;here, we load our false GDT, used for having the kernel in higher half
lgdt [trickgdt]
mov cx, 0x10;
mov ds, cx;
@@ -32,13 +32,14 @@ loader:
jmp 0x08:higherhalf
-higherhalf:
+higherhalf: ; now we're running in higher half
+
mov esp, stack+STACKSIZE ; set up the stack
push eax ; pass Multiboot magic number
add ebx, 0xC0000000 ; update the MB info structure so that it is in the new seg.
push ebx ; pass Multiboot info structure
-static_ctors_loop:
+static_ctors_loop: ; construct global objects
mov ebx, start_ctors
jmp .test
.body:
@@ -50,10 +51,10 @@ static_ctors_loop:
call kmain ; call kernel proper
- cli
+ cli ; disable interuptions
static_dtors_loop: ; useless, kernel should never return
- mov ebx, start_dtors
+ mov ebx, start_dtors ; destruct global objects
jmp .test
.body:
call [ebx]
@@ -66,16 +67,16 @@ hang:
hlt ; halt machine should kernel return
jmp hang
-[section .setup]
+[section .setup] ; this is included in the .setup section, so that it thinks it is at 0x00100000
-trickgdt:
- dw gdt_end - gdt - 1
- dd gdt
+trickgdt: ; our false GDT
+ dw gdt_end - gdt - 1 ; gdt limit
+ dd gdt ; gdt base
gdt:
- dd 0, 0
- db 0xFF, 0xFF, 0, 0, 0, 10011010b, 11001111b, 0x40
- db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x40
+ dd 0, 0 ; null GDT entry
+ db 0xFF, 0xFF, 0, 0, 0, 10011010b, 11001111b, 0x40 ; kernel code segment
+ db 0xFF, 0xFF, 0, 0, 0, 10010010b, 11001111b, 0x40 ; kernel data segment
gdt_end:
diff --git a/Source/Kernel/DeviceManager/Dev.ns.cpp b/Source/Kernel/DeviceManager/Dev.ns.cpp
new file mode 100644
index 0000000..71ac3c7
--- /dev/null
+++ b/Source/Kernel/DeviceManager/Dev.ns.cpp
@@ -0,0 +1,51 @@
+#include "Dev.ns.h"
+
+namespace Dev {
+
+Vector<Device*> devices;
+Device* irqHandler[16] = { NULL };
+
+void handleIRQ(registers_t *regs, int irq) {
+ if (irqHandler[irq] != NULL)
+ irqHandler[irq]->handleIRQ(regs, irq);
+}
+
+void registerDevice(Device* dev) {
+ unregisterDevice(dev); //Bad things could have happened
+ devices.push(dev);
+}
+
+void unregisterDevice(Device* dev) {
+ for (u32int i = 0; i < devices.size(); i++) {
+ if (devices[i] == dev) {
+ devices[i] = devices.back();
+ devices.pop();
+ return;
+ }
+ }
+}
+
+bool requestIRQ(Device* dev, int irq) {
+ if (irqHandler[irq] == NULL) {
+ irqHandler[irq] = dev;
+ return true;
+ } else {
+ return false;
+ }
+}
+
+Vector<Device*> findDevice(String _class) {
+ if (_class.empty()) return devices;
+ Vector<Device*> ret;
+ for (u32int i = 0; i < devices.size(); i++) {
+ String devclass = devices[i]->getClass();
+ if (devclass == _class) {
+ ret.push(devices[i]);
+ } else if (devclass.size() > _class.size()) {
+ if (devclass.substr(0, _class.size()) == _class) ret.push(devices[i]);
+ }
+ }
+ return ret;
+}
+
+}
diff --git a/Source/Kernel/DeviceManager/Dev.ns.h b/Source/Kernel/DeviceManager/Dev.ns.h
new file mode 100644
index 0000000..c2651c2
--- /dev/null
+++ b/Source/Kernel/DeviceManager/Dev.ns.h
@@ -0,0 +1,19 @@
+#ifndef DEF_DEV_NS_H
+#define DEF_DEV_NS_H
+
+#include <Devices/Device.proto.h>
+#include <Library/Vector.class.h>
+
+namespace Dev {
+ void handleIRQ(registers_t *regs, int irq);
+
+ void registerDevice(Device* dev);
+ void unregisterDevice(Device* dev);
+
+ bool requestIRQ(Device* dev, int irq);
+
+ Vector<Device*> findDevice(String _class = "");
+}
+
+#endif
+
diff --git a/Source/Kernel/DisplayManager/Disp.ns.cpp b/Source/Kernel/DeviceManager/Disp.ns.cpp
index 8db9503..8db9503 100644
--- a/Source/Kernel/DisplayManager/Disp.ns.cpp
+++ b/Source/Kernel/DeviceManager/Disp.ns.cpp
diff --git a/Source/Kernel/DisplayManager/Disp.ns.h b/Source/Kernel/DeviceManager/Disp.ns.h
index a815836..a815836 100644
--- a/Source/Kernel/DisplayManager/Disp.ns.h
+++ b/Source/Kernel/DeviceManager/Disp.ns.h
diff --git a/Source/Kernel/DeviceManager/Time.ns.cpp b/Source/Kernel/DeviceManager/Time.ns.cpp
new file mode 100644
index 0000000..104db1d
--- /dev/null
+++ b/Source/Kernel/DeviceManager/Time.ns.cpp
@@ -0,0 +1,19 @@
+#include "Time.ns.h"
+
+namespace Time {
+
+Timer* timer;
+
+void setTimer(Timer* t) {
+ timer = t;
+}
+
+u32int uptime() {
+ return timer->uptime();
+}
+
+u32int time() {
+ return timer->time();
+}
+
+}
diff --git a/Source/Kernel/DeviceManager/Time.ns.h b/Source/Kernel/DeviceManager/Time.ns.h
new file mode 100644
index 0000000..6b8a40f
--- /dev/null
+++ b/Source/Kernel/DeviceManager/Time.ns.h
@@ -0,0 +1,14 @@
+#ifndef DEF_TIME_NS_H
+#define DEF_TIME_NS_H
+
+#include <Devices/Timer.class.h>
+
+namespace Time {
+ void setTimer(Timer* t);
+
+ u32int uptime();
+ u32int time();
+}
+
+
+#endif
diff --git a/Source/Kernel/Devices/Device.proto.h b/Source/Kernel/Devices/Device.proto.h
new file mode 100644
index 0000000..fa31b06
--- /dev/null
+++ b/Source/Kernel/Devices/Device.proto.h
@@ -0,0 +1,16 @@
+#ifndef DEF_DEVICE_PROTO_H
+#define DEF_DEVICE_PROTO_H
+
+#include <Library/String.class.h>
+
+#include <SyscallManager/IDT.ns.h>
+
+class Device {
+ public:
+ virtual String getClass() = 0;
+ virtual String getName() = 0;
+
+ virtual void handleIRQ(registers_t *regs, int irq) {};
+};
+
+#endif
diff --git a/Source/Kernel/Devices/Display/Display.proto.h b/Source/Kernel/Devices/Display/Display.proto.h
index d91023a..1c8e724 100644
--- a/Source/Kernel/Devices/Display/Display.proto.h
+++ b/Source/Kernel/Devices/Display/Display.proto.h
@@ -2,8 +2,9 @@
#define DEF_DISPLAY_PROTO_H
#include <Core/common.wtf.h>
+#include <Devices/Device.proto.h>
-class Display {
+class Display : public Device {
public:
virtual u16int textCols() = 0;
virtual u16int textRows() = 0;
diff --git a/Source/Kernel/Devices/Display/VGATextOutput.class.cpp b/Source/Kernel/Devices/Display/VGATextOutput.class.cpp
index 28c943a..a424153 100644
--- a/Source/Kernel/Devices/Display/VGATextOutput.class.cpp
+++ b/Source/Kernel/Devices/Display/VGATextOutput.class.cpp
@@ -1,9 +1,18 @@
#include "VGATextOutput.class.h"
+//Virtual address in higher half
#define RAM_ADDR 0xC00B8000
using namespace Sys; //For outb
+String VGATextOutput::getClass() {
+ return "display.text";
+}
+
+String VGATextOutput::getName() {
+ return "Standard mode0 VGA text display";
+}
+
u16int VGATextOutput::textCols() {
return 80;
}
diff --git a/Source/Kernel/Devices/Display/VGATextOutput.class.h b/Source/Kernel/Devices/Display/VGATextOutput.class.h
index a7968c7..eb3fc99 100644
--- a/Source/Kernel/Devices/Display/VGATextOutput.class.h
+++ b/Source/Kernel/Devices/Display/VGATextOutput.class.h
@@ -5,6 +5,9 @@
class VGATextOutput : public Display {
public:
+ String getClass();
+ String getName();
+
u16int textCols();
u16int textRows();
void putChar(u16int line, u16int col, char c, u8int color);
diff --git a/Source/Kernel/Devices/Timer.class.cpp b/Source/Kernel/Devices/Timer.class.cpp
new file mode 100644
index 0000000..42a6d1c
--- /dev/null
+++ b/Source/Kernel/Devices/Timer.class.cpp
@@ -0,0 +1,56 @@
+#include "Timer.class.h"
+
+#include <DeviceManager/Dev.ns.h>
+#include <DeviceManager/Time.ns.h>
+
+using namespace Sys; //For outb
+
+Timer::Timer(u8int frequency) {
+ m_ticks = 0;
+ m_seconds = 0;
+
+ Dev::requestIRQ(this, 0);
+ Time::setTimer(this);
+ setFrequency(frequency);
+}
+
+String Timer::getClass() {
+ return String("timer");
+}
+
+String Timer::getName() {
+ return String("Programmable interrupt timer");
+}
+
+void Timer::setFrequency(u8int frequency) {
+ m_frequency = frequency;
+ u32int divisor = 1193180 / (u32int)frequency;
+ outb(0x43, 0x36);
+
+ u8int l = (u8int)(divisor & 0xFF);
+ u8int h = (u8int)( (divisor >> 8) & 0xFF);
+
+ outb(0x40, l);
+ outb(0x40, h);
+}
+
+u32int Timer::uptime() {
+ return m_seconds;
+}
+
+u32int Timer::time() {
+ return (m_seconds * 1000) + ((m_ticks * 1000) / m_frequency);
+}
+
+void Timer::handleIRQ(registers_t registers, int irq) {
+ if (irq == 0) {
+ m_ticks++;
+ if (m_ticks == m_frequency) {
+ m_ticks = 0;
+ m_seconds++;
+ }
+ //Switching task is called in Dev::handleInterrupt
+ }
+}
+
+
diff --git a/Source/Kernel/Devices/Timer.class.h b/Source/Kernel/Devices/Timer.class.h
new file mode 100644
index 0000000..187a7e9
--- /dev/null
+++ b/Source/Kernel/Devices/Timer.class.h
@@ -0,0 +1,26 @@
+#ifndef DEF_TIMER_CLASS
+#define DEF_TIMER_CLASS
+
+#include <Devices/Device.proto.h>
+
+class Timer : public Device {
+ private:
+ u8int m_frequency;
+ u8int m_ticks;
+ u32int m_seconds;
+
+ public:
+ Timer(u8int frequency = 100);
+
+ void setFrequency(u8int frequency);
+
+ String getClass();
+ String getName();
+
+ u32int uptime();//Returns seconds since init
+ u32int time(); //Returns miliseconds since init
+
+ void handleIRQ(registers_t registers, int irq);
+};
+
+#endif
diff --git a/Source/Kernel/Library/Bitset.class.cpp b/Source/Kernel/Library/Bitset.class.cpp
new file mode 100644
index 0000000..ec4e62c
--- /dev/null
+++ b/Source/Kernel/Library/Bitset.class.cpp
@@ -0,0 +1,62 @@
+#include "Bitset.class.h"
+
+Bitset::Bitset() {
+}
+
+Bitset::Bitset(u32int size) {
+ init(size, (u32int*)Mem::kalloc(INDEX_FROM_BIT(size)));
+}
+
+Bitset::Bitset(u32int size, u32int *ptr) {
+ init(size, ptr);
+}
+
+Bitset::~Bitset() {
+ Mem::kfree(m_data);
+}
+
+void Bitset::init(u32int size, u32int *ptr) {
+ m_size = size;
+ m_data = ptr;
+ for (u32int i = 0; i < INDEX_FROM_BIT(m_size); i++) {
+ m_data[i] = 0;
+ }
+ m_usedCount = 0;
+}
+
+void Bitset::setBit(u32int number) {
+ u32int idx = INDEX_FROM_BIT(number);
+ u32int off = OFFSET_FROM_BIT(number);
+ m_data[idx] |= (0x1 << off);
+ m_usedCount++;
+}
+
+void Bitset::clearBit(u32int number) {
+ u32int idx = INDEX_FROM_BIT(number);
+ u32int off = OFFSET_FROM_BIT(number);
+ m_data[idx] &= ~(0x1 << off);
+ m_usedCount--;
+}
+
+bool Bitset::testBit(u32int number) {
+ u32int idx = INDEX_FROM_BIT(number);
+ u32int off = OFFSET_FROM_BIT(number);
+ return (m_data[idx] & (0x1 << off));
+}
+
+u32int Bitset::firstFreeBit() {
+ for (u32int i = 0; i < INDEX_FROM_BIT(m_size); i++) {
+ if (m_data[i] != 0xFFFFFFFF) {
+ for (int j = 0; j < 32; j++) {
+ if (!(m_data[i] & (0x1 << j))) {
+ return (i * 4 * 8) + j;
+ }
+ }
+ }
+ }
+ return (u32int) - 1;
+}
+
+u32int Bitset::usedBits() {
+ return m_usedCount;
+}
diff --git a/Source/Kernel/Library/Bitset.class.h b/Source/Kernel/Library/Bitset.class.h
new file mode 100644
index 0000000..75fde24
--- /dev/null
+++ b/Source/Kernel/Library/Bitset.class.h
@@ -0,0 +1,31 @@
+#ifndef DEF_BITSET_CLASS_H
+#define DEF_BITSET_CLASS_H
+
+#include <Core/common.wtf.h>
+
+#define INDEX_FROM_BIT(a) (a/(8*4))
+#define OFFSET_FROM_BIT(a) (a%(8*4))
+
+class Bitset {
+ private:
+ u32int m_size;
+ u32int *m_data;
+ u32int m_usedCount;
+
+ public:
+ Bitset();
+ Bitset(u32int size);
+ Bitset(u32int size, u32int *ptr);
+ ~Bitset();
+
+ void init(u32int size, u32int *ptr);
+
+ void setBit(u32int number);
+ void clearBit(u32int number);
+ bool testBit(u32int number);
+ u32int firstFreeBit();
+
+ u32int usedBits();
+};
+
+#endif
diff --git a/Source/Kernel/Library/OrderedArray.class.cpp b/Source/Kernel/Library/OrderedArray.class.cpp
new file mode 100644
index 0000000..8b8f24f
--- /dev/null
+++ b/Source/Kernel/Library/OrderedArray.class.cpp
@@ -0,0 +1,54 @@
+template <typename T>
+OrderedArray<T>::OrderedArray(u32int max_size) {
+ m_array = (T*)Memory::alloc(max_size * sizeof(T*));
+ m_size = 0;
+ m_maxSize = max_size;
+}
+
+template <typename T>
+OrderedArray<T>::OrderedArray(T **addr, u32int max_size) {
+ m_array = addr;
+ memset((u8int*)addr, 0, max_size * sizeof(T*));
+ m_size = 0;
+ m_maxSize = max_size;
+}
+
+template <typename T>
+OrderedArray<T>::~OrderedArray() {
+ //Free memory
+}
+
+template <typename T>
+void OrderedArray<T>::insert(T *element) {
+ if (m_size == m_maxSize) return; //Array is full
+ u32int iterator = 0;
+ while (iterator < m_size && *(m_array[iterator]) < *element) {
+ iterator++;
+ }
+ if (iterator == m_size) {
+ m_array[m_size++] = element;
+ } else {
+ u32int pos = iterator;
+ while (iterator < m_size) {
+ iterator++;
+ m_array[iterator] = m_array[iterator - 1];
+ }
+ m_size++;
+ m_array[pos] = element;
+ }
+}
+
+template <typename T>
+T *OrderedArray<T>::lookup(int index) {
+ return m_array[index];
+}
+
+template <typename T>
+void OrderedArray<T>::remove(int index) {
+ m_size--;
+ while (index < m_size) {
+ m_array[index] = m_array[index + 1];
+ index++;
+ }
+}
+
diff --git a/Source/Kernel/Library/OrderedArray.class.h b/Source/Kernel/Library/OrderedArray.class.h
new file mode 100644
index 0000000..2a5acdd
--- /dev/null
+++ b/Source/Kernel/Library/OrderedArray.class.h
@@ -0,0 +1,29 @@
+#ifndef DEF_ORDARRAY_CLASS
+#define DEF_ORDARRAY_CLASS
+
+#include <Core/common.wtf.h>
+
+template <typename T>
+class OrderedArray {
+ private:
+ T *m_array[];
+ u32int m_size;
+ u32int m_maxSize;
+
+ public:
+ OrderedArray(u32int max_size);
+ OrderedArray(T **addr, u32int max_size);
+ ~OrderedArray();
+
+ u32int size() { return m_size; }
+
+ void insert(T *element);
+ T *lookup(int index);
+ void remove(int index);
+
+ T *operator[] (int index) { return lookup(index); }
+};
+
+#include "OrderedArray.class.cpp"
+
+#endif
diff --git a/Source/Kernel/Library/String.class.cpp b/Source/Kernel/Library/String.class.cpp
new file mode 100644
index 0000000..dc763bd
--- /dev/null
+++ b/Source/Kernel/Library/String.class.cpp
@@ -0,0 +1,261 @@
+#include "String.class.h"
+#include <Library/Vector.class.h>
+
+using namespace CMem; //strlen and memcpy
+
+String String::hex(u32int number) {
+ String ret;
+ ret.m_length = 10;
+ ret.m_string = (char*)Mem::kalloc(11);
+ ret.m_string[0] = '0';
+ ret.m_string[1] = 'x';
+ ret.m_string[10] = 0;
+
+ char hexdigits[] = "0123456789ABCDEF";
+ for (unsigned int j = 0; j < 8; j++) {
+ ret.m_string[j + 2] = hexdigits[(number & 0xF0000000) >> 28];
+ number = number << 4;
+ }
+ return ret;
+}
+
+String String::number(s32int number) {
+ if (number == 0) return String("0");
+ bool negative = false;
+ if (number < 0) {
+ negative = true;
+ number = 0 - number;
+ }
+ u32int order = 0, temp = number;
+ char numbers[] = "0123456789";
+ while (temp > 0) {
+ order++;
+ temp /= 10;
+ }
+
+ String ret;
+ ret.m_length = order;
+ ret.m_string = (char*)Mem::kalloc(order + 1);
+
+ for (u32int i = order; i > 0; i--) {
+ ret.m_string[i - 1] = numbers[number % 10];
+ number /= 10;
+ }
+
+ ret.m_string[order] = 0;
+
+ if (negative) return String("-") += ret;
+
+ return ret;
+}
+
+String::String() {
+ m_string = 0;
+ m_length = 0;
+}
+
+String::String(char* string) {
+ m_length = strlen(string);
+ m_string = (char*)Mem::kalloc(m_length + 1);
+ for (u32int i = 0; i < m_length; i++) {
+ m_string[i] = string[i];
+ }
+ m_string[m_length] = 0;
+}
+
+String::String(const String &other) {
+ m_length = other.m_length;
+ m_string = (char*)Mem::kalloc(m_length + 1);
+ for (u32int i = 0; i < m_length; i++) {
+ m_string[i] = other.m_string[i];
+ }
+ m_string[m_length] = 0;
+}
+
+String::~String() {
+ if (m_string != 0) Mem::kfree(m_string);
+}
+
+void String::operator= (const String &other) {
+ m_length = other.m_length;
+ if (m_string != 0) Mem::kfree(m_string);
+ m_string = (char*)Mem::kalloc(m_length + 1);
+ for (u32int i = 0; i < m_length; i++) {
+ m_string[i] = other.m_string[i];
+ }
+ m_string[m_length] = 0;
+}
+
+void String::operator= (char* string) {
+ m_length = strlen(string);
+ if (m_string != 0) Mem::kfree(m_string);
+ m_string = (char*)Mem::kalloc(m_length + 1);
+ for (u32int i = 0; i < m_length; i++) {
+ m_string[i] = string[i];
+ }
+ m_string[m_length] = 0;
+}
+
+bool String::operator== (String &other) {
+ if (m_length != other.m_length) return false;
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] != other.m_string[i]) return false;
+ }
+ return true;
+}
+
+bool String::operator== (char* string) {
+ if (m_length != strlen(string)) return false;
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] != string[i]) return false;
+ }
+ return true;
+}
+
+String& String::operator+= (String &other) {
+ char* newdata = (char*)Mem::kalloc(m_length + other.m_length + 1);
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ for (u32int i = 0; i < other.m_length; i++) {
+ newdata[i + m_length] = other.m_string[i];
+ }
+ if (m_string != 0) Mem::kfree(m_string);
+ m_string = newdata;
+ m_length += other.m_length;
+ m_string[m_length] = 0;
+ return *this;
+}
+
+String& String::operator+= (char* other) {
+ char* newdata = (char*)Mem::kalloc(m_length + strlen(other) + 1);
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ for (u32int i = 0; i < strlen(other); i++) {
+ newdata[i + m_length] = other[i];
+ }
+ if (m_string != 0) Mem::kfree(m_string);
+ m_string = newdata;
+ m_length += strlen(other);
+ m_string[m_length] = 0;
+ return *this;
+}
+
+String& String::operator+= (char other) {
+ char* newdata = (char*)Mem::kalloc(m_length + 2);
+ for (u32int i = 0; i < m_length; i++) {
+ newdata[i] = m_string[i];
+ }
+ if (m_string != 0) Mem::kfree(m_string);
+ m_string = newdata;
+ m_string[m_length] = other;
+ m_length++;
+ m_string[m_length] = 0;
+ return *this;
+}
+
+String& String::operator+ (String &other) { //Can be optimized
+ String ret(*this);
+ return (ret += other);
+}
+
+String& String::operator+ (char* other) { //Can be optimized
+ String ret(*this);
+ return (ret += other);
+}
+
+String& String::operator+ (char other) { //Can be optimized
+ String ret(*this);
+ return (ret += other);
+}
+
+String::operator char* () {
+ if (m_string == 0) return "";
+ return m_string;
+}
+
+s32int String::toInt() {
+ if (m_string == 0) return 0;
+ s32int pos = 0, number = 0;
+ bool negative = false;
+ if (m_string[0] == '-') {
+ negative = true;
+ pos = 1;
+ }
+ while (m_string[pos] >= '0' && m_string[pos] <= '9') {
+ number *= 10;
+ number += (m_string[pos] - '0');
+ pos++;
+ }
+ if (negative) return 0 - number;
+ return number;
+}
+
+u32int String::toInt16() {
+ if (m_string == 0) return 0;
+ u32int pos = 0, number = 0;
+ if (m_string[0] == '0' && m_string[1] == 'x') pos = 2;
+ while (1) {
+ char c = m_string[pos];
+ pos++;
+ if (c >= 'a' && c <= 'f') c -= ('a' - 'A'); //To uppercase
+ if (c >= '0' && c <= '9') {
+ number *= 16;
+ number += (c - '0');
+ continue;
+ }
+ if (c >= 'A' && c <= 'F') {
+ number *= 16;
+ number += (c - 'A' + 10);
+ continue;
+ }
+ break;
+ }
+ return number;
+}
+
+char& String::operator[] (int index) {
+ return m_string[index];
+}
+
+u32int String::size() {
+ return m_length;
+}
+
+void String::clear() {
+ Mem::kfree(m_string);
+ m_length = 0;
+ m_string = 0;
+}
+
+bool String::empty() {
+ return (m_length == 0);
+}
+
+Vector<String> String::split(char c) {
+ Vector<String> ret;
+ ret.push(String(""));
+ for (u32int i = 0; i < m_length; i++) {
+ if (m_string[i] == c) {
+ ret.push(String(""));
+ } else {
+ ret.back() += m_string[i];
+ }
+ }
+ return ret;
+}
+
+String String::substr(s32int start, s32int size) {
+ if (start < 0) start = m_length - start;
+ if (size < 0) { //this fucks
+ start = start + size;
+ size = 0 - size;
+ }
+ String ret;
+ ret.m_string = (char*)Mem::kalloc(size + 1);
+ ret.m_length = size;
+ memcpy((u8int*)ret.m_string, (const u8int*)(m_string + start), size);
+ ret.m_string[size] = 0;
+ return ret;
+}
diff --git a/Source/Kernel/Library/String.class.h b/Source/Kernel/Library/String.class.h
new file mode 100644
index 0000000..58237f0
--- /dev/null
+++ b/Source/Kernel/Library/String.class.h
@@ -0,0 +1,47 @@
+#ifndef DEF_STRING_CLASS
+#define DEF_STRING_CLASS
+
+#include <Core/common.wtf.h>
+
+template <typename T> class Vector;
+
+class String {
+ private:
+ char *m_string;
+ u32int m_length;
+
+ public:
+ static String hex(u32int number);
+ static String number(s32int number);
+
+ String(char* string);
+ String();
+ String(const String &other);
+ ~String();
+
+ void operator= (const String &other);
+ void operator= (char* string);
+
+ bool operator== (String &other);
+ bool operator== (char* string);
+ String &operator+= (String &other);
+ String &operator+= (char* other);
+ String &operator+= (char other);
+ String &operator+ (String &other);
+ String &operator+ (char* other);
+ String &operator+ (char other);
+ operator char* ();
+ s32int toInt();
+ u32int toInt16(); //From HEX
+ char& operator[] (int index);
+
+ u32int size();
+ void clear();
+ bool empty();
+
+ Vector<String> split(char c);
+
+ String substr(s32int start, s32int size);
+};
+
+#endif
diff --git a/Source/Kernel/Library/Vector.class.cpp b/Source/Kernel/Library/Vector.class.cpp
new file mode 100644
index 0000000..aaa777f
--- /dev/null
+++ b/Source/Kernel/Library/Vector.class.cpp
@@ -0,0 +1,103 @@
+using namespace CMem; //strlen and memcpy
+
+template <typename T>
+Vector<T>::Vector() {
+ m_data = 0;
+ m_size = 0;
+}
+
+template <typename T>
+Vector<T>::Vector(u32int size) {
+ m_data = new T[size];
+ m_size = size;
+}
+
+template <typename T>
+Vector<T>::Vector(u32int size, T value) {
+ //m_data = (T*)Mem::kalloc(size * sizeof(T));
+ m_data = new T[size](value);
+ m_size = size;
+ /*for (u32int i = 0; i < size; i++) {
+ m_data[i] = new(&m_data[i]) T(value);
+ }*/
+}
+
+template <typename T>
+Vector<T>::Vector(const Vector<T> &other) {
+ m_size = other.m_size;
+ m_data = (T*)Mem::kalloc(m_size * sizeof(T));
+ for (u32int i = 0; i < m_size; i++) {
+ new(&m_data[i]) T(other.m_data[i]);
+ }
+}
+
+template <typename T>
+Vector<T>::~Vector() {
+ if (m_data != 0) delete[] m_data;
+}
+
+template <typename T>
+T& Vector<T>::operator[] (u32int index) {
+ return m_data[index];
+}
+
+template <typename T>
+void Vector<T>::push(T element) {
+ T* newdata = (T*)Mem::kalloc((m_size + 1) * sizeof(T));
+ memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
+ new(&newdata[m_size]) T(element); //Construct by copy
+ m_size++;
+ Mem::kfree(m_data);
+ m_data = newdata;
+}
+
+/* template <typename T>
+void Vector<T>::push(T& element) {
+ T* newdata = (T*)Memory::alloc((m_size + 1) * sizeof(T));
+ memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
+ //memcpy((u8int*)newdata + (m_size * sizeof(T)), (const u8int*) element, sizeof(T)); //Copy
+ new(&newdata[m_size]) T(element); //Construct by copy
+ m_size++;
+ Memory::free(m_data);
+ m_data = newdata;
+} */
+
+template <typename T>
+void Vector<T>::pop() {
+ m_size--;
+ //delete(&m_data[m_size], &m_data[m_size]); //implicitly call destructor with placement delete
+ m_data[m_size].~T(); //Call destructor
+ T* newdata = (T*)Mem::kalloc(m_size * sizeof(T));
+ memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
+ Mem::kfree(m_data);
+ m_data = newdata;
+}
+
+template <typename T>
+T& Vector<T>::back() {
+ return m_data[m_size - 1];
+}
+
+template <typename T>
+T& Vector<T>::front() {
+ return m_data[0];
+}
+
+
+template <typename T>
+u32int Vector<T>::size() {
+ return m_size;
+}
+
+template <typename T>
+bool Vector<T>::empty() {
+ return m_size == 0;
+}
+
+template <typename T>
+void Vector<T>::clear() {
+ if (empty()) return;
+ Mem::kfree(m_data);
+ m_data = 0;
+ m_size = 0;
+}
diff --git a/Source/Kernel/Library/Vector.class.h b/Source/Kernel/Library/Vector.class.h
new file mode 100644
index 0000000..9763d2c
--- /dev/null
+++ b/Source/Kernel/Library/Vector.class.h
@@ -0,0 +1,35 @@
+#ifndef DEF_VECTOR_CLASS
+#define DEF_VECTOR_CLASS
+
+#include <Core/common.wtf.h>
+
+template <typename T>
+class Vector {
+ private:
+ T *m_data;
+ u32int m_size;
+
+ public:
+ Vector();
+ Vector(u32int size);
+ Vector(u32int size, T value);
+ Vector(const Vector<T> &other);
+ ~Vector();
+
+ T& operator[] (u32int index);
+
+ void push(T element);
+ //void push(T& element);
+ void pop();
+
+ T& back();
+ T& front();
+
+ u32int size();
+ bool empty();
+ void clear();
+};
+
+#include "Vector.class.cpp"
+
+#endif
diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile
index e42e881..7c0389e 100644
--- a/Source/Kernel/Makefile
+++ b/Source/Kernel/Makefile
@@ -16,9 +16,22 @@ Objects = Core/kmain.wtf.o \
Core/Sys.ns.o \
Core/CMem.ns.o \
MemoryManager/Mem.ns.o \
- DisplayManager/Disp.ns.o \
+ MemoryManager/PhysMem.ns.o \
+ MemoryManager/GDT.wtf.o \
+ MemoryManager/GDT.ns.o \
+ MemoryManager/PageDirectory.class.o \
+ MemoryManager/PageAlloc.ns.o \
+ DeviceManager/Disp.ns.o \
+ DeviceManager/Dev.ns.o \
+ DeviceManager/Time.ns.o \
VTManager/VirtualTerminal.class.o \
- Devices/Display/VGATextOutput.class.o
+ VTManager/VT.ns.o \
+ Library/Bitset.class.o \
+ Library/String.class.o \
+ SyscallManager/IDT.ns.o \
+ SyscallManager/IDT.wtf.o \
+ Devices/Display/VGATextOutput.class.o \
+ Devices/Timer.class.o
all: $(OutFile)
echo "* Done with $(OutFile)."
diff --git a/Source/Kernel/Map.txt b/Source/Kernel/Map.txt
index fec07b3..2ad862b 100644
--- a/Source/Kernel/Map.txt
+++ b/Source/Kernel/Map.txt
@@ -7,6 +7,10 @@ Discarded input sections
.group 0x00000000 0x0 Core/kmain.wtf.o
.group 0x00000000 0x0 Core/kmain.wtf.o
.group 0x00000000 0x0 Core/kmain.wtf.o
+ .group 0x00000000 0x0 Core/kmain.wtf.o
+ .group 0x00000000 0x0 Core/kmain.wtf.o
+ .group 0x00000000 0x0 Core/kmain.wtf.o
+ .group 0x00000000 0x0 Core/kmain.wtf.o
.group 0x00000000 0x0 Core/Sys.ns.o
.group 0x00000000 0x0 Core/Sys.ns.o
.group 0x00000000 0x0 Core/Sys.ns.o
@@ -15,8 +19,64 @@ Discarded input sections
0x00000000 0x0 Core/Sys.ns.o
.text._ZN15VirtualTerminallsEi
0x00000000 0x0 Core/Sys.ns.o
+ .group 0x00000000 0x0 MemoryManager/PhysMem.ns.o
+ .group 0x00000000 0x0 MemoryManager/PhysMem.ns.o
+ .text._Znwj 0x00000000 0x0 MemoryManager/PhysMem.ns.o
+ .group 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .group 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .group 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .group 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .group 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .group 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .group 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .group 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .group 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .group 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .text._ZnwjPv 0x00000000 0x0 DeviceManager/Dev.ns.o
.group 0x00000000 0x0 VTManager/VirtualTerminal.class.o
+ .group 0x00000000 0x0 VTManager/VirtualTerminal.class.o
+ .text._ZdaPv 0x00000000 0x0 VTManager/VirtualTerminal.class.o
+ .group 0x00000000 0x0 VTManager/VT.ns.o
+ .group 0x00000000 0x0 VTManager/VT.ns.o
+ .group 0x00000000 0x0 VTManager/VT.ns.o
+ .group 0x00000000 0x0 VTManager/VT.ns.o
+ .group 0x00000000 0x0 VTManager/VT.ns.o
+ .group 0x00000000 0x0 VTManager/VT.ns.o
+ .group 0x00000000 0x0 VTManager/VT.ns.o
+ .group 0x00000000 0x0 VTManager/VT.ns.o
+ .group 0x00000000 0x0 VTManager/VT.ns.o
+ .text._ZnwjPv 0x00000000 0x0 VTManager/VT.ns.o
+ .text._ZdaPv 0x00000000 0x0 VTManager/VT.ns.o
+ .group 0x00000000 0x0 Library/String.class.o
+ .group 0x00000000 0x0 Library/String.class.o
+ .group 0x00000000 0x0 Library/String.class.o
+ .group 0x00000000 0x0 Library/String.class.o
+ .text._ZnwjPv 0x00000000 0x0 Library/String.class.o
+ .group 0x00000000 0x0 SyscallManager/IDT.ns.o
+ .group 0x00000000 0x0 SyscallManager/IDT.ns.o
+ .group 0x00000000 0x0 SyscallManager/IDT.ns.o
+ .group 0x00000000 0x0 SyscallManager/IDT.ns.o
+ .text._Znwj 0x00000000 0x0 SyscallManager/IDT.ns.o
+ .text._ZN15VirtualTerminallsEPc
+ 0x00000000 0x0 SyscallManager/IDT.ns.o
+ .text._ZN15VirtualTerminallsEi
+ 0x00000000 0x0 SyscallManager/IDT.ns.o
+ .text._ZN15VirtualTerminallsEj
+ 0x00000000 0x0 SyscallManager/IDT.ns.o
+ .group 0x00000000 0x0 Devices/Display/VGATextOutput.class.o
.group 0x00000000 0x0 Devices/Display/VGATextOutput.class.o
+ .text._ZN6Device9handleIRQEP11registers_ti
+ 0x00000000 0x0 Devices/Display/VGATextOutput.class.o
+ .group 0x00000000 0x0 Devices/Timer.class.o
+ .group 0x00000000 0x0 Devices/Timer.class.o
+ .group 0x00000000 0x0 Devices/Timer.class.o
+ .group 0x00000000 0x0 Devices/Timer.class.o
+ .text._ZN6Device9handleIRQEP11registers_ti
+ 0x00000000 0x0 Devices/Timer.class.o
+ .text._ZN6DeviceC2Ev
+ 0x00000000 0x0 Devices/Timer.class.o
+ .rodata._ZTV6Device
+ 0x00000000 0x0 Devices/Timer.class.o
Memory Configuration
@@ -32,120 +92,445 @@ Linker script and memory map
.setup 0x00100000 0x1e Core/loader.wtf.o
0xc010001e . = (. + 0xc0000000)
-.text 0xc0100020 0x1277 load address 0x00100020
+.text 0xc0100020 0x4c2d load address 0x00100020
*(.text)
- .text 0xc0100020 0x1f0 Core/kmain.wtf.o
+ .text 0xc0100020 0x500 Core/kmain.wtf.o
0xc0100020 kmain
- .text 0xc0100210 0x75 Core/loader.wtf.o
- 0xc010021c loader
- *fill* 0xc0100285 0x3 00
- .text 0xc0100288 0xf Core/cppsupport.wtf.o
- 0xc0100288 __cxa_pure_virtual
- 0xc010028d __cxa_atexit
- *fill* 0xc0100297 0x1 00
- .text 0xc0100298 0x3b0 Core/Sys.ns.o
- 0xc01002f2 Sys::bochs_output(char*, char*, unsigned int)
- 0xc01002b6 Sys::inb(unsigned short)
- 0xc01002d3 Sys::inw(unsigned short)
- 0xc01003ec Sys::panic(char*, char*, unsigned int)
- 0xc010062c Sys::reboot()
- 0xc0100298 Sys::outb(unsigned short, unsigned char)
- 0xc010050c Sys::panic_assert(char*, unsigned int, char*)
- .text 0xc0100648 0xd5 Core/CMem.ns.o
- 0xc010067e CMem::memset(unsigned char*, unsigned char, int)
- 0xc01006b5 CMem::memsetw(unsigned short*, unsigned short, int)
- 0xc01006f0 CMem::strlen(char const*)
- 0xc0100648 CMem::memcpy(unsigned char*, unsigned char const*, int)
- *fill* 0xc010071d 0x3 00
- .text 0xc0100720 0x8e MemoryManager/Mem.ns.o
- 0xc0100778 Mem::kalloc(unsigned int, bool)
- 0xc0100720 Mem::kallocInternal(unsigned int, bool)
- *fill* 0xc01007ae 0x2 00
- .text 0xc01007b0 0x167 DisplayManager/Disp.ns.o
- 0xc01007ba Disp::textRows()
- 0xc01008a6 Disp::clear()
- 0xc01007b0 Disp::textCols()
- 0xc01008c4 Disp::setDisplay(Display*)
- 0xc0100845 Disp::moveCursor(unsigned short, unsigned short)
- 0xc01007c4 Disp::putChar(unsigned short, unsigned short, char, unsigned char)
- *fill* 0xc0100917 0x1 00
- .text 0xc0100918 0x84d VTManager/VirtualTerminal.class.o
- 0xc0100b7e VirtualTerminal::map(int, int)
- 0xc0100bec VirtualTerminal::unmap()
- 0xc0100e26 VirtualTerminal::put(char, bool)
- 0xc0100dee VirtualTerminal::setCursorLine(unsigned int)
- 0xc0100a18 VirtualTerminal::setColor(unsigned char, unsigned char)
- 0xc0100e0a VirtualTerminal::setCursorCol(unsigned int)
- 0xc0100998 VirtualTerminal::VirtualTerminal(unsigned int, unsigned int, unsigned char, unsigned char)
- 0xc0100d8c VirtualTerminal::updateCursor()
- 0xc0100f74 VirtualTerminal::write(char*, bool)
- 0xc0100fc8 VirtualTerminal::writeDec(int, bool)
- 0xc0100bf8 VirtualTerminal::redraw()
- 0xc0100a66 VirtualTerminal::putChar(unsigned int, unsigned int, char)
- 0xc01010ca VirtualTerminal::writeHex(unsigned int, bool)
- 0xc0100cd2 VirtualTerminal::scroll()
- 0xc0100918 VirtualTerminal::VirtualTerminal(unsigned int, unsigned int, unsigned char, unsigned char)
- 0xc0100b14 VirtualTerminal::clear()
- 0xc0100dc8 VirtualTerminal::moveCursor(unsigned int, unsigned int)
- *fill* 0xc0101165 0x3 00
- .text 0xc0101168 0x12f Devices/Display/VGATextOutput.class.o
- 0xc0101168 VGATextOutput::textCols()
- 0xc0101260 VGATextOutput::clear()
- 0xc01011da VGATextOutput::moveCursor(unsigned short, unsigned short)
- 0xc010117c VGATextOutput::putChar(unsigned short, unsigned short, char, unsigned char)
- 0xc0101172 VGATextOutput::textRows()
-
-.text._Znwj 0xc0101297 0x1b load address 0x00101297
- .text._Znwj 0xc0101297 0x1b Core/kmain.wtf.o
- 0xc0101297 operator new(unsigned int)
+ .text 0xc0100520 0x75 Core/loader.wtf.o
+ 0xc010052c loader
+ *fill* 0xc0100595 0x3 00
+ .text 0xc0100598 0xf Core/cppsupport.wtf.o
+ 0xc0100598 __cxa_pure_virtual
+ 0xc010059d __cxa_atexit
+ *fill* 0xc01005a7 0x1 00
+ .text 0xc01005a8 0x41a Core/Sys.ns.o
+ 0xc0100602 Sys::bochs_output(char*, char*, unsigned int)
+ 0xc01005c6 Sys::inb(unsigned short)
+ 0xc01005e3 Sys::inw(unsigned short)
+ 0xc0100786 Sys::panic(char*, char*, unsigned int)
+ 0xc01009a6 Sys::reboot()
+ 0xc01005a8 Sys::outb(unsigned short, unsigned char)
+ 0xc01006fc Sys::bochs_output_hex(unsigned int)
+ 0xc0100896 Sys::panic_assert(char*, unsigned int, char*)
+ *fill* 0xc01009c2 0x2 00
+ .text 0xc01009c4 0xd5 Core/CMem.ns.o
+ 0xc01009fa CMem::memset(unsigned char*, unsigned char, int)
+ 0xc0100a31 CMem::memsetw(unsigned short*, unsigned short, int)
+ 0xc0100a6c CMem::strlen(char const*)
+ 0xc01009c4 CMem::memcpy(unsigned char*, unsigned char const*, int)
+ *fill* 0xc0100a99 0x3 00
+ .text 0xc0100a9c 0x8b4 MemoryManager/Mem.ns.o
+ 0xc0100f4f Mem::contractHeap()
+ 0xc0100b56 Mem::insertIntoHeapIndex(Mem::heap_header_t*)
+ 0xc0100cfa Mem::removeFromHeapIndex(Mem::heap_header_t*)
+ 0xc0100cb1 Mem::removeFromHeapIndex(unsigned int)
+ 0xc0100d21 Mem::createHeap()
+ 0xc0100e2f Mem::expandHeap(unsigned int)
+ 0xc01011ee Mem::kfree(void*)
+ 0xc010105f Mem::kalloc(unsigned int, bool)
+ 0xc0100c6f Mem::heapIndexFindEntry(Mem::heap_header_t*)
+ 0xc0100a9c Mem::kallocInternal(unsigned int, bool)
+ .text 0xc0101350 0x35c MemoryManager/PhysMem.ns.o
+ 0xc01016a2 PhysMem::total()
+ 0xc01014f2 PhysMem::removeTemporaryPages()
+ 0xc010162d PhysMem::freeFrame(page_t*)
+ 0xc010167c PhysMem::free()
+ 0xc0101546 PhysMem::allocFrame(page_t*, bool, bool)
+ 0xc0101350 PhysMem::initPaging(unsigned int)
+ *fill* 0xc01016ac 0x4 00
+ .text 0xc01016b0 0x1d MemoryManager/GDT.wtf.o
+ 0xc01016b0 gdt_flush
+ *fill* 0xc01016cd 0x3 00
+ .text 0xc01016d0 0x193 MemoryManager/GDT.ns.o
+ 0xc010175f GDT::init()
+ 0xc01016d0 GDT::setGate(int, unsigned int, unsigned int, unsigned char, unsigned char)
+ *fill* 0xc0101863 0x1 00
+ .text 0xc0101864 0x2db MemoryManager/PageDirectory.class.o
+ 0xc01019cc PageDirectory::getPage(unsigned int, bool)
+ 0xc0101864 PageDirectory::PageDirectory()
+ 0xc010197a PageDirectory::~PageDirectory()
+ 0xc0101928 PageDirectory::~PageDirectory()
+ 0xc0101ade PageDirectory::freeFrame(unsigned int)
+ 0xc01018c6 PageDirectory::PageDirectory()
+ 0xc0101a8c PageDirectory::allocFrame(unsigned int, bool, bool)
+ 0xc0101b18 PageDirectory::switchTo()
+ *fill* 0xc0101b3f 0x1 00
+ .text 0xc0101b40 0x239 MemoryManager/PageAlloc.ns.o
+ 0xc0101d5d PageAlloc::free(void*)
+ 0xc0101b94 PageAlloc::alloc(unsigned int*)
+ 0xc0101b40 PageAlloc::init()
+ *fill* 0xc0101d79 0x3 00
+ .text 0xc0101d7c 0x16a DeviceManager/Disp.ns.o
+ 0xc0101d86 Disp::textRows()
+ 0xc0101e72 Disp::clear()
+ 0xc0101d7c Disp::textCols()
+ 0xc0101e90 Disp::setDisplay(Display*)
+ 0xc0101e11 Disp::moveCursor(unsigned short, unsigned short)
+ 0xc0101d90 Disp::putChar(unsigned short, unsigned short, char, unsigned char)
+ *fill* 0xc0101ee6 0x2 00
+ .text 0xc0101ee8 0x310 DeviceManager/Dev.ns.o
+ 0xc0101f2c Dev::registerDevice(Device*)
+ 0xc0102000 Dev::findDevice(String)
+ 0xc0101f52 Dev::unregisterDevice(Device*)
+ 0xc0101fd4 Dev::requestIRQ(Device*, int)
+ 0xc0101ee8 Dev::handleIRQ(registers_t*, int)
+ .text 0xc01021f8 0x37 DeviceManager/Time.ns.o
+ 0xc01021f8 Time::setTimer(Timer*)
+ 0xc010221a Time::time()
+ 0xc0102205 Time::uptime()
+ *fill* 0xc010222f 0x1 00
+ .text 0xc0102230 0x941 VTManager/VirtualTerminal.class.o
+ 0xc0102522 VirtualTerminal::map(int, int)
+ 0xc010259c VirtualTerminal::unmap()
+ 0xc010282a VirtualTerminal::put(char, bool)
+ 0xc01027f2 VirtualTerminal::setCursorLine(unsigned int)
+ 0xc0102398 VirtualTerminal::setColor(unsigned char, unsigned char)
+ 0xc0102330 VirtualTerminal::~VirtualTerminal()
+ 0xc010280e VirtualTerminal::setCursorCol(unsigned int)
+ 0xc01022b0 VirtualTerminal::VirtualTerminal(unsigned int, unsigned int, unsigned char, unsigned char)
+ 0xc0102790 VirtualTerminal::updateCursor()
+ 0xc0102980 VirtualTerminal::write(char*, bool)
+ 0xc01029d4 VirtualTerminal::writeDec(int, bool)
+ 0xc0102364 VirtualTerminal::~VirtualTerminal()
+ 0xc01025b6 VirtualTerminal::redraw()
+ 0xc01023e6 VirtualTerminal::putChar(unsigned int, unsigned int, char)
+ 0xc0102ad6 VirtualTerminal::writeHex(unsigned int, bool)
+ 0xc0102690 VirtualTerminal::scroll()
+ 0xc0102230 VirtualTerminal::VirtualTerminal(unsigned int, unsigned int, unsigned char, unsigned char)
+ 0xc01024b8 VirtualTerminal::clear()
+ 0xc01027cc VirtualTerminal::moveCursor(unsigned int, unsigned int)
+ *fill* 0xc0102b71 0x3 00
+ .text 0xc0102b74 0x156 VTManager/VT.ns.o
+ 0xc0102b9a VT::unmap(VirtualTerminal*)
+ 0xc0102c21 VT::redrawScreen()
+ 0xc0102b74 VT::map(VirtualTerminal*)
+ *fill* 0xc0102cca 0x2 00
+ .text 0xc0102ccc 0x2f1 Library/Bitset.class.o
+ 0xc0102fb2 Bitset::usedBits()
+ 0xc0102ccc Bitset::Bitset()
+ 0xc0102ed4 Bitset::testBit(unsigned int)
+ 0xc0102d9a Bitset::~Bitset()
+ 0xc0102e6c Bitset::clearBit(unsigned int)
+ 0xc0102db0 Bitset::init(unsigned int, unsigned int*)
+ 0xc0102cd8 Bitset::Bitset(unsigned int)
+ 0xc0102cd2 Bitset::Bitset()
+ 0xc0102d0c Bitset::Bitset(unsigned int)
+ 0xc0102e06 Bitset::setBit(unsigned int)
+ 0xc0102d84 Bitset::~Bitset()
+ 0xc0102d62 Bitset::Bitset(unsigned int, unsigned int*)
+ 0xc0102d40 Bitset::Bitset(unsigned int, unsigned int*)
+ 0xc0102f1c Bitset::firstFreeBit()
+ *fill* 0xc0102fbd 0x3 00
+ .text 0xc0102fc0 0xd2c Library/String.class.o
+ 0xc0102fc0 String::hex(unsigned int)
+ 0xc01035e4 String::operator==(char*)
+ 0xc01039b6 String::toInt()
+ 0xc01033ac String::String(String const&)
+ 0xc0103208 String::String()
+ 0xc0103220 String::String()
+ 0xc0103b32 String::size()
+ 0xc0103074 String::number(int)
+ 0xc0103582 String::operator==(String&)
+ 0xc0103914 String::operator+(char*)
+ 0xc0103442 String::~String()
+ 0xc0103334 String::String(String const&)
+ 0xc010399c String::operator char*()
+ 0xc0103424 String::~String()
+ 0xc0103460 String::operator=(String const&)
+ 0xc0103238 String::String(char*)
+ 0xc0103656 String::operator+=(String&)
+ 0xc0103b22 String::operator[](int)
+ 0xc0103b3e String::clear()
+ 0xc0103b66 String::empty()
+ 0xc0103824 String::operator+=(char)
+ 0xc0103b76 String::split(char)
+ 0xc0103a6a String::toInt16()
+ 0xc0103c50 String::substr(int, int)
+ 0xc0103954 String::operator+(char)
+ 0xc01032b6 String::String(char*)
+ 0xc0103732 String::operator+=(char*)
+ 0xc01034ee String::operator=(char*)
+ 0xc01038d4 String::operator+(String&)
+ .text 0xc0103cec 0x9b8 SyscallManager/IDT.ns.o
+ 0xc0104591 IDT::handleException(registers_t*, int)
+ 0xc0103d94 IDT::init()
+ 0xc0103d2d IDT::setGate(unsigned char, unsigned int, unsigned short, unsigned char)
+ 0xc0103cec interrupt_handler
+ *fill* 0xc01046a4 0xc 00
+ .text 0xc01046b0 0x204 SyscallManager/IDT.wtf.o
+ 0xc01046e0 isr4
+ 0xc01047ba isr27
+ 0xc0104732 isr13
+ 0xc0104864 irq12
+ 0xc0104788 isr22
+ 0xc0104742 isr15
+ 0xc0104850 irq10
+ 0xc0104878 irq14
+ 0xc0104710 isr9
+ 0xc010483c irq8
+ 0xc0104792 isr23
+ 0xc01047ce isr29
+ 0xc01047e2 isr31
+ 0xc010477e isr21
+ 0xc010485a irq11
+ 0xc01047c4 isr28
+ 0xc0104708 isr8
+ 0xc010481e irq5
+ 0xc0104774 isr20
+ 0xc010473a isr14
+ 0xc01046ea isr5
+ 0xc0104828 irq6
+ 0xc01047f6 irq1
+ 0xc01046c2 isr1
+ 0xc0104846 irq9
+ 0xc01047b0 isr26
+ 0xc0104722 isr11
+ 0xc010486e irq13
+ 0xc010472a isr12
+ 0xc01046b8 isr0
+ 0xc0104800 irq2
+ 0xc010479c isr24
+ 0xc010474c isr16
+ 0xc01046d6 isr3
+ 0xc01046f4 isr6
+ 0xc0104832 irq7
+ 0xc0104760 isr18
+ 0xc01047ec irq0
+ 0xc010471a isr10
+ 0xc0104756 isr17
+ 0xc01046cc isr2
+ 0xc010476a isr19
+ 0xc01046b0 idt_flush
+ 0xc01047d8 isr30
+ 0xc0104882 irq15
+ 0xc01046fe isr7
+ 0xc01047a6 isr25
+ 0xc0104814 irq4
+ 0xc010480a irq3
+ .text 0xc01048b4 0x17f Devices/Display/VGATextOutput.class.o
+ 0xc01048dc VGATextOutput::getName()
+ 0xc0104904 VGATextOutput::textCols()
+ 0xc01049fc VGATextOutput::clear()
+ 0xc01048b4 VGATextOutput::getClass()
+ 0xc0104976 VGATextOutput::moveCursor(unsigned short, unsigned short)
+ 0xc0104918 VGATextOutput::putChar(unsigned short, unsigned short, char, unsigned char)
+ 0xc010490e VGATextOutput::textRows()
+ *fill* 0xc0104a33 0x1 00
+ .text 0xc0104a34 0x219 Devices/Timer.class.o
+ 0xc0104b4c Timer::setFrequency(unsigned char)
+ 0xc0104a34 Timer::Timer(unsigned char)
+ 0xc0104afc Timer::getClass()
+ 0xc0104b24 Timer::getName()
+ 0xc0104bd0 Timer::time()
+ 0xc0104c0a Timer::handleIRQ(registers_t, int)
+ 0xc0104bc4 Timer::uptime()
+ 0xc0104a98 Timer::Timer(unsigned char)
+
+.text._Znwj 0xc0104c4d 0x1b load address 0x00104c4d
+ .text._Znwj 0xc0104c4d 0x1b Core/kmain.wtf.o
+ 0xc0104c4d operator new(unsigned int)
+
+.text._ZN6Device9handleIRQEP11registers_ti
+ 0xc0104c68 0x5 load address 0x00104c68
+ .text._ZN6Device9handleIRQEP11registers_ti
+ 0xc0104c68 0x5 Core/kmain.wtf.o
+ 0xc0104c68 Device::handleIRQ(registers_t*, int)
.text._ZN15VirtualTerminallsEPc
- 0xc01012b2 0x25 load address 0x001012b2
+ 0xc0104c6e 0x25 load address 0x00104c6e
.text._ZN15VirtualTerminallsEPc
- 0xc01012b2 0x25 Core/kmain.wtf.o
- 0xc01012b2 VirtualTerminal::operator<<(char*)
+ 0xc0104c6e 0x25 Core/kmain.wtf.o
+ 0xc0104c6e VirtualTerminal::operator<<(char*)
.text._ZN15VirtualTerminallsEi
- 0xc01012d8 0x25 load address 0x001012d8
+ 0xc0104c94 0x25 load address 0x00104c94
.text._ZN15VirtualTerminallsEi
- 0xc01012d8 0x25 Core/kmain.wtf.o
- 0xc01012d8 VirtualTerminal::operator<<(int)
+ 0xc0104c94 0x25 Core/kmain.wtf.o
+ 0xc0104c94 VirtualTerminal::operator<<(int)
+
+.text._ZN15VirtualTerminallsEj
+ 0xc0104cba 0x25 load address 0x00104cba
+ .text._ZN15VirtualTerminallsEj
+ 0xc0104cba 0x25 Core/kmain.wtf.o
+ 0xc0104cba VirtualTerminal::operator<<(unsigned int)
+
+.text._ZN6DeviceC2Ev
+ 0xc0104ce0 0xe load address 0x00104ce0
+ .text._ZN6DeviceC2Ev
+ 0xc0104ce0 0xe Core/kmain.wtf.o
+ 0xc0104ce0 Device::Device()
.text._ZN7DisplayC2Ev
- 0xc01012fe 0xe load address 0x001012fe
+ 0xc0104cee 0x1c load address 0x00104cee
.text._ZN7DisplayC2Ev
- 0xc01012fe 0xe Core/kmain.wtf.o
- 0xc01012fe Display::Display()
+ 0xc0104cee 0x1c Core/kmain.wtf.o
+ 0xc0104cee Display::Display()
.text._ZN13VGATextOutputC1Ev
- 0xc010130c 0x1c load address 0x0010130c
+ 0xc0104d0a 0x1c load address 0x00104d0a
.text._ZN13VGATextOutputC1Ev
- 0xc010130c 0x1c Core/kmain.wtf.o
- 0xc010130c VGATextOutput::VGATextOutput()
+ 0xc0104d0a 0x1c Core/kmain.wtf.o
+ 0xc0104d0a VGATextOutput::VGATextOutput()
+
+.text._ZnwjPv 0xc0104d26 0x8 load address 0x00104d26
+ .text._ZnwjPv 0xc0104d26 0x8 MemoryManager/PhysMem.ns.o
+ 0xc0104d26 operator new(unsigned int, void*)
+
+.text._ZdaPv 0xc0104d2e 0x13 load address 0x00104d2e
+ .text._ZdaPv 0xc0104d2e 0x13 DeviceManager/Dev.ns.o
+ 0xc0104d2e operator delete[](void*)
+
+.text._ZN6VectorIP6DeviceEC1Ev
+ 0xc0104d42 0x18 load address 0x00104d42
+ .text._ZN6VectorIP6DeviceEC1Ev
+ 0xc0104d42 0x18 DeviceManager/Dev.ns.o
+ 0xc0104d42 Vector<Device*>::Vector()
+
+.text._ZN6VectorIP6DeviceE4pushES1_
+ 0xc0104d5a 0x91 load address 0x00104d5a
+ .text._ZN6VectorIP6DeviceE4pushES1_
+ 0xc0104d5a 0x91 DeviceManager/Dev.ns.o
+ 0xc0104d5a Vector<Device*>::push(Device*)
+
+.text._ZN6VectorIP6DeviceE4sizeEv
+ 0xc0104dec 0xb load address 0x00104dec
+ .text._ZN6VectorIP6DeviceE4sizeEv
+ 0xc0104dec 0xb DeviceManager/Dev.ns.o
+ 0xc0104dec Vector<Device*>::size()
+
+.text._ZN6VectorIP6DeviceEixEj
+ 0xc0104df8 0x12 load address 0x00104df8
+ .text._ZN6VectorIP6DeviceEixEj
+ 0xc0104df8 0x12 DeviceManager/Dev.ns.o
+ 0xc0104df8 Vector<Device*>::operator[](unsigned int)
+
+.text._ZN6VectorIP6DeviceE4backEv
+ 0xc0104e0a 0x19 load address 0x00104e0a
+ .text._ZN6VectorIP6DeviceE4backEv
+ 0xc0104e0a 0x19 DeviceManager/Dev.ns.o
+ 0xc0104e0a Vector<Device*>::back()
+
+.text._ZN6VectorIP6DeviceE3popEv
+ 0xc0104e24 0x6d load address 0x00104e24
+ .text._ZN6VectorIP6DeviceE3popEv
+ 0xc0104e24 0x6d DeviceManager/Dev.ns.o
+ 0xc0104e24 Vector<Device*>::pop()
+
+.text._ZN6VectorIP6DeviceEC1ERKS2_
+ 0xc0104e92 0x7f load address 0x00104e92
+ .text._ZN6VectorIP6DeviceEC1ERKS2_
+ 0xc0104e92 0x7f DeviceManager/Dev.ns.o
+ 0xc0104e92 Vector<Device*>::Vector(Vector<Device*> const&)
+
+.text._ZN6VectorIP6DeviceED1Ev
+ 0xc0104f12 0x27 load address 0x00104f12
+ .text._ZN6VectorIP6DeviceED1Ev
+ 0xc0104f12 0x27 DeviceManager/Dev.ns.o
+ 0xc0104f12 Vector<Device*>::~Vector()
+
+.text._Znaj 0xc0104f39 0x1b load address 0x00104f39
+ .text._Znaj 0xc0104f39 0x1b VTManager/VirtualTerminal.class.o
+ 0xc0104f39 operator new[](unsigned int)
+
+.text._ZN6VectorIP15VirtualTerminalEC1Ev
+ 0xc0104f54 0x18 load address 0x00104f54
+ .text._ZN6VectorIP15VirtualTerminalEC1Ev
+ 0xc0104f54 0x18 VTManager/VT.ns.o
+ 0xc0104f54 Vector<VirtualTerminal*>::Vector()
+
+.text._ZN6VectorIP15VirtualTerminalE4pushES1_
+ 0xc0104f6c 0x91 load address 0x00104f6c
+ .text._ZN6VectorIP15VirtualTerminalE4pushES1_
+ 0xc0104f6c 0x91 VTManager/VT.ns.o
+ 0xc0104f6c Vector<VirtualTerminal*>::push(VirtualTerminal*)
+
+.text._ZN6VectorIP15VirtualTerminalE4sizeEv
+ 0xc0104ffe 0xb load address 0x00104ffe
+ .text._ZN6VectorIP15VirtualTerminalE4sizeEv
+ 0xc0104ffe 0xb VTManager/VT.ns.o
+ 0xc0104ffe Vector<VirtualTerminal*>::size()
+
+.text._ZN6VectorIP15VirtualTerminalEixEj
+ 0xc010500a 0x12 load address 0x0010500a
+ .text._ZN6VectorIP15VirtualTerminalEixEj
+ 0xc010500a 0x12 VTManager/VT.ns.o
+ 0xc010500a Vector<VirtualTerminal*>::operator[](unsigned int)
+
+.text._ZN6VectorIP15VirtualTerminalE4backEv
+ 0xc010501c 0x19 load address 0x0010501c
+ .text._ZN6VectorIP15VirtualTerminalE4backEv
+ 0xc010501c 0x19 VTManager/VT.ns.o
+ 0xc010501c Vector<VirtualTerminal*>::back()
-.text._Znaj 0xc0101328 0x1b load address 0x00101328
- .text._Znaj 0xc0101328 0x1b VTManager/VirtualTerminal.class.o
- 0xc0101328 operator new[](unsigned int)
+.text._ZN6VectorIP15VirtualTerminalE3popEv
+ 0xc0105036 0x6d load address 0x00105036
+ .text._ZN6VectorIP15VirtualTerminalE3popEv
+ 0xc0105036 0x6d VTManager/VT.ns.o
+ 0xc0105036 Vector<VirtualTerminal*>::pop()
-.rodata 0xc0102000 0x293 load address 0x00102000
+.text._ZN6VectorIP15VirtualTerminalED1Ev
+ 0xc01050a4 0x27 load address 0x001050a4
+ .text._ZN6VectorIP15VirtualTerminalED1Ev
+ 0xc01050a4 0x27 VTManager/VT.ns.o
+ 0xc01050a4 Vector<VirtualTerminal*>::~Vector()
+
+.text._ZN6VectorI6StringEC1Ev
+ 0xc01050cc 0x18 load address 0x001050cc
+ .text._ZN6VectorI6StringEC1Ev
+ 0xc01050cc 0x18 Library/String.class.o
+ 0xc01050cc Vector<String>::Vector()
+
+.text._ZN6VectorI6StringE4pushES0_
+ 0xc01050e4 0x9b load address 0x001050e4
+ .text._ZN6VectorI6StringE4pushES0_
+ 0xc01050e4 0x9b Library/String.class.o
+ 0xc01050e4 Vector<String>::push(String)
+
+.text._ZN6VectorI6StringE4backEv
+ 0xc0105180 0x19 load address 0x00105180
+ .text._ZN6VectorI6StringE4backEv
+ 0xc0105180 0x19 Library/String.class.o
+ 0xc0105180 Vector<String>::back()
+
+.rodata 0xc0106000 0x6f3 load address 0x00106000
*(.rodata)
- .rodata 0xc0102000 0x23f Core/kmain.wtf.o
- .rodata 0xc010223f 0x51 Core/Sys.ns.o
- .rodata 0xc0102290 0x3 VTManager/VirtualTerminal.class.o
+ .rodata 0xc0106000 0x353 Core/kmain.wtf.o
+ .rodata 0xc0106353 0x4f Core/Sys.ns.o
+ .rodata 0xc01063a2 0x5c MemoryManager/PhysMem.ns.o
+ *fill* 0xc01063fe 0x2 00
+ .rodata 0xc0106400 0x6f MemoryManager/PageAlloc.ns.o
+ .rodata 0xc010646f 0x3 VTManager/VirtualTerminal.class.o
+ .rodata 0xc0106472 0x5 Library/String.class.o
+ *fill* 0xc0106477 0x9 00
+ .rodata 0xc0106480 0x220 SyscallManager/IDT.ns.o
+ .rodata 0xc01066a0 0x30 Devices/Display/VGATextOutput.class.o
+ .rodata 0xc01066d0 0x23 Devices/Timer.class.o
.rodata._ZTV7Display
- 0xc0102298 0x1c load address 0x00102298
+ 0xc0106700 0x28 load address 0x00106700
.rodata._ZTV7Display
- 0xc0102298 0x1c Core/kmain.wtf.o
- 0xc0102298 vtable for Display
+ 0xc0106700 0x28 Core/kmain.wtf.o
+ 0xc0106700 vtable for Display
+
+.rodata._ZTV6Device
+ 0xc0106728 0x14 load address 0x00106728
+ .rodata._ZTV6Device
+ 0xc0106728 0x14 Core/kmain.wtf.o
+ 0xc0106728 vtable for Device
.rodata._ZTV13VGATextOutput
- 0xc01022b8 0x1c load address 0x001022b8
+ 0xc0106740 0x28 load address 0x00106740
.rodata._ZTV13VGATextOutput
- 0xc01022b8 0x1c Devices/Display/VGATextOutput.class.o
- 0xc01022b8 vtable for VGATextOutput
+ 0xc0106740 0x28 Devices/Display/VGATextOutput.class.o
+ 0xc0106740 vtable for VGATextOutput
+
+.rodata._ZTV5Timer
+ 0xc0106768 0x14 load address 0x00106768
+ .rodata._ZTV5Timer
+ 0xc0106768 0x14 Devices/Timer.class.o
+ 0xc0106768 vtable for Timer
-.rel.dyn 0xc01022d4 0x0 load address 0x001022d4
+.rel.dyn 0xc010677c 0x0 load address 0x0010677c
.rel.text 0x00000000 0x0 Core/kmain.wtf.o
.rel.text._Znwj
0x00000000 0x0 Core/kmain.wtf.o
@@ -153,76 +538,173 @@ Linker script and memory map
0x00000000 0x0 Core/kmain.wtf.o
.rel.text._ZN15VirtualTerminallsEi
0x00000000 0x0 Core/kmain.wtf.o
+ .rel.text._ZN15VirtualTerminallsEj
+ 0x00000000 0x0 Core/kmain.wtf.o
+ .rel.text._ZN6DeviceC2Ev
+ 0x00000000 0x0 Core/kmain.wtf.o
.rel.text._ZN7DisplayC2Ev
0x00000000 0x0 Core/kmain.wtf.o
.rel.text._ZN13VGATextOutputC1Ev
0x00000000 0x0 Core/kmain.wtf.o
.rel.rodata._ZTV7Display
0x00000000 0x0 Core/kmain.wtf.o
+ .rel.rodata._ZTV6Device
+ 0x00000000 0x0 Core/kmain.wtf.o
+ .rel.text._ZN6VectorIP6DeviceE4pushES1_
+ 0x00000000 0x0 Core/kmain.wtf.o
+ .rel.text._ZN6VectorIP6DeviceEC1ERKS2_
+ 0x00000000 0x0 Core/kmain.wtf.o
+ .rel.text._ZN6VectorIP6DeviceED1Ev
+ 0x00000000 0x0 Core/kmain.wtf.o
+ .rel.text._ZN6VectorIP15VirtualTerminalE4pushES1_
+ 0x00000000 0x0 Core/kmain.wtf.o
+ .rel.text._ZN6VectorIP15VirtualTerminalED1Ev
+ 0x00000000 0x0 Core/kmain.wtf.o
+ .rel.text._ZN6VectorI6StringE4pushES0_
+ 0x00000000 0x0 Core/kmain.wtf.o
+ .rel.rodata._ZTV13VGATextOutput
+ 0x00000000 0x0 Core/kmain.wtf.o
+ .rel.rodata._ZTV5Timer
+ 0x00000000 0x0 Core/kmain.wtf.o
-.data 0xc0103000 0x24 load address 0x00103000
- 0xc0103000 start_ctors = .
+.data 0xc0107000 0x2c load address 0x00107000
+ 0xc0107000 start_ctors = .
*(.ctor*)
- 0xc0103000 end_ctors = .
- 0xc0103000 start_dtors = .
+ .ctors 0xc0107000 0x4 DeviceManager/Dev.ns.o
+ .ctors 0xc0107004 0x4 VTManager/VT.ns.o
+ 0xc0107008 end_ctors = .
+ 0xc0107008 start_dtors = .
*(.dtor*)
- 0xc0103000 end_dtors = .
+ 0xc0107008 end_dtors = .
*(.data)
- .data 0xc0103000 0x24 Core/kmain.wtf.o
- 0xc0103020 melonLogoCols
- 0xc0103000 melonLogo
- 0xc010301c melonLogoLines
- .data 0xc0103024 0x0 Core/cppsupport.wtf.o
- .data 0xc0103024 0x0 Core/Sys.ns.o
- .data 0xc0103024 0x0 Core/CMem.ns.o
- .data 0xc0103024 0x0 MemoryManager/Mem.ns.o
- .data 0xc0103024 0x0 DisplayManager/Disp.ns.o
- .data 0xc0103024 0x0 VTManager/VirtualTerminal.class.o
- .data 0xc0103024 0x0 Devices/Display/VGATextOutput.class.o
-
-.bss 0xc0103024 0x401c load address 0x00103024
- 0xc0103024 sbss = .
+ .data 0xc0107008 0x24 Core/kmain.wtf.o
+ 0xc0107028 melonLogoCols
+ 0xc0107008 melonLogo
+ 0xc0107024 melonLogoLines
+ .data 0xc010702c 0x0 Core/cppsupport.wtf.o
+ .data 0xc010702c 0x0 Core/Sys.ns.o
+ .data 0xc010702c 0x0 Core/CMem.ns.o
+ .data 0xc010702c 0x0 MemoryManager/Mem.ns.o
+ .data 0xc010702c 0x0 MemoryManager/PhysMem.ns.o
+ .data 0xc010702c 0x0 MemoryManager/GDT.ns.o
+ .data 0xc010702c 0x0 MemoryManager/PageDirectory.class.o
+ .data 0xc010702c 0x0 MemoryManager/PageAlloc.ns.o
+ .data 0xc010702c 0x0 DeviceManager/Disp.ns.o
+ .data 0xc010702c 0x0 DeviceManager/Dev.ns.o
+ .data 0xc010702c 0x0 DeviceManager/Time.ns.o
+ .data 0xc010702c 0x0 VTManager/VirtualTerminal.class.o
+ .data 0xc010702c 0x0 VTManager/VT.ns.o
+ .data 0xc010702c 0x0 Library/Bitset.class.o
+ .data 0xc010702c 0x0 Library/String.class.o
+ .data 0xc010702c 0x0 SyscallManager/IDT.ns.o
+ .data 0xc010702c 0x0 Devices/Display/VGATextOutput.class.o
+ .data 0xc010702c 0x0 Devices/Timer.class.o
+
+.bss 0xc0107040 0x4928 load address 0x00107040
+ 0xc0107040 sbss = .
*(COMMON)
*(.bss)
- .bss 0xc0103024 0x0 Core/kmain.wtf.o
- .bss 0xc0103024 0x4000 Core/loader.wtf.o
- .bss 0xc0107024 0x4 Core/cppsupport.wtf.o
- 0xc0107024 __dso_handle
- .bss 0xc0107028 0x0 Core/Sys.ns.o
- .bss 0xc0107028 0x0 Core/CMem.ns.o
- .bss 0xc0107028 0xc MemoryManager/Mem.ns.o
- 0xc0107030 Mem::kheapFree
- 0xc0107028 Mem::kheapUsable
- 0xc010702c Mem::placementAddress
- .bss 0xc0107034 0xc DisplayManager/Disp.ns.o
- 0xc0107034 Disp::mode
- .bss 0xc0107040 0x0 VTManager/VirtualTerminal.class.o
- .bss 0xc0107040 0x0 Devices/Display/VGATextOutput.class.o
- 0xc0107040 ebss = .
- 0xc0107040 end = .
- 0xc0107040 _end = .
- 0xc0107040 __end = .
+ .bss 0xc0107040 0x0 Core/kmain.wtf.o
+ .bss 0xc0107040 0x4000 Core/loader.wtf.o
+ .bss 0xc010b040 0x4 Core/cppsupport.wtf.o
+ 0xc010b040 __dso_handle
+ .bss 0xc010b044 0x0 Core/Sys.ns.o
+ .bss 0xc010b044 0x0 Core/CMem.ns.o
+ .bss 0xc010b044 0x1c MemoryManager/Mem.ns.o
+ 0xc010b058 Mem::heapStart
+ 0xc010b045 Mem::pagingEnabled
+ 0xc010b04c Mem::kheapFree
+ 0xc010b05c Mem::heapEnd
+ 0xc010b044 Mem::kheapUsable
+ 0xc010b048 Mem::placementAddress
+ 0xc010b050 Mem::heapIndex
+ .bss 0xc010b060 0xc MemoryManager/PhysMem.ns.o
+ 0xc010b060 kernelPageDirectory
+ 0xc010b068 PhysMem::frames
+ 0xc010b064 PhysMem::nframes
+ *fill* 0xc010b06c 0x14 00
+ .bss 0xc010b080 0x2e MemoryManager/GDT.ns.o
+ 0xc010b0a8 GDT::gdt_ptr
+ 0xc010b080 GDT::gdt_entries
+ *fill* 0xc010b0ae 0x2 00
+ .bss 0xc010b0b0 0x0 MemoryManager/PageDirectory.class.o
+ .bss 0xc010b0b0 0x12 MemoryManager/PageAlloc.ns.o
+ 0xc010b0c0 PageAlloc::usable
+ 0xc010b0b0 PageAlloc::freePage
+ 0xc010b0bc PageAlloc::freec
+ 0xc010b0c1 PageAlloc::locked
+ *fill* 0xc010b0c2 0x2 00
+ .bss 0xc010b0c4 0xc DeviceManager/Disp.ns.o
+ 0xc010b0c4 Disp::mode
+ *fill* 0xc010b0d0 0x10 00
+ .bss 0xc010b0e0 0x60 DeviceManager/Dev.ns.o
+ 0xc010b0e0 Dev::devices
+ 0xc010b100 Dev::irqHandler
+ .bss 0xc010b140 0x4 DeviceManager/Time.ns.o
+ 0xc010b140 Time::timer
+ .bss 0xc010b144 0x0 VTManager/VirtualTerminal.class.o
+ .bss 0xc010b144 0x8 VTManager/VT.ns.o
+ 0xc010b144 VT::mappedVTs
+ .bss 0xc010b14c 0x0 Library/Bitset.class.o
+ .bss 0xc010b14c 0x0 Library/String.class.o
+ *fill* 0xc010b14c 0x14 00
+ .bss 0xc010b160 0x806 SyscallManager/IDT.ns.o
+ 0xc010b160 IDT::idt_entries
+ 0xc010b960 IDT::idt_ptr
+ *fill* 0xc010b966 0x2 00
+ .bss 0xc010b968 0x0 Devices/Display/VGATextOutput.class.o
+ .bss 0xc010b968 0x0 Devices/Timer.class.o
+ 0xc010b968 ebss = .
+ 0xc010b968 end = .
+ 0xc010b968 _end = .
+ 0xc010b968 __end = .
LOAD Core/kmain.wtf.o
LOAD Core/loader.wtf.o
LOAD Core/cppsupport.wtf.o
LOAD Core/Sys.ns.o
LOAD Core/CMem.ns.o
LOAD MemoryManager/Mem.ns.o
-LOAD DisplayManager/Disp.ns.o
+LOAD MemoryManager/PhysMem.ns.o
+LOAD MemoryManager/GDT.wtf.o
+LOAD MemoryManager/GDT.ns.o
+LOAD MemoryManager/PageDirectory.class.o
+LOAD MemoryManager/PageAlloc.ns.o
+LOAD DeviceManager/Disp.ns.o
+LOAD DeviceManager/Dev.ns.o
+LOAD DeviceManager/Time.ns.o
LOAD VTManager/VirtualTerminal.class.o
+LOAD VTManager/VT.ns.o
+LOAD Library/Bitset.class.o
+LOAD Library/String.class.o
+LOAD SyscallManager/IDT.ns.o
+LOAD SyscallManager/IDT.wtf.o
LOAD Devices/Display/VGATextOutput.class.o
+LOAD Devices/Timer.class.o
OUTPUT(Melon.ke elf32-i386)
-.comment 0x00000000 0xaf
+.comment 0x00000000 0x1b3
.comment 0x00000000 0x12 Core/kmain.wtf.o
.comment 0x00000012 0x1f Core/loader.wtf.o
.comment 0x00000031 0x12 Core/cppsupport.wtf.o
.comment 0x00000043 0x12 Core/Sys.ns.o
.comment 0x00000055 0x12 Core/CMem.ns.o
.comment 0x00000067 0x12 MemoryManager/Mem.ns.o
- .comment 0x00000079 0x12 DisplayManager/Disp.ns.o
- .comment 0x0000008b 0x12 VTManager/VirtualTerminal.class.o
- .comment 0x0000009d 0x12 Devices/Display/VGATextOutput.class.o
+ .comment 0x00000079 0x12 MemoryManager/PhysMem.ns.o
+ .comment 0x0000008b 0x1f MemoryManager/GDT.wtf.o
+ .comment 0x000000aa 0x12 MemoryManager/GDT.ns.o
+ .comment 0x000000bc 0x12 MemoryManager/PageDirectory.class.o
+ .comment 0x000000ce 0x12 MemoryManager/PageAlloc.ns.o
+ .comment 0x000000e0 0x12 DeviceManager/Disp.ns.o
+ .comment 0x000000f2 0x12 DeviceManager/Dev.ns.o
+ .comment 0x00000104 0x12 DeviceManager/Time.ns.o
+ .comment 0x00000116 0x12 VTManager/VirtualTerminal.class.o
+ .comment 0x00000128 0x12 VTManager/VT.ns.o
+ .comment 0x0000013a 0x12 Library/Bitset.class.o
+ .comment 0x0000014c 0x12 Library/String.class.o
+ .comment 0x0000015e 0x12 SyscallManager/IDT.ns.o
+ .comment 0x00000170 0x1f SyscallManager/IDT.wtf.o
+ .comment 0x0000018f 0x12 Devices/Display/VGATextOutput.class.o
+ .comment 0x000001a1 0x12 Devices/Timer.class.o
.note.GNU-stack
0x00000000 0x0
@@ -237,8 +719,30 @@ OUTPUT(Melon.ke elf32-i386)
.note.GNU-stack
0x00000000 0x0 MemoryManager/Mem.ns.o
.note.GNU-stack
- 0x00000000 0x0 DisplayManager/Disp.ns.o
+ 0x00000000 0x0 MemoryManager/PhysMem.ns.o
+ .note.GNU-stack
+ 0x00000000 0x0 MemoryManager/GDT.ns.o
+ .note.GNU-stack
+ 0x00000000 0x0 MemoryManager/PageDirectory.class.o
+ .note.GNU-stack
+ 0x00000000 0x0 MemoryManager/PageAlloc.ns.o
+ .note.GNU-stack
+ 0x00000000 0x0 DeviceManager/Disp.ns.o
+ .note.GNU-stack
+ 0x00000000 0x0 DeviceManager/Dev.ns.o
+ .note.GNU-stack
+ 0x00000000 0x0 DeviceManager/Time.ns.o
.note.GNU-stack
0x00000000 0x0 VTManager/VirtualTerminal.class.o
.note.GNU-stack
+ 0x00000000 0x0 VTManager/VT.ns.o
+ .note.GNU-stack
+ 0x00000000 0x0 Library/Bitset.class.o
+ .note.GNU-stack
+ 0x00000000 0x0 Library/String.class.o
+ .note.GNU-stack
+ 0x00000000 0x0 SyscallManager/IDT.ns.o
+ .note.GNU-stack
0x00000000 0x0 Devices/Display/VGATextOutput.class.o
+ .note.GNU-stack
+ 0x00000000 0x0 Devices/Timer.class.o
diff --git a/Source/Kernel/Melon.ke b/Source/Kernel/Melon.ke
index 5b40f90..a4bbc45 100755
--- a/Source/Kernel/Melon.ke
+++ b/Source/Kernel/Melon.ke
Binary files differ
diff --git a/Source/Kernel/MemoryManager/GDT.ns.cpp b/Source/Kernel/MemoryManager/GDT.ns.cpp
new file mode 100644
index 0000000..4fb9803
--- /dev/null
+++ b/Source/Kernel/MemoryManager/GDT.ns.cpp
@@ -0,0 +1,34 @@
+#include "GDT.ns.h"
+
+extern "C" void gdt_flush(u32int);
+
+namespace GDT {
+
+gdt_entry_t gdt_entries[5];
+gdt_ptr_t gdt_ptr;
+
+void setGate(s32int num, u32int base, u32int limit, u8int access, u8int gran) {
+ gdt_entries[num].base_low = (base & 0xFFFF);
+ gdt_entries[num].base_middle = (base >> 16) & 0xFF;
+ gdt_entries[num].base_high = (base >> 24) & 0xFF;
+
+ gdt_entries[num].limit_low = (limit & 0xFFFF);
+ gdt_entries[num].granularity = (limit >> 16) & 0x0F;
+ gdt_entries[num].granularity |= gran & 0xF0;
+ gdt_entries[num].access = access;
+}
+
+void init() {
+ gdt_ptr.limit = (sizeof(gdt_entry_t) * 5) - 1;
+ gdt_ptr.base = (u32int)&gdt_entries;
+
+ setGate(0, 0, 0, 0, 0); //Null segment
+ setGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); //Kernel code segment
+ setGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); //Kernel data segment
+ setGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); //User code segment
+ setGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); //User data segment
+
+ gdt_flush((u32int)&gdt_ptr);
+}
+
+}
diff --git a/Source/Kernel/MemoryManager/GDT.ns.h b/Source/Kernel/MemoryManager/GDT.ns.h
new file mode 100644
index 0000000..7a9f95f
--- /dev/null
+++ b/Source/Kernel/MemoryManager/GDT.ns.h
@@ -0,0 +1,24 @@
+#ifndef DEF_GDT_NS_H
+#define DEF_GDT_NS_H
+
+#include <Core/common.wtf.h>
+
+namespace GDT {
+ struct gdt_entry_t {
+ u16int limit_low;
+ u16int base_low;
+ u8int base_middle;
+ u8int access;
+ u8int granularity;
+ u8int base_high;
+ } __attribute__((packed));
+
+ struct gdt_ptr_t {
+ u16int limit;
+ u32int base;
+ } __attribute__((packed));
+
+ void init();
+}
+
+#endif
diff --git a/Source/Kernel/MemoryManager/GDT.wtf.asm b/Source/Kernel/MemoryManager/GDT.wtf.asm
new file mode 100644
index 0000000..eb216ed
--- /dev/null
+++ b/Source/Kernel/MemoryManager/GDT.wtf.asm
@@ -0,0 +1,17 @@
+[GLOBAL gdt_flush]
+
+gdt_flush:
+ mov eax, [esp+4]
+ lgdt [eax]
+
+ mov ax, 0x10
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+ mov ss, ax
+ jmp 0x08:.flush
+
+.flush:
+ ret
+
diff --git a/Source/Kernel/MemoryManager/Mem.ns.cpp b/Source/Kernel/MemoryManager/Mem.ns.cpp
index d8bfc4f..832bd99 100644
--- a/Source/Kernel/MemoryManager/Mem.ns.cpp
+++ b/Source/Kernel/MemoryManager/Mem.ns.cpp
@@ -1,23 +1,259 @@
#include <Core/common.wtf.h>
+#include <MemoryManager/PhysMem.ns.h>
namespace Mem {
-bool kheapUsable = false;
+bool kheapUsable = false, pagingEnabled = false;
u32int placementAddress, kheapFree;
+heap_index_t heapIndex;
+u32int heapStart, heapEnd;
+
+//Placement malloc, used while heap is not initialized
void *kallocInternal(u32int sz, bool align) {
+ if (kheapUsable) return 0;
if (align && (placementAddress & 0xFFFFF000)) {
placementAddress &= 0xFFFFF000;
placementAddress += 0x1000;
}
u32int temp = placementAddress;
placementAddress += sz;
+ for (u32int i = temp; i < placementAddress; i += 0x1000) {
+ if (pagingEnabled) kernelPageDirectory->allocFrame(i, true, false);
+ }
return (void*)temp;
}
+//***************************************************************************
+//*** HEAP INDEX FUNCTIONS ***
+//***************************************************************************
+void insertIntoHeapIndex(heap_header_t *e) {
+ //If index is full, return
+ if ((heapIndex.size * sizeof(heap_header_t*) + (u32int)heapIndex.data) >= heapStart) return;
+
+ u32int iterator = 0;
+ while (iterator < heapIndex.size && heapIndex.data[iterator]->size < e->size) {
+ if (heapIndex.data[iterator] == e) return;
+ iterator++;
+ }
+ if (iterator == heapIndex.size) {
+ heapIndex.data[heapIndex.size++] = e;
+ } else {
+ u32int pos = iterator;
+ iterator = heapIndex.size;
+ while (iterator > pos) {
+ heapIndex.data[iterator] = heapIndex.data[iterator - 1];
+ iterator--;
+ }
+ heapIndex.size++;
+ heapIndex.data[pos] = e;
+ }
+}
+
+u32int heapIndexFindEntry(heap_header_t *e) {
+ for (u32int i = 0; i < heapIndex.size; i++) {
+ if (heapIndex.data[i] == e)
+ return i;
+ }
+ return (u32int) - 1;
+}
+
+void removeFromHeapIndex(u32int idx) {
+ heapIndex.size--;
+ while (idx < heapIndex.size) {
+ heapIndex.data[idx] = heapIndex.data[idx + 1];
+ idx++;
+ }
+}
+
+void removeFromHeapIndex(heap_header_t *e) {
+ u32int i = heapIndexFindEntry(e);
+ if (i != (u32int) - 1) {
+ removeFromHeapIndex(i);
+ }
+}
+
+//***************************************************************************
+//*** MEMORY MANAGMENT FUNCTIONS ***
+//***************************************************************************
+void createHeap() {
+ u32int heapIndexSize = PhysMem::total() * 64 + 0x10000;
+ heapStart = placementAddress + 0x10000; //Set initial heap start
+ heapEnd = heapStart + HEAP_MIN_SIZE + heapIndexSize; //Set heap end
+
+ //Alocate frames for the heap
+ for (u32int i = placementAddress; i < heapEnd; i += 0x1000) {
+ kernelPageDirectory->allocFrame(i, true, false);
+ }
+
+ heapIndex.data = (heap_header_t **)heapStart; //Set index start
+ heapIndex.size = 0;
+ heapStart += heapIndexSize; //Set some of available memory to be the index
+
+ heap_header_t *hole = (heap_header_t*) heapStart;
+ hole->size = (heapEnd - heapStart);
+ hole->magic = HEAP_MAGIC;
+ hole->is_hole = true;
+
+ heap_footer_t *hole_footer = (heap_footer_t*) (heapEnd - sizeof(heap_footer_t));
+ hole_footer->header = hole;
+ hole_footer->magic = HEAP_MAGIC;
+
+ insertIntoHeapIndex(hole);
+
+ kheapUsable = true;
+ kheapFree = (heapEnd - heapStart);
+}
+
+void expandHeap(u32int quantity) {
+ if (quantity & 0x00000FFF)
+ quantity = (quantity & 0xFFFFF000) + 0x1000;
+
+ u32int newEnd = heapEnd + quantity;
+
+ for (u32int i = heapEnd; i < newEnd; i++) {
+ kernelPageDirectory->allocFrame(i, true, false);
+ }
+
+ heap_footer_t *last_footer = (heap_footer_t*) (heapEnd - sizeof(heap_footer_t));
+ heap_header_t *last_header = last_footer->header;
+ if (last_header->is_hole) { //Last block of heap is a hole, update its size
+ removeFromHeapIndex(last_header);
+ last_header->size += quantity;
+
+ last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t));
+
+ last_footer->magic = HEAP_MAGIC;
+ last_footer->header = last_header;
+
+ insertIntoHeapIndex(last_header);
+ } else { //Last block is not a hole. Just add a new hole at the end
+ last_header = (heap_header_t*)heapEnd;
+ last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t));
+
+ last_header->is_hole = true;
+ last_header->magic = HEAP_MAGIC;
+ last_header->size = quantity;
+
+ last_footer->magic = HEAP_MAGIC;
+ last_footer->header = last_header;
+
+ insertIntoHeapIndex(last_header);
+ }
+
+ heapEnd = newEnd;
+}
+
+void contractHeap() { //Automatically work out how much we can contract
+ heap_footer_t *last_footer = (heap_footer_t*) (heapEnd - sizeof(heap_footer_t));
+ heap_header_t *last_header = last_footer->header;
+ if (last_header->is_hole == false) return; //We need a hole at end of heap
+
+ u32int quantity = 0;
+ while ((heapEnd - heapStart) - quantity > HEAP_MIN_SIZE and
+ (last_header->size - quantity) > 0x1000) //Always keep at least 0x1000 free at end
+ quantity += 0x1000;
+ if (quantity == 0) return;
+
+ u32int newEnd = heapEnd - quantity;
+
+ removeFromHeapIndex(last_header);
+ last_header->size -= quantity;
+ last_footer = (heap_footer_t*)((u32int)last_footer - quantity);
+ last_footer->magic = HEAP_MAGIC;
+ last_footer->header = last_header;
+ insertIntoHeapIndex(last_header);
+
+ for (u32int i = newEnd; i < heapEnd; i += 0x1000) {
+ kernelPageDirectory->freeFrame(i);
+ }
+
+ heapEnd = newEnd;
+}
+
void *kalloc(u32int sz, bool align) {
if (!kheapUsable) return kallocInternal(sz, align);
- return 0;
+ if (align) return 0;
+
+ u32int newsize = sz + sizeof(heap_header_t) + sizeof(heap_footer_t);
+ u32int iterator = 0;
+ while (iterator < heapIndex.size) {
+ if (heapIndex.data[iterator]->size >= newsize) break;
+ iterator++;
+ }
+ if (iterator == heapIndex.size) { //TODO : expand heap
+ expandHeap((sz & 0xFFFFF000) + 0x1000);
+ return kalloc(sz); //Recurse call
+ }
+
+ heap_header_t *loc = heapIndex.data[iterator];
+ heap_footer_t *footer = (heap_footer_t*)((u32int)loc + loc->size - sizeof(heap_footer_t));
+ loc->is_hole = false; //Update current header
+
+ removeFromHeapIndex(loc);
+
+
+ //Here we create a new hole after currently allocated block, but only if we have enough space. If we don't, we simply allocate a bigger block so that we don't loose space
+ if (loc->size > (newsize + sizeof(heap_header_t) + sizeof(heap_footer_t))) {
+ loc->size = newsize; //Update header for return block
+
+ heap_footer_t *newfooter = (heap_footer_t*)((u32int)loc + newsize - sizeof(heap_footer_t)); //Write footer for return block
+ newfooter->header = loc;
+ newfooter->magic = HEAP_MAGIC;
+
+ heap_header_t *nextloc = (heap_header_t*)((u32int)loc + newsize); //Write header for new hole
+ nextloc->is_hole = true;
+ nextloc->magic = HEAP_MAGIC;
+ nextloc->size = ((u32int)footer - (u32int)nextloc + sizeof(heap_footer_t));
+
+ footer->header = nextloc; //Write footer for new hole
+ footer->magic = HEAP_MAGIC;
+
+ insertIntoHeapIndex(nextloc);
+ }
+
+ kheapFree -= loc->size;
+
+ return (void*)((u32int)loc + sizeof(heap_header_t));
+}
+
+void kfree(void *ptr) { //TODO
+ if (ptr == 0) return;
+
+ heap_header_t *header = (heap_header_t*) ((u32int)ptr - sizeof(heap_header_t));
+ heap_footer_t *footer = (heap_footer_t*)((u32int)header + header->size - sizeof(heap_footer_t));
+ if (header->magic != HEAP_MAGIC or footer->magic != HEAP_MAGIC) return;
+
+ kheapFree += header->size;
+
+ //Unify left
+ heap_footer_t *prev_footer = (heap_footer_t*)((u32int)header - sizeof(heap_footer_t));
+ if (prev_footer->magic == HEAP_MAGIC && prev_footer->header->is_hole) {
+ header = prev_footer->header;
+ removeFromHeapIndex(header);
+
+ footer->header = header;
+ header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t));
+ }
+
+ //Unify right
+ heap_header_t *next_header = (heap_header_t*)((u32int)footer + sizeof(heap_footer_t));
+ if (next_header->magic == HEAP_MAGIC && next_header->is_hole) {
+ removeFromHeapIndex(next_header);
+ footer = (heap_footer_t*)((u32int)footer + next_header->size);
+
+ footer->header = header;
+ header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t));
+ }
+
+ header->is_hole = true;
+
+ insertIntoHeapIndex(header);
+
+ if ((u32int)footer == (heapEnd - sizeof(heap_footer_t)) and
+ header->size >= 0x2000 and (heapEnd - heapStart > HEAP_MIN_SIZE)) {
+ contractHeap();
+ }
}
}
diff --git a/Source/Kernel/MemoryManager/Mem.ns.h b/Source/Kernel/MemoryManager/Mem.ns.h
index b3177a4..e208d65 100644
--- a/Source/Kernel/MemoryManager/Mem.ns.h
+++ b/Source/Kernel/MemoryManager/Mem.ns.h
@@ -3,12 +3,34 @@
#ifndef DEF_MEM_NS_H
#define DEF_MEM_NS_H
+//Heap minimum size : 2M
+#define HEAP_MIN_SIZE 0x00200000
+//Heap magic number, for verifications
+#define HEAP_MAGIC 0xBEEF1337
+
namespace Mem {
+ extern bool pagingEnabled;
extern u32int placementAddress, kheapFree;
+ struct heap_header_t {
+ u32int magic;
+ bool is_hole;
+ u32int size;
+ };
+
+ struct heap_footer_t {
+ u32int magic;
+ heap_header_t *header;
+ };
+
+ struct heap_index_t {
+ heap_header_t **data;
+ u32int size;
+ };
+
+ void createHeap();
void *kalloc(u32int sz, bool align = false);
void kfree(void *ptr);
-
}
#endif
diff --git a/Source/Kernel/MemoryManager/PageAlloc.ns.cpp b/Source/Kernel/MemoryManager/PageAlloc.ns.cpp
new file mode 100644
index 0000000..ac2969e
--- /dev/null
+++ b/Source/Kernel/MemoryManager/PageAlloc.ns.cpp
@@ -0,0 +1,68 @@
+#include "PageAlloc.ns.h"
+#include <MemoryManager/PhysMem.ns.h>
+
+#define CACHED_PAGES 3
+
+// This mechanism is supposed to make it impossible to run out of free pages to use as a page table
+
+namespace PageAlloc {
+
+void* freePage[CACHED_PAGES];
+int freec = 0;
+bool usable = false, locked = false;
+
+void init() {
+ freec = CACHED_PAGES;
+ for (u32int i = 0; i < CACHED_PAGES; i++) {
+ freePage[i] = Mem::kalloc(0x1000, true);
+ }
+ usable = true;
+}
+
+void* alloc(u32int* phys) {
+ if (!usable) init();
+
+ while (freec < CACHED_PAGES && (!locked)) {
+ locked = true;
+ void* next = 0;
+ if (!Mem::pagingEnabled) {
+ next = Mem::kalloc(0x1000, true);
+ } else {
+ u32int i = 0xFFFFF000;
+ page_t *p;
+ while (1) {
+ p = kernelPageDirectory->getPage(i, true);
+ if (p->frame == 0) break;
+ i -= 0x1000;
+ }
+ PhysMem::allocFrame(p, true, false);
+ next = (void*)i;
+ }
+ freePage[freec] = next;
+ freec++;
+ locked = false;
+ }
+
+ freec--;
+ void* ret = freePage[freec];
+ if (!Mem::pagingEnabled) {
+ *phys = (u32int)ret - 0xC0000000;
+ } else {
+ page_t* p = kernelPageDirectory->getPage((u32int)ret, false);
+ if (p == 0) { //THIS SHOULD NEVER HAPPEN
+ PANIC("Cached free page does not exist.");
+ } else if (p->frame == 0) {
+ PANIC("Cached free page is not mapped to a frame.");
+ } else {
+ *phys = (p->frame * 0x1000);
+ }
+ }
+ return ret;
+}
+
+void free(void *ptr) {
+ kernelPageDirectory->freeFrame((u32int)ptr);
+ return;
+}
+
+}
diff --git a/Source/Kernel/MemoryManager/PageAlloc.ns.h b/Source/Kernel/MemoryManager/PageAlloc.ns.h
new file mode 100644
index 0000000..894defa
--- /dev/null
+++ b/Source/Kernel/MemoryManager/PageAlloc.ns.h
@@ -0,0 +1,12 @@
+#ifndef DEF_PAGEALLOC_NS_H
+#define DEF_PAGEALLOC_NS_H
+
+#include <Core/common.wtf.h>
+
+namespace PageAlloc {
+ void init();
+ void* alloc(u32int* phys);
+ void free(void *ptr);
+}
+
+#endif
diff --git a/Source/Kernel/MemoryManager/PageDirectory.class.cpp b/Source/Kernel/MemoryManager/PageDirectory.class.cpp
new file mode 100644
index 0000000..f48b0be
--- /dev/null
+++ b/Source/Kernel/MemoryManager/PageDirectory.class.cpp
@@ -0,0 +1,53 @@
+#include "PageDirectory.class.h"
+#include <MemoryManager/PhysMem.ns.h>
+#include <MemoryManager/PageAlloc.ns.h>
+
+PageDirectory::PageDirectory() {
+ tablesPhysical = (u32int*)PageAlloc::alloc(&physicalAddr);
+ for (u32int i = 0; i < 1024; i++) {
+ tables[i] = 0;
+ tablesPhysical[i] = 0;
+ }
+}
+
+PageDirectory::~PageDirectory() {
+ PageAlloc::free((void*)tablesPhysical);
+ for (int i = 0; i < 1024; i++) {
+ if (tables[i] != 0) PageAlloc::free((void*)tables[i]);
+ }
+}
+
+page_t *PageDirectory::getPage(u32int address, bool make) {
+ address /= 0x1000;
+ u32int tableIdx = address / 1024;
+ if (tables[tableIdx] != 0) {
+ return &(tables[tableIdx]->pages[address % 1024]);
+ } else if (make) {
+ u32int tmp;
+ tables[tableIdx] = (page_table_t*)PageAlloc::alloc(&tmp);
+ CMem::memset((u8int*)tables[tableIdx], 0, 0x1000);
+ tablesPhysical[tableIdx] = tmp | 0x07;
+ return &(tables[tableIdx]->pages[address % 1024]);
+ } else {
+ return 0;
+ }
+}
+
+void PageDirectory::allocFrame(u32int address, bool is_user, bool is_writable) {
+ page_t *p = getPage(address, true);
+ if (p != 0) PhysMem::allocFrame(p, is_user, is_writable);
+}
+
+void PageDirectory::freeFrame(u32int address) {
+ page_t *p = getPage(address, false);
+ if (p == 0) return;
+ PhysMem::freeFrame(p);
+}
+
+void PageDirectory::switchTo() {
+ asm volatile("mov %0, %%cr3" :: "r"(physicalAddr));
+ u32int cr0;
+ asm volatile("mov %%cr0, %0" : "=r"(cr0));
+ cr0 |= 0x80000000;
+ asm volatile("mov %0, %%cr0" :: "r"(cr0));
+}
diff --git a/Source/Kernel/MemoryManager/PageDirectory.class.h b/Source/Kernel/MemoryManager/PageDirectory.class.h
new file mode 100644
index 0000000..4591324
--- /dev/null
+++ b/Source/Kernel/MemoryManager/PageDirectory.class.h
@@ -0,0 +1,35 @@
+#ifndef DEF_PAGEDIRECTORY_CLASS_H
+#define DEF_PAGEDIRECTORY_CLASS_H
+
+#include <Core/common.wtf.h>
+
+struct page_t {
+ u32int present : 1;
+ u32int rw : 1;
+ u32int user : 1;
+ u32int accessed : 1;
+ u32int dirty : 1;
+ u32int unused : 7;
+ u32int frame : 20;
+};
+
+struct page_table_t {
+ page_t pages[1024];
+};
+
+struct PageDirectory {
+ page_table_t *tables[1024];
+ u32int *tablesPhysical;
+ u32int physicalAddr;
+
+ PageDirectory();
+ ~PageDirectory();
+ page_t *getPage(u32int address, bool make);
+ void allocFrame(u32int address, bool is_user, bool is_writable);
+ void freeFrame(u32int address);
+ void switchTo();
+};
+
+
+
+#endif
diff --git a/Source/Kernel/MemoryManager/PhysMem.ns.cpp b/Source/Kernel/MemoryManager/PhysMem.ns.cpp
new file mode 100644
index 0000000..a9bfd35
--- /dev/null
+++ b/Source/Kernel/MemoryManager/PhysMem.ns.cpp
@@ -0,0 +1,79 @@
+#include "PhysMem.ns.h"
+#include <Library/Bitset.class.h>
+#include <VTManager/VirtualTerminal.class.h>
+
+PageDirectory* kernelPageDirectory;
+
+namespace PhysMem {
+
+u32int nframes;
+Bitset *frames;
+
+void initPaging(u32int mem_size) {
+ nframes = mem_size / 0x1000;
+
+ frames = new Bitset(nframes);
+
+ kernelPageDirectory = new (Mem::kalloc(sizeof(PageDirectory), true)) PageDirectory();
+
+ u32int i = 0xC0000000;
+ while (i < Mem::placementAddress) {
+ page_t *p2 = kernelPageDirectory->getPage(i, true);
+ allocFrame(p2, true, false);
+ /* /DEBUG_HEX(i); DEBUG(" =>");
+ DEBUG_HEX(p2->frame); DEBUG("."); */
+ i += 0x1000;
+ }
+ //Also map thoses pages at begning of virtual memory
+ for (u32int i = 0; i < (Mem::placementAddress - 0xC0000000) / 0x100000; i++) {
+ kernelPageDirectory->tablesPhysical[i] = kernelPageDirectory->tablesPhysical[768 + i];
+ kernelPageDirectory->tables[i] = kernelPageDirectory->tables[768 + i];
+ }
+ DEBUG_HEX((u32int)kernelPageDirectory->physicalAddr); DEBUG(" is page dir phys addr.");
+ //asm volatile("hlt");
+
+ kernelPageDirectory->switchTo();
+ DEBUG("Paging enabled !");
+
+ Mem::pagingEnabled = true;
+}
+
+void removeTemporaryPages() {
+ for (u32int i = 0; i < (Mem::placementAddress - 0xC0000000) / 0x100000; i++) {
+ kernelPageDirectory->tablesPhysical[i] = 0;
+ kernelPageDirectory->tables[i] = 0;
+ }
+}
+
+void allocFrame(page_t *page, bool is_user, bool is_writable) {
+ if (page->frame != 0) {
+ return;
+ } else {
+ u32int idx = frames->firstFreeBit();
+ if (idx == (u32int) - 1) PANIC("No more free frames !");
+ frames->setBit(idx);
+ page->present = 1;
+ page->user = (is_user ? 1 : 0);
+ page->rw = (is_writable ? 1 : 0);
+ page->frame = idx;
+ }
+}
+
+void freeFrame(page_t *page) {
+ if (page->frame == 0) {
+ return;
+ } else {
+ frames->clearBit(page->frame / 0x1000);
+ page->frame = 0;
+ }
+}
+
+u32int free() {
+ return nframes - frames->usedBits();
+}
+
+u32int total() {
+ return nframes;
+}
+
+}
diff --git a/Source/Kernel/MemoryManager/PhysMem.ns.h b/Source/Kernel/MemoryManager/PhysMem.ns.h
new file mode 100644
index 0000000..258591a
--- /dev/null
+++ b/Source/Kernel/MemoryManager/PhysMem.ns.h
@@ -0,0 +1,19 @@
+#ifndef DEF_PHYSMEM_NS_H
+#define DEF_PHYSMEM_NS_H
+
+#include <MemoryManager/PageDirectory.class.h>
+
+extern PageDirectory* kernelPageDirectory;
+
+namespace PhysMem {
+ void initPaging(u32int mem_size);
+ void removeTemporaryPages();
+
+ void allocFrame(page_t *page, bool is_user, bool is_writable);
+ void freeFrame(page_t *page);
+
+ u32int free();
+ u32int total();
+}
+
+#endif
diff --git a/Source/Kernel/Ressources/logo.cd b/Source/Kernel/Ressources/logo.cd
index 6dbcc41..ef35bd4 100644
--- a/Source/Kernel/Ressources/logo.cd
+++ b/Source/Kernel/Ressources/logo.cd
@@ -1,10 +1,10 @@
char *melonLogo[] = {
-" THE //|| //// ",
-" // || // // //==// // /====/ //| // ",
-" // || // // // // // // // //|| // ",
-" // |// // //==// // // // // || // ",
-" // // // // // // // ||// ",
-" // // //==== // /====/ // |// ",
-" OPERATING SYSTEM "
+" THE //|| //// ",
+" // || // // //==// // /====/ //| // ",
+" // || // // // // // // // //|| // ",
+" // |// // //==// // // // // || // ",
+" // // // // // // // ||// ",
+" // // //==== //=== /====/ // |// ",
+" OPERATING SYSTEM "
};
int melonLogoLines = 7, melonLogoCols = 60;
diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp
new file mode 100644
index 0000000..6ad17b5
--- /dev/null
+++ b/Source/Kernel/SyscallManager/IDT.ns.cpp
@@ -0,0 +1,176 @@
+#include "IDT.ns.h"
+#include <VTManager/VirtualTerminal.class.h>
+#include <DeviceManager/Dev.ns.h>
+
+using namespace Sys; //For outb
+
+extern "C" void isr0();
+extern "C" void isr1();
+extern "C" void isr2();
+extern "C" void isr3();
+extern "C" void isr4();
+extern "C" void isr5();
+extern "C" void isr6();
+extern "C" void isr7();
+extern "C" void isr8();
+extern "C" void isr9();
+extern "C" void isr10();
+extern "C" void isr11();
+extern "C" void isr12();
+extern "C" void isr13();
+extern "C" void isr14();
+extern "C" void isr15();
+extern "C" void isr16();
+extern "C" void isr17();
+extern "C" void isr18();
+extern "C" void isr19();
+extern "C" void isr20();
+extern "C" void isr21();
+extern "C" void isr22();
+extern "C" void isr23();
+extern "C" void isr24();
+extern "C" void isr25();
+extern "C" void isr26();
+extern "C" void isr27();
+extern "C" void isr28();
+extern "C" void isr29();
+extern "C" void isr30();
+extern "C" void isr31();
+
+extern "C" void irq0();
+extern "C" void irq1();
+extern "C" void irq2();
+extern "C" void irq3();
+extern "C" void irq4();
+extern "C" void irq5();
+extern "C" void irq6();
+extern "C" void irq7();
+extern "C" void irq8();
+extern "C" void irq9();
+extern "C" void irq10();
+extern "C" void irq11();
+extern "C" void irq12();
+extern "C" void irq13();
+extern "C" void irq14();
+extern "C" void irq15();
+
+extern "C" void idt_flush(u32int);
+
+extern "C" void interrupt_handler(registers_t regs) {
+ if (regs.int_no < 32) {
+ IDT::handleException(&regs, regs.int_no);
+ } else if (regs.int_no < 48) {
+ Dev::handleIRQ(&regs, (regs.int_no - 32));
+ }
+}
+
+namespace IDT {
+
+idt_entry_t idt_entries[256];
+idt_ptr_t idt_ptr;
+
+void setGate(u8int num, u32int base, u16int sel, u8int flags) {
+ idt_entries[num].base_lo = base & 0xFFFF;
+ idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
+
+ idt_entries[num].sel = sel;
+ idt_entries[num].flags = flags;
+ idt_entries[num].always0 = 0;
+}
+
+void init() {
+ idt_ptr.limit = (sizeof(idt_entry_t) * 256) - 1;
+ idt_ptr.base = (u32int)&idt_entries;
+
+ CMem::memset((u8int*)&idt_entries, 0, sizeof(idt_entry_t) * 256);
+
+ //Remap the IRQ table
+ outb(0x20, 0x11);
+ outb(0xA0, 0x11);
+ outb(0x21, 0x20);
+ outb(0xA1, 0x28);
+ outb(0x21, 0x04);
+ outb(0xA1, 0x02);
+ outb(0x21, 0x01);
+ outb(0xA1, 0x01);
+ outb(0x21, 0x0);
+ outb(0xA1, 0x0);
+
+ setGate(0, (u32int)isr0, 0x08, 0x8E);
+ setGate(1, (u32int)isr1, 0x08, 0x8E);
+ setGate(2, (u32int)isr2, 0x08, 0x8E);
+ setGate(3, (u32int)isr3, 0x08, 0x8E);
+ setGate(4, (u32int)isr4, 0x08, 0x8E);
+ setGate(5, (u32int)isr5, 0x08, 0x8E);
+ setGate(6, (u32int)isr6, 0x08, 0x8E);
+ setGate(7, (u32int)isr7, 0x08, 0x8E);
+ setGate(8, (u32int)isr8, 0x08, 0x8E);
+ setGate(9, (u32int)isr9, 0x08, 0x8E);
+ setGate(10, (u32int)isr10, 0x08, 0x8E);
+ setGate(11, (u32int)isr11, 0x08, 0x8E);
+ setGate(12, (u32int)isr12, 0x08, 0x8E);
+ setGate(13, (u32int)isr13, 0x08, 0x8E);
+ setGate(14, (u32int)isr14, 0x08, 0x8E);
+ setGate(15, (u32int)isr15, 0x08, 0x8E);
+ setGate(16, (u32int)isr16, 0x08, 0x8E);
+ setGate(17, (u32int)isr17, 0x08, 0x8E);
+ setGate(18, (u32int)isr18, 0x08, 0x8E);
+ setGate(19, (u32int)isr19, 0x08, 0x8E);
+ setGate(20, (u32int)isr20, 0x08, 0x8E);
+ setGate(21, (u32int)isr21, 0x08, 0x8E);
+ setGate(22, (u32int)isr22, 0x08, 0x8E);
+ setGate(23, (u32int)isr23, 0x08, 0x8E);
+ setGate(24, (u32int)isr24, 0x08, 0x8E);
+ setGate(25, (u32int)isr25, 0x08, 0x8E);
+ setGate(26, (u32int)isr26, 0x08, 0x8E);
+ setGate(27, (u32int)isr27, 0x08, 0x8E);
+ setGate(28, (u32int)isr28, 0x08, 0x8E);
+ setGate(29, (u32int)isr29, 0x08, 0x8E);
+ setGate(30, (u32int)isr30, 0x08, 0x8E);
+ setGate(31, (u32int)isr31, 0x08, 0x8E);
+
+ setGate(32, (u32int)irq0, 0x08, 0x8E);
+ setGate(33, (u32int)irq1, 0x08, 0x8E);
+ setGate(34, (u32int)irq2, 0x08, 0x8E);
+ setGate(35, (u32int)irq3, 0x08, 0x8E);
+ setGate(36, (u32int)irq4, 0x08, 0x8E);
+ setGate(37, (u32int)irq5, 0x08, 0x8E);
+ setGate(38, (u32int)irq6, 0x08, 0x8E);
+ setGate(39, (u32int)irq7, 0x08, 0x8E);
+ setGate(40, (u32int)irq8, 0x08, 0x8E);
+ setGate(41, (u32int)irq9, 0x08, 0x8E);
+ setGate(42, (u32int)irq10, 0x08, 0x8E);
+ setGate(43, (u32int)irq11, 0x08, 0x8E);
+ setGate(44, (u32int)irq12, 0x08, 0x8E);
+ setGate(45, (u32int)irq13, 0x08, 0x8E);
+ setGate(46, (u32int)irq14, 0x08, 0x8E);
+ setGate(47, (u32int)irq15, 0x08, 0x8E);
+
+ idt_flush((u32int)&idt_ptr);
+}
+
+void handleException(registers_t *regs, int no) {
+ asm volatile("cli;");
+ char* exceptions[] = {
+ "Division by zero", "Debug exception", "Non maskable interrupt",
+ "Breakpoint exception", "'Into detected overflow'", "Out of bounds exception",
+ "Invalid opcode exception", "No coprocessor exception", "Double fault",
+ "Coprocessor segment overrun", "Bad TSS", "Segment not present",
+ "Stack fault", "General protection fault", "Page fault",
+ "Unknown", "Coprocessor fault", "Alignement check exception",
+ "Machine check exception", "", "",
+ "", "", "",
+ "", "", "",
+ "", "", "",
+ "", ""};
+
+ VirtualTerminal *vt = new VirtualTerminal(5, 50, 0, 15);
+ vt->map();
+
+ *vt << "\n Unhandled exception " << (s32int)no << " at " << (u32int)regs->cs << ":" <<
+ (u32int)regs->eip << "\n :: " << exceptions[no];
+
+ asm volatile("hlt");
+}
+
+}
diff --git a/Source/Kernel/SyscallManager/IDT.ns.h b/Source/Kernel/SyscallManager/IDT.ns.h
new file mode 100644
index 0000000..0a79100
--- /dev/null
+++ b/Source/Kernel/SyscallManager/IDT.ns.h
@@ -0,0 +1,32 @@
+#ifndef DEF_IDT_NS_H
+#define DEF_IDT_NS_H
+
+#include <Core/common.wtf.h>
+
+struct registers_t {
+ u32int ds; // Data segment selector
+ u32int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
+ u32int int_no, err_code; // Interrupt number and error code (if applicable)
+ u32int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
+};
+
+namespace IDT {
+ struct idt_entry_t {
+ u16int base_lo;
+ u16int sel;
+ u8int always0;
+ u8int flags;
+ u16int base_hi;
+ }__attribute__((packed));
+
+ struct idt_ptr_t {
+ u16int limit;
+ u32int base;
+ }__attribute__((packed));
+
+ void init();
+ void handleException(registers_t *regs, int no);
+}
+
+#endif
+
diff --git a/Source/Kernel/SyscallManager/IDT.wtf.asm b/Source/Kernel/SyscallManager/IDT.wtf.asm
new file mode 100644
index 0000000..b76d912
--- /dev/null
+++ b/Source/Kernel/SyscallManager/IDT.wtf.asm
@@ -0,0 +1,117 @@
+[GLOBAL idt_flush]
+
+idt_flush:
+ mov eax, [esp + 4]
+ lidt [eax]
+ ret
+
+; **********************************************************
+
+; stuff for handling interrupts
+[EXTERN interrupt_handler]
+
+%macro ISR_NOERRCODE 1
+ [GLOBAL isr%1]
+ isr%1:
+ cli
+ push byte 0
+ push byte %1
+ jmp interrupt_common_stub
+%endmacro
+
+%macro ISR_ERRCODE 1
+ [GLOBAL isr%1]
+ isr%1:
+ cli
+ push byte %1
+ jmp interrupt_common_stub
+%endmacro
+
+%macro IRQ 2
+ global irq%1
+ irq%1:
+ cli
+ push byte 0
+ push byte %2
+ jmp interrupt_common_stub
+%endmacro
+
+; ********************************************************************
+
+ISR_NOERRCODE 0
+ISR_NOERRCODE 1
+ISR_NOERRCODE 2
+ISR_NOERRCODE 3
+ISR_NOERRCODE 4
+ISR_NOERRCODE 5
+ISR_NOERRCODE 6
+ISR_NOERRCODE 7
+ISR_ERRCODE 8
+ISR_NOERRCODE 9
+ISR_ERRCODE 10
+ISR_ERRCODE 11
+ISR_ERRCODE 12
+ISR_ERRCODE 13
+ISR_ERRCODE 14
+ISR_NOERRCODE 15
+ISR_NOERRCODE 16
+ISR_NOERRCODE 17
+ISR_NOERRCODE 18
+ISR_NOERRCODE 19
+ISR_NOERRCODE 20
+ISR_NOERRCODE 21
+ISR_NOERRCODE 22
+ISR_NOERRCODE 23
+ISR_NOERRCODE 24
+ISR_NOERRCODE 25
+ISR_NOERRCODE 26
+ISR_NOERRCODE 27
+ISR_NOERRCODE 28
+ISR_NOERRCODE 29
+ISR_NOERRCODE 30
+ISR_NOERRCODE 31
+
+IRQ 0, 32
+IRQ 1, 33
+IRQ 2, 34
+IRQ 3, 35
+IRQ 4, 36
+IRQ 5, 37
+IRQ 6, 38
+IRQ 7, 39
+IRQ 8, 40
+IRQ 9, 41
+IRQ 10, 42
+IRQ 11, 43
+IRQ 12, 44
+IRQ 13, 45
+IRQ 14, 46
+IRQ 15, 47
+
+; ******************************************************************
+
+interrupt_common_stub:
+ pusha ; Pushes edi,esi,ebp,esp,ebx,edx,ecx,eax
+
+ mov ax, ds ; Lower 16-bits of eax = ds.
+ push eax ; save the data segment descriptor
+
+ mov ax, 0x10 ; load the kernel data segment descriptor
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ call interrupt_handler
+
+ pop eax ; reload the original data segment descriptor
+ mov ds, ax
+ mov es, ax
+ mov fs, ax
+ mov gs, ax
+
+ popa ; Pops edi,esi,ebp...
+ add esp, 8 ; Cleans up the pushed error code and pushed ISR number
+ sti
+ iret
+
diff --git a/Source/Kernel/VTManager/VT.ns.cpp b/Source/Kernel/VTManager/VT.ns.cpp
new file mode 100644
index 0000000..76aeb47
--- /dev/null
+++ b/Source/Kernel/VTManager/VT.ns.cpp
@@ -0,0 +1,32 @@
+#include "VT.ns.h"
+#include <Library/Vector.class.h>
+#include <DeviceManager/Disp.ns.h>
+
+namespace VT {
+
+Vector<VirtualTerminal*> mappedVTs;
+
+void map(VirtualTerminal* vt) {
+ unmap(vt); //Bad things might happen
+ mappedVTs.push(vt);
+}
+
+void unmap(VirtualTerminal* vt) {
+ for (u32int i = 0; i < mappedVTs.size(); i++) {
+ if (mappedVTs[i] == vt) {
+ mappedVTs[i] = mappedVTs.back();
+ mappedVTs.pop();
+ redrawScreen();
+ return;
+ }
+ }
+}
+
+void redrawScreen() {
+ Disp::clear();
+ for (u32int i = 0; i < mappedVTs.size(); i++) {
+ mappedVTs[i]->redraw();
+ }
+}
+
+}
diff --git a/Source/Kernel/VTManager/VT.ns.h b/Source/Kernel/VTManager/VT.ns.h
new file mode 100644
index 0000000..9e6d3ba
--- /dev/null
+++ b/Source/Kernel/VTManager/VT.ns.h
@@ -0,0 +1,14 @@
+#ifndef DEF_VT_NS_H
+#define DEF_VT_NS_H
+
+#include <Core/common.wtf.h>
+#include <VTManager/VirtualTerminal.class.h>
+
+namespace VT {
+ //These should be called only from inside class VirtualTerminal
+ void map(VirtualTerminal* vt);
+ void unmap(VirtualTerminal* vt);
+ void redrawScreen();
+}
+
+#endif
diff --git a/Source/Kernel/VTManager/VirtualTerminal.class.cpp b/Source/Kernel/VTManager/VirtualTerminal.class.cpp
index 6478be4..a0c920b 100644
--- a/Source/Kernel/VTManager/VirtualTerminal.class.cpp
+++ b/Source/Kernel/VTManager/VirtualTerminal.class.cpp
@@ -1,7 +1,8 @@
#include "VirtualTerminal.class.h"
-#include <DisplayManager/Disp.ns.h>
+#include <DeviceManager/Disp.ns.h>
+#include <VTManager/VT.ns.h>
-#define BUFCHR(l, c) m_buff[(l * m_rows) + c]
+#define BUFCHR(l, c) m_buff[((l) * m_cols) + (c)]
VirtualTerminal::VirtualTerminal(u32int rows, u32int cols, u8int fgcolor, u8int bgcolor) {
m_buff = new chr[rows * cols];
@@ -15,6 +16,11 @@ VirtualTerminal::VirtualTerminal(u32int rows, u32int cols, u8int fgcolor, u8int
m_csrlin = 0;
}
+VirtualTerminal::~VirtualTerminal() {
+ if (m_mapped) VT::unmap(this);
+ delete [] m_buff;
+}
+
void VirtualTerminal::setColor(u8int fgcolor, u8int bgcolor) {
if (bgcolor == 0xFF) {
m_color = (m_color & 0xF0) | fgcolor;
@@ -24,6 +30,7 @@ void VirtualTerminal::setColor(u8int fgcolor, u8int bgcolor) {
}
void VirtualTerminal::putChar(u32int row, u32int col, char c) {
+ if (row >= m_rows or col >= m_cols) return;
chr* ch = &BUFCHR(row, col);
ch->c = c;
ch->color = m_color;
@@ -44,10 +51,12 @@ void VirtualTerminal::map(s32int row, s32int col) {
m_mapcol = (col == -1 ? (Disp::textCols() / 2) - (m_cols / 2) : col);
m_mapped = true;
redraw();
+ VT::map(this);
}
void VirtualTerminal::unmap() {
m_mapped = false;
+ VT::unmap(this);
}
void VirtualTerminal::redraw() {
@@ -68,7 +77,8 @@ void VirtualTerminal::scroll() {
for (u32int c = 0; c < m_cols; c++) {
BUFCHR(m_rows - 1, c).c = ' ';
BUFCHR(m_rows - 1, c).color = m_color;
- }
+ }
+ if (m_mapped) redraw();
}
void VirtualTerminal::updateCursor() {
@@ -112,7 +122,7 @@ void VirtualTerminal::put(char c, bool updatecsr) {
m_csrcol = 0;
m_csrlin++;
}
- if (m_csrlin >= m_rows) {
+ while (m_csrlin >= m_rows) {
scroll();
m_csrlin--;
}
diff --git a/Source/Kernel/VTManager/VirtualTerminal.class.h b/Source/Kernel/VTManager/VirtualTerminal.class.h
index 801d009..61e78a7 100644
--- a/Source/Kernel/VTManager/VirtualTerminal.class.h
+++ b/Source/Kernel/VTManager/VirtualTerminal.class.h
@@ -21,6 +21,7 @@ class VirtualTerminal {
public:
VirtualTerminal(u32int rows, u32int cols, u8int fgcolor = 7, u8int bgcolor = 0);
+ ~VirtualTerminal();
void setColor(u8int fgcolor, u8int bgcolor = 0xFF);
void putChar(u32int row, u32int col, char c);