diff options
Diffstat (limited to 'Source/Kernel')
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 Binary files differindex bf1668b..27008ec 100644 --- a/Source/Kernel/Core/.kmain.wtf.cpp.swp +++ b/Source/Kernel/Core/.kmain.wtf.cpp.swp 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 Binary files differindex 5b40f90..a4bbc45 100755 --- a/Source/Kernel/Melon.ke +++ b/Source/Kernel/Melon.ke 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(®s, regs.int_no); + } else if (regs.int_no < 48) { + Dev::handleIRQ(®s, (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); |