diff options
author | Alexis211 <alexis211@gmail.com> | 2009-10-20 19:23:33 +0200 |
---|---|---|
committer | Alexis211 <alexis211@gmail.com> | 2009-10-20 19:23:33 +0200 |
commit | 768ada13917aeda373e6ff5fee21faf90c963746 (patch) | |
tree | 9e26d7d65e1693d1a7f9fd93c9fd33b41d175464 /Source/Kernel | |
parent | 6ec4b3d31080f90393e72989d559cfb76eff6f9d (diff) | |
parent | 9836acd720988af30250c2c1ec18d618664dea4e (diff) | |
download | Melon-768ada13917aeda373e6ff5fee21faf90c963746.tar.gz Melon-768ada13917aeda373e6ff5fee21faf90c963746.zip |
Merge branch 'usermode_syscalls'
Conflicts:
Source/Kernel/Makefile
Diffstat (limited to 'Source/Kernel')
83 files changed, 934 insertions, 1813 deletions
diff --git a/Source/Kernel/Core/CMem.ns.cpp b/Source/Kernel/Core/CMem.ns.cpp deleted file mode 100644 index c2129ec..0000000 --- a/Source/Kernel/Core/CMem.ns.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include <Core/common.wtf.h> - -namespace CMem { - -//Standard C functions -u8int *memcpy(u8int *dest, const u8int *src, int count) { - for (int i = 0; i < count; i++) { - dest[i] = src[i]; - } - return dest; -} - -u8int *memset(u8int *dest, u8int val, int count) { - for (int i = 0; i < count; i++) { - dest[i] = val; - } - return dest; -} - -u16int *memsetw(u16int *dest, u16int val, int count) { - for (int i = 0; i < count; i++) { - dest[i] = val; - } - return dest; -} - -u32int strlen(const char *str) { - u32int i = 0; - while (str[i]) { - i++; - } - return i; -} - -} diff --git a/Source/Kernel/Core/CMem.ns.h b/Source/Kernel/Core/CMem.ns.h deleted file mode 100644 index f0c15da..0000000 --- a/Source/Kernel/Core/CMem.ns.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifdef DEF_COMMON - -#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); - u16int *memsetw(u16int *dest, u16int val, int count); - u32int strlen(const char *str); -} - -#endif - -#endif diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp index c0218d8..c99544b 100644 --- a/Source/Kernel/Core/Sys.ns.cpp +++ b/Source/Kernel/Core/Sys.ns.cpp @@ -1,5 +1,5 @@ //This automatically includes Sys.ns.h -#include <Core/common.wtf.h> +#include <common.h> #include <Core/Log.ns.h> #include <VTManager/SimpleVT.class.h> #include <SyscallManager/IDT.ns.h> @@ -93,7 +93,14 @@ void panic(char *message, registers_t *regs, char *file, u32int line) { vt << "eax=" << (u32int)regs->eax << ", ebx=" << (u32int)regs->ebx << ", ecx=" << (u32int)regs->ecx << ", edx=" << (u32int)regs->edx << "\n"; vt << "int_no=" << (s32int)regs->int_no << ", err_code=" << (u32int)regs->err_code << "\n"; - vt << "eflags=" << (u32int)regs->eflags << ", useresp=" << (u32int)regs->useresp << ", ss=" << (u32int)regs->ss << "\n\n"; + vt << "eflags=" << (u32int)regs->eflags << ", useresp=" << (u32int)regs->useresp << ", ss=" << (u32int)regs->ss << "\n"; + if (regs->int_no == 14) { + u32int cr2; + asm volatile("mov %%cr2, %0" : "=r"(cr2)); + vt << "cr2=" << (u32int)cr2 << "\n"; + } + vt << "\n"; + while (1) asm volatile("cli; hlt"); u32int *v = (u32int*)regs->ebp; diff --git a/Source/Kernel/Core/cppsupport.wtf.cpp b/Source/Kernel/Core/cppsupport.wtf.cpp index bad28f2..2cefc39 100644 --- a/Source/Kernel/Core/cppsupport.wtf.cpp +++ b/Source/Kernel/Core/cppsupport.wtf.cpp @@ -1,5 +1,5 @@ //This file just contains a few methods required for some C++ things to work -#include <Core/types.wtf.h> +#include <types.h> extern "C" void __cxa_pure_virtual() {} //Required when using abstract classes diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index c7b47e1..a8fb002 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -1,6 +1,6 @@ //This file contains the kernel's main procedure -#include <Core/common.wtf.h> +#include <common.h> #include <Core/multiboot.wtf.h> #include <Devices/Display/VGATextOutput.class.h> @@ -18,8 +18,8 @@ #include <MemoryManager/GDT.ns.h> #include <TaskManager/Task.ns.h> #include <SyscallManager/IDT.ns.h> -#include <Library/String.class.h> -#include <Library/ByteArray.class.h> +#include <String.class.h> +#include <ByteArray.class.h> #include <VFS/Part.ns.h> #include <FileSystems/RamFS/RamFS.class.h> #include <VFS/FileNode.class.h> @@ -169,7 +169,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { new KernelShell(cwd); //No need to save that in a var, it is automatically destroyed anyways Log::log(KL_STATUS, "kmain : Kernel shell launched"); - kvt->unmap(); + //kvt->unmap(); while (KernelShell::getInstances() > 0) { Task::currThread()->sleep(100); diff --git a/Source/Kernel/Core/types.wtf.h b/Source/Kernel/Core/types.wtf.h deleted file mode 100644 index ca6f73d..0000000 --- a/Source/Kernel/Core/types.wtf.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef DEF_TYPES_WTF_H -#define DEF_TYPES_WTF_H - -//This file defines base types. It's made to be used also by C programs - -typedef unsigned int addr_t; -typedef unsigned long long u64int; -typedef unsigned int u32int; -typedef unsigned short u16int; -typedef unsigned char u8int; -typedef long long s64int; -typedef int s32int; -typedef short s16int; -typedef char s8int; - -#define U64 unsigned long long -#define S64 long long - -#endif diff --git a/Source/Kernel/DeviceManager/Dev.ns.h b/Source/Kernel/DeviceManager/Dev.ns.h index 7dda56b..aa52e81 100644 --- a/Source/Kernel/DeviceManager/Dev.ns.h +++ b/Source/Kernel/DeviceManager/Dev.ns.h @@ -2,7 +2,7 @@ #define DEF_DEV_NS_H #include <Devices/Device.proto.h> -#include <Library/Vector.class.h> +#include <Vector.class.h> namespace Dev { void handleIRQ(registers_t regs, int irq); diff --git a/Source/Kernel/DeviceManager/Disp.ns.h b/Source/Kernel/DeviceManager/Disp.ns.h index 5a92e69..0eea51d 100644 --- a/Source/Kernel/DeviceManager/Disp.ns.h +++ b/Source/Kernel/DeviceManager/Disp.ns.h @@ -2,7 +2,7 @@ #define DEF_DISP_NS_H #include <Devices/Display/Display.proto.h> -#include <Library/WChar.class.h> +#include <WChar.class.h> namespace Disp { struct mode_t { diff --git a/Source/Kernel/DeviceManager/Kbd.ns.cpp b/Source/Kernel/DeviceManager/Kbd.ns.cpp index 3db0d34..4fbf511 100644 --- a/Source/Kernel/DeviceManager/Kbd.ns.cpp +++ b/Source/Kernel/DeviceManager/Kbd.ns.cpp @@ -1,6 +1,6 @@ #include "Kbd.ns.h" #include <DeviceManager/Dev.ns.h> -#include <Library/Vector.class.h> +#include <Vector.class.h> #include <Devices/Keyboard/Keyboard.proto.h> #include <VTManager/VirtualTerminal.proto.h> #include <Ressources/Keymaps/Keymap.h> diff --git a/Source/Kernel/DeviceManager/Kbd.ns.h b/Source/Kernel/DeviceManager/Kbd.ns.h index 50cd746..2934474 100644 --- a/Source/Kernel/DeviceManager/Kbd.ns.h +++ b/Source/Kernel/DeviceManager/Kbd.ns.h @@ -1,8 +1,8 @@ #ifndef DEF_KBD_NS_H #define DEF_KBD_NS_H -#include <Core/common.wtf.h> -#include <Library/WChar.class.h> +#include <common.h> +#include <WChar.class.h> //Used by variable kbdstatus #define STATUS_SCRL 0x40 diff --git a/Source/Kernel/Devices/Device.proto.h b/Source/Kernel/Devices/Device.proto.h index 4f216ec..b0db514 100644 --- a/Source/Kernel/Devices/Device.proto.h +++ b/Source/Kernel/Devices/Device.proto.h @@ -1,7 +1,7 @@ #ifndef DEF_DEVICE_PROTO_H #define DEF_DEVICE_PROTO_H -#include <Library/String.class.h> +#include <String.class.h> #include <SyscallManager/IDT.ns.h> diff --git a/Source/Kernel/Devices/Display/Display.proto.h b/Source/Kernel/Devices/Display/Display.proto.h index d4bd8fc..2cec616 100644 --- a/Source/Kernel/Devices/Display/Display.proto.h +++ b/Source/Kernel/Devices/Display/Display.proto.h @@ -1,9 +1,9 @@ #ifndef DEF_DISPLAY_PROTO_H #define DEF_DISPLAY_PROTO_H -#include <Core/common.wtf.h> +#include <common.h> #include <Devices/Device.proto.h> -#include <Library/WChar.class.h> +#include <WChar.class.h> class Display : public Device { public: diff --git a/Source/Kernel/Devices/Floppy/FloppyController.class.h b/Source/Kernel/Devices/Floppy/FloppyController.class.h index 2d0104b..a27d853 100644 --- a/Source/Kernel/Devices/Floppy/FloppyController.class.h +++ b/Source/Kernel/Devices/Floppy/FloppyController.class.h @@ -2,7 +2,7 @@ #define DEF_FLOPPYCONTROLLER_CLASS_H #include <Devices/Device.proto.h> -#include <TaskManager/Mutex.class.h> +#include <Mutex.class.h> #define FLOPPY_DMALEN 0x4800 //This is one cylinder diff --git a/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp b/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp index a224bf8..5997841 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp +++ b/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp @@ -112,11 +112,11 @@ bool RamFS::write(FileNode* file, u64int position, u32int length, u8int *data) { m_usedSize -= node->getLength(); m_usedSize += end; - u8int* data = (u8int*)Mem::kalloc(end); + u8int* data = (u8int*)Mem::alloc(end); if (data == 0) return false; //Invalid pointer if (node->m_data != 0) { memcpy(data, node->m_data, node->getLength()); - Mem::kfree(node->m_data); + Mem::free(node->m_data); } node->m_data = data; node->setLength(end); @@ -129,7 +129,7 @@ bool RamFS::truncate(FileNode* file) { if (!m_isWritable) return false; RamFileNode *node = (RamFileNode*) file; - Mem::kfree(node->m_data); + Mem::free(node->m_data); node->setLength(0); node->m_data = 0; @@ -163,7 +163,7 @@ DirectoryNode* RamFS::createDirectory(DirectoryNode* parent, String name) { bool RamFS::remove(DirectoryNode* parent, FSNode* node) { if (node->type() == NT_FILE) { u8int *d = ((RamFileNode*)node)->m_data; - if (d != 0) Mem::kfree(d); + if (d != 0) Mem::free(d); } return true; } diff --git a/Source/Kernel/Library/BasicString.class.cpp b/Source/Kernel/Library/BasicString.class.cpp deleted file mode 100644 index ae89fe4..0000000 --- a/Source/Kernel/Library/BasicString.class.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include <Library/Vector.class.h> - -#define FREE if (m_string != 0) delete m_string; -#define ALLOC m_string = new T[m_length]; -#define VRFY if (m_length == 0) { m_string = NULL; return; } - -using namespace CMem; - -template <typename T> -BasicString<T>::BasicString() { - m_string = NULL; - m_length = 0; -} - -template <typename T> -BasicString<T>::BasicString(const T* string, u32int length) { - m_string = NULL; - affect(string, length); -} - -template <typename T> -BasicString<T>::BasicString(const BasicString<T> &other) { - m_string = NULL; - affect(other); -} - -template <typename T> -BasicString<T>::BasicString(const T value, u32int count) { - m_string = NULL; - affect(value, count); -} - -template <typename T> -BasicString<T>::~BasicString() { - FREE; -} - -template <typename T> -void BasicString<T>::affect(const BasicString<T> &other) { - FREE; - m_length = other.m_length; - VRFY; - ALLOC; - memcpy((u8int*)m_string, (u8int*)(other.m_string), m_length * sizeof(T)); -} - -template <typename T> -void BasicString<T>::affect(const T* string, u32int length) { - FREE; - m_length = length; - VRFY; - ALLOC; - memcpy((u8int*)string, (u8int*)string, m_length * sizeof(T)); -} - -template <typename T> -void BasicString<T>::affect(const T value, u32int count) { - FREE; - m_length = count; - VRFY; - ALLOC; - for (u32int i = 0; i < count; i++) { - m_string[i] = value; - } -} - -template <typename T> -bool BasicString<T>::compare(const BasicString<T> &other) const { - 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; -} - -template <typename T> -bool BasicString<T>::compare(const T* string, u32int length) const { - if (m_length != length) return false; - for (u32int i = 0; i < m_length; i++) { - if (m_string[i] != string[i]) return false; - } - return true; -} - -template <typename T> -BasicString<T> &BasicString<T>::append(const BasicString<T> &other) { - T* newdata = new T[m_length + other.m_length]; - 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]; - } - FREE; - m_string = newdata; - m_length += other.m_length; - return *this; -} - -template <typename T> -BasicString<T> &BasicString<T>::append(const T* string, u32int length) { - T* newdata = new T[m_length + length]; - for (u32int i = 0; i < m_length; i++) { - newdata[i] = m_string[i]; - } - for (u32int i = 0; i < length; i++) { - newdata[i + m_length] = string[i]; - } - FREE; - m_string = newdata; - m_length += length; - return *this; -} - -template <typename T> -BasicString<T> &BasicString<T>::append(const T other) { - T* newdata = new T[m_length + 1]; - for (u32int i = 0; i < m_length; i++) { - newdata[i] = m_string[i]; - } - FREE; - m_string = newdata; - m_string[m_length] = other; - m_length++; - return *this; -} - -template <typename T> -BasicString<T> BasicString<T>::concat(const BasicString<T> &other) const { - BasicString<T> ret(*this); - return (ret.append(other)); -} - -template <typename T> -BasicString<T> BasicString<T>::concat(const T* string, u32int length) const { - BasicString<T> ret(*this); - return (ret.append(string, length)); -} - -template <typename T> -BasicString<T> BasicString<T>::concat(const T other) const { - BasicString<T> ret(*this); - return (ret.append(other)); -} - -template <typename T> -void BasicString<T>::clear() { - FREE; - m_string = 0; - m_length = 0; -} - -template <typename T> -Vector< BasicString<T> > BasicString<T>::split(T sep) const { - Vector< BasicString<T> > ret; - ret.push(BasicString<T>()); - for (u32int i = 0; i < m_length; i++) { - if (m_string[i] == sep) { - ret.push(BasicString<T>()); - } else { - ret.back().append(m_string[i]); - } - } - return ret; -} - -template <typename T> -BasicString<T> BasicString<T>::substr(s32int start, u32int size) { - if (start < 0) start = m_length - start; - BasicString<T> ret; - ret.m_string = new T[size + 1]; - ret.m_length = size; - memcpy((u8int*)ret.m_string, (u8int*)(&m_string[start]), size * sizeof(T)); - return ret; -} diff --git a/Source/Kernel/Library/BasicString.class.h b/Source/Kernel/Library/BasicString.class.h deleted file mode 100644 index 5c69d00..0000000 --- a/Source/Kernel/Library/BasicString.class.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef DEF_BASICSTRING_CLASS_H -#define DEF_BASICSTRING_CLASS_H - -#include <Core/common.wtf.h> - -template <typename T> class Vector; - -template <typename T> -class BasicString { - protected: - T *m_string; - u32int m_length; - - public: - BasicString(); - BasicString(const T* string, u32int length); - BasicString(const BasicString<T> &other); - BasicString(const T, u32int count = 1); - virtual ~BasicString(); - - void affect(const BasicString<T> &other); - void affect(const T* string, u32int length); - void affect(const T value, u32int count = 1); - void operator= (const BasicString<T> &other) { affect(other); } - - bool compare(const BasicString<T> &other) const; - bool compare(const T* string, u32int length) const; - bool operator== (const BasicString<T> &other) const { return compare(other); } - bool operator!= (const BasicString<T> &other) const { return !compare(other); } - - BasicString<T>& append(const BasicString<T> &other); - BasicString<T>& append(const T* string, u32int length); - BasicString<T>& append(const T other); - BasicString<T>& operator+= (const BasicString<T> &other) { return append(other); } - BasicString<T>& operator+= (const T other) { return append(other); } - - BasicString<T> concat(const BasicString<T> &other) const; - BasicString<T> concat(const T* string, u32int length) const; - BasicString<T> concat(const T other) const; - - T& operator[] (int index) const { return m_string[index]; } - - u32int size() const { return m_length; } - void clear(); - bool empty() const { return m_length == 0; } - - Vector< BasicString<T> > split(T sep) const; - BasicString<T> substr(s32int start, u32int size); -}; - -#include "BasicString.class.cpp" - -#endif diff --git a/Source/Kernel/Library/Bitset.class.cpp b/Source/Kernel/Library/Bitset.class.cpp deleted file mode 100644 index ec4e62c..0000000 --- a/Source/Kernel/Library/Bitset.class.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#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 deleted file mode 100644 index 75fde24..0000000 --- a/Source/Kernel/Library/Bitset.class.h +++ /dev/null @@ -1,31 +0,0 @@ -#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/ByteArray.class.cpp b/Source/Kernel/Library/ByteArray.class.cpp deleted file mode 100644 index 9972493..0000000 --- a/Source/Kernel/Library/ByteArray.class.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "ByteArray.class.h" - -//Define size of a uchar_repr_t -#define CHARSZ(x) (x.c[0] == 0 ? 0 : (x.c[1] == 0 ? 1 : (x.c[2] == 0 ? 2 : (x.c[3] == 0 ? 3 : 4)))) - -using namespace CMem; - -ByteArray::ByteArray(const char* c) : BasicString<u8int>() { - m_length = strlen(c); - memcpy(m_string, (u8int*)c, m_length); -} - -void ByteArray::affect(const String &string, u8int encoding) { - m_length = 0; - for (u32int i = 0; i < string.size(); i++) { - uchar_repr_t a = string[i].encode(encoding); - m_length += CHARSZ(a); - } - if (m_string != 0) delete m_string; - if (m_length == 0) { - m_string = 0; - return; - } - m_string = new u8int[m_length]; - u32int x = 0; - for (u32int i = 0; i < string.size(); i++) { - uchar_repr_t a = string[i].encode(encoding); - memcpy(m_string + x, (u8int*)a.c, CHARSZ(a)); - x += CHARSZ(a); - } -} - -void ByteArray::resize(u32int size) { - if (size == m_length) return; - if (size == 0) { - delete m_string; - m_length = 0; - m_string = 0; - } - u8int *nd = new u8int[size]; - if (size < m_length) { - memcpy(nd, m_string, size); - } else { - memcpy(nd, m_string, m_length); - memset(nd + m_length, 0, size - m_length); - } - delete m_string; - m_string = nd; - m_length = size; -} - -void ByteArray::dump(VirtualTerminal *vt) { - vt->hexDump(m_string, m_length); -} - -String ByteArray::toString (u8int encoding) { - char* c = new char[m_length + 1]; - memcpy((u8int*)c, m_string, m_length); - c[m_length] = 0; //Add NULL terminator - String r(c, encoding); - delete c; - return r; -} diff --git a/Source/Kernel/Library/ByteArray.class.h b/Source/Kernel/Library/ByteArray.class.h deleted file mode 100644 index a6d594f..0000000 --- a/Source/Kernel/Library/ByteArray.class.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef DEF_BYTEARRAY_CLASS_H -#define DEF_BYTEARRAY_CLASS_H - -#include <Library/String.class.h> -#include <VTManager/VirtualTerminal.proto.h> - -class ByteArray : public BasicString<u8int> { - public: - ByteArray() : BasicString<u8int>() {} - ByteArray(const BasicString<u8int> &bs) : BasicString<u8int>() { - m_length = bs.size(); - m_string = new u8int[m_length]; - for (u32int i = 0; i < m_length; i++) - m_string[i] = bs[i]; - } - ByteArray(const ByteArray& other) : BasicString<u8int>(other) {} - ByteArray(const char* c); - ByteArray(u32int size) : BasicString<u8int>((u8int)0, size) {} - ByteArray(const String &string, u8int encoding = UE_UTF8) : BasicString<u8int>() { affect(string, encoding); } - - void affect(const String& string, u8int encoding = UE_UTF8); - void resize(u32int size); - - void dump(VirtualTerminal *vt); - - String toString(u8int encoding = UE_UTF8); - operator u8int* () { return m_string; } -}; - -#endif diff --git a/Source/Kernel/Library/OrderedArray.class.cpp b/Source/Kernel/Library/OrderedArray.class.cpp deleted file mode 100644 index 8b8f24f..0000000 --- a/Source/Kernel/Library/OrderedArray.class.cpp +++ /dev/null @@ -1,54 +0,0 @@ -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 deleted file mode 100644 index 2a5acdd..0000000 --- a/Source/Kernel/Library/OrderedArray.class.h +++ /dev/null @@ -1,29 +0,0 @@ -#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/Rand.ns.cpp b/Source/Kernel/Library/Rand.ns.cpp deleted file mode 100644 index e568678..0000000 --- a/Source/Kernel/Library/Rand.ns.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "Rand.ns.h" - -namespace Rand { - -u32int m = 2073741824, a = 50000, b = 1534; -u64int current = RANDOM_SEED; - -u64int rand() { - current = (u32int)(a*current + b); - while (current > m) current -= m; - return current; -} - -u64int max() { - return m; -} - -} diff --git a/Source/Kernel/Library/Rand.ns.h b/Source/Kernel/Library/Rand.ns.h deleted file mode 100644 index 3598de0..0000000 --- a/Source/Kernel/Library/Rand.ns.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef DEF_RAND_NS_H -#define DEF_RAND_NS_H - -#include <Core/common.wtf.h> - -namespace Rand { - u64int rand(); - u64int max(); -} - -#endif - diff --git a/Source/Kernel/Library/SimpleList.class.h b/Source/Kernel/Library/SimpleList.class.h deleted file mode 100644 index 64e37aa..0000000 --- a/Source/Kernel/Library/SimpleList.class.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef DEF_SIMPLELIST_CLASS_H -#define DEF_SIMPLELIST_CLASS_H - -/* This class implements a singly linked list. It is also used to represent one of its elements. */ - -template <typename T> -class SimpleList { - protected: - T m_value; - SimpleList<T>* m_next; - - public: - SimpleList(const T& value, SimpleList<T>* next = 0) : m_value(value), m_next(next) {} - ~SimpleList() { - if (m_next != 0) - delete m_next; - } - - T& v() { return m_value; } - T& operator* () { return m_value; } - - SimpleList<T>* cons(const T& value) { - return new SimpleList<T>(value, this); - } - - SimpleList<T>* next() { - return m_next; - } - - SimpleList<T>* last() { - if (m_next == 0) return this; - return m_next->last(); - } - - SimpleList<T>* delThis() { - SimpleList<T>* ret = m_next; - Mem::kfree(this); - return ret; - } - - void delNext() { - if (m_next == 0) return; - SimpleList<T>* temp = m_next; - m_next = m_next->m_next; - Mem::kfree(temp); - } - - SimpleList<T>* removeOnce(const T& value) { - if (value == m_value) return delThis(); - for (SimpleList<T> *iter = this; iter->next() != 0; iter = iter->next()) { - if (iter->next()->v() == value) { - iter->delNext(); - break; - } - } - return this; - } - - bool isEnd() { - return m_next == 0; - } - - u32int size() { - if (m_next == 0) - return 0; - return m_next->size() + 1; - } -}; - -#endif diff --git a/Source/Kernel/Library/String.class.cpp b/Source/Kernel/Library/String.class.cpp deleted file mode 100644 index 693a11a..0000000 --- a/Source/Kernel/Library/String.class.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#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 = new WChar[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 = new WChar[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(const char* string, u8int encoding) { - m_string = 0; - m_length = 0; - affect(string, encoding); -} - -void String::affect (const char* string, u8int encoding) { - m_length = WChar::utfLen(string, encoding); - if (m_string != 0) delete [] m_string; - if (m_length == 0) { - m_string = 0; - return; - } - m_string = new WChar[m_length + 1]; - int i = 0, l = strlen(string), c = 0; - while (i < l) { - i += m_string[c].affect(string + i, encoding); - c++; - } - m_string[m_length] = 0; -} - -bool String::compare (const char* string, u8int encoding) const { - if (m_length != WChar::utfLen(string, encoding)) return false; - int i = 0, l = strlen(string), c = 0; - WChar tmp; - while (i < l) { - i += tmp.affect(string + i, encoding); - if (m_string[c] != tmp) return false; - c++; - } - return true; -} - -String& String::append (const char* other, u8int encoding) { - WChar* newdata = new WChar[m_length + WChar::utfLen(other, encoding) + 1]; - for (u32int i = 0; i < m_length; i++) { - newdata[i] = m_string[i]; - } - int i = 0, l = strlen(other), c = 0; - while (i < l) { - i += newdata[c + m_length].affect(other + i, encoding); - c++; - } - if (m_string != 0) delete [] m_string; - m_string = newdata; - m_length += strlen(other); - m_string[m_length] = 0; - return *this; -} - -String String::concat (const String &other) const { //Can be optimized - String ret(*this); - return (ret += other); -} - -String String::concat (const char* other, u8int encoding) const { //Can be optimized - String ret(*this); - return (ret.append(other, encoding)); -} - -String String::concat (WChar other) const { - String ret(*this); - return (ret += other); -} - -s64int String::toInt() const { - if (m_string == 0) return 0; - s32int pos = 0; - s64int number = 0; - bool negative = false; - if (m_string[0].value == '-') { - negative = true; - pos = 1; - } - while (m_string[pos] >= '0' && m_string[pos] <= '9') { - number *= 10; - number += (m_string[pos].value - '0'); - pos++; - } - if (negative) return 0 - number; - return number; -} - -u64int String::toInt16() const { - if (m_string == 0) return 0; - u32int pos = 0; - u64int number = 0; - if (m_string[0].value == '0' && m_string[1].value == '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; -} - -Vector<String> String::split(WChar c) const { - 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, u32int size) { - if (start < 0) start = m_length - start; - String ret; - ret.m_string = new WChar[size + 1]; - ret.m_length = size; - memcpy((u8int*)ret.m_string, (const u8int*)(m_string + start), size * sizeof(WChar)); - ret.m_string[size] = 0; - return ret; -} diff --git a/Source/Kernel/Library/String.class.h b/Source/Kernel/Library/String.class.h deleted file mode 100644 index db274c9..0000000 --- a/Source/Kernel/Library/String.class.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef DEF_STRING_CLASS -#define DEF_STRING_CLASS - -#include <Core/common.wtf.h> -#include <Library/WChar.class.h> -#include <Library/BasicString.class.h> - -class String : public BasicString<WChar> { - public: - static String hex(u32int number); - static String number(s32int number); - - String(const char* string, u8int encoding = UE_UTF8); - String() : BasicString<WChar>() {} - String(const String &other) : BasicString<WChar> (other) {} - - void affect(const char* string, u8int encoding = UE_UTF8); - void operator= (const char* other) { affect(other); } - void operator= (const String& other) { BasicString<WChar>::affect(other); } - - bool compare(const char* string, u8int encoding = UE_UTF8) const; - bool operator== (const char* other) const { return compare(other); } - bool operator!= (const char* other) { return !compare(other); } - bool operator== (const String& other) const { return BasicString<WChar>::compare(other); } - bool operator!= (const String& other) const { return !BasicString<WChar>::compare(other); } - - String& append(const char* other, u8int encoding = UE_UTF8); - String &operator+= (const String &other) { BasicString<WChar>::append(other); return *this; } - String &operator+= (const char* other) { return append(other); } - String &operator+= (WChar other) { BasicString<WChar>::append(other); return *this; } - - String concat(const String &other) const; - String concat(const char* other, u8int encoding = UE_UTF8) const; - String concat(WChar other) const; - String operator+ (const String &other) const { return concat(other); } - String operator+ (const char* other) const { return concat(other); } - String operator+ (WChar other) const { return concat(other); } - - s64int toInt() const; //Convert from DEC - u64int toInt16() const; //Convert from HEX - - Vector<String> split(WChar c) const; - - String substr(s32int start, u32int size); -}; - -#endif diff --git a/Source/Kernel/Library/Vector.class.cpp b/Source/Kernel/Library/Vector.class.cpp deleted file mode 100644 index 02ae9be..0000000 --- a/Source/Kernel/Library/Vector.class.cpp +++ /dev/null @@ -1,135 +0,0 @@ -using namespace CMem; //strlen and memcpy - -#define DELDATA if (m_data != NULL and m_size != 0) { \ - for (u32int i = 0; i < m_size; i++) { \ - m_data[i].~T(); \ - } \ - Mem::kfree(m_data); \ -} - -template <typename T> -Vector<T>::Vector() { - //DEBUG_HEX((u32int)this); DEBUG(" NEW EMPTY"); - //DEBUG_HEX(sizeof(T)); DEBUG(" sizeof(T)"); - m_data = 0; - m_size = 0; -} - -template <typename T> -Vector<T>::Vector(u32int size) { - //DEBUG_HEX((u32int)this); DEBUG(" NEW ZERO"); - m_data = new T[size]; - m_size = size; -} - -template <typename T> -Vector<T>::Vector(u32int size, const T& value) { - //DEBUG_HEX((u32int)this); DEBUG(" NEW FILLED"); - //m_data = (T*)Mem::kalloc(size * sizeof(T)); - m_data = new T[size]; - m_size = size; - for (u32int i = 0; i < m_size; i++) { - new (&m_data[i]) T(value); - } - /*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) { - //DEBUG_HEX((u32int)this); DEBUG(" COPY REF"); - 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<T>::operator= (const Vector<T> &other) { - //DEBUG_HEX((u32int)this); DEBUG(" COPY EQ"); - DELDATA; - 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]); - } - return *this; -} - -template <typename T> -Vector<T>::~Vector() { - //DEBUG_HEX((u32int)this); DEBUG(" DELETE"); - DELDATA; - //if (m_data != 0) delete[] m_data; -} - -template <typename T> -T& Vector<T>::operator[] (u32int index) const { - return m_data[index]; -} - -template <typename T> -void Vector<T>::push(const T& element) { - T* newdata = (T*)Mem::kalloc((m_size + 1) * sizeof(T)); - if (m_size != 0 and m_data != 0) { - memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T)); - } - new(&newdata[m_size]) T(element); //Construct by copy - //newdata[m_size] = element; - 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() const { - return m_data[m_size - 1]; -} - -template <typename T> -T& Vector<T>::front() const { - return m_data[0]; -} - - -template <typename T> -u32int Vector<T>::size() const { - return m_size; -} - -template <typename T> -bool Vector<T>::empty() const { - return m_size == 0; -} - -template <typename T> -void Vector<T>::clear() { - if (empty()) return; - DELDATA - m_data = 0; - m_size = 0; -} diff --git a/Source/Kernel/Library/Vector.class.h b/Source/Kernel/Library/Vector.class.h deleted file mode 100644 index 61c26a4..0000000 --- a/Source/Kernel/Library/Vector.class.h +++ /dev/null @@ -1,36 +0,0 @@ -#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, const T& value); - Vector(const Vector<T> &other); - Vector<T>& operator= (const Vector<T> &other); - ~Vector(); - - T& operator[] (u32int index) const; - - void push(const T& element); - //void push(T& element); - void pop(); - - T& back() const; - T& front() const; - - u32int size() const; - bool empty() const; - void clear(); -}; - -#include "Vector.class.cpp" - -#endif diff --git a/Source/Kernel/Library/WChar.class.cpp b/Source/Kernel/Library/WChar.class.cpp deleted file mode 100644 index ee42849..0000000 --- a/Source/Kernel/Library/WChar.class.cpp +++ /dev/null @@ -1,151 +0,0 @@ -#include "WChar.class.h" - -#ifdef THIS_IS_MELON -using namespace CMem; -#endif - -WChar WChar::CP437[] = { //These are the UTF8 equivalents for the 128 extra characters of code page 437 - "Ç", "ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å", - "É", "æ", "Æ", "ô", "ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "₧", "ƒ", - "á", "í", "ó", "ú", "ñ", "Ñ", "ª", "º", "¿", "⌐", "¬", "½", "¼", "¡", "«", "»", - "░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣", "║", "╗", "╝", "╜", "╛", "┐", - "└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠", "═", "╬", "¤", - "╨", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀", - "α", "ß", "Γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩", - "≡", "±", "≥", "≤", "⌠", "⌡", "÷", "≈", "°", "∙", "·", "√", "ⁿ", "²", "■", "⍽" -}; - -WChar::WChar() { - value = 0; -} - -WChar::WChar(char c) { - affectAscii(c); -} - -WChar::WChar(const char* c, u8int encoding) { - if (encoding == UE_UTF8) affectUtf8(c); - if (encoding == UE_UTF16) affectUtf16(c); - if (encoding == UE_UTF32) affectUtf32(c); -} - -u32int WChar::ucharLen(const char* c, u8int encoding) { - if (encoding == UE_UTF8) { - if ((c[0] & 0x80) == 0) return 1; - else if ((c[0] & 0xE0) == 0xC0) return 2; - else if ((c[0] & 0xF0) == 0xE0) return 3; - else if ((c[0] & 0xF8) == 0xF0) return 4; - else return 1; - } else if (encoding == UE_UTF16) { - if ((c[0] & 0xFC) == 0xD8 and (c[2] & 0xFC) == 0xDC) return 4; - else return 2; - } else if (encoding == UE_UTF32) { - return 4; - } - return 1; -} - -u32int WChar::utfLen(const char* c, u8int encoding) { - int i = 0, l = strlen(c), co = 0; - while (i < l) { - i += ucharLen(c + i, encoding); - co++; - } - return co; -} - -void WChar::affectAscii(char c) { - if (c >= 0) value = c; - else value = CP437[c + 128]; -} - -u32int WChar::affectUtf8(const char* c) { //Returns the number of bytes for the character - if ((c[0] & 0x80) == 0) { - value = c[0]; //0x80 = 10000000b - return 1; - } - if ((c[0] & 0xE0) == 0xC0) { // 11100000b, 11000000b - value = ((c[0] & 0x1F) << 6) | (c[1] & 0x3F); - if (value < 128) value = 0; //Bad value - return 2; - } - if ((c[0] & 0xF0) == 0xE0) { // 11110000b, 11100000b - value = ((c[0] & 0x0F) << 12) | ((c[1] & 0x3F) << 6) | (c[2] & 0x3F); - if (value < 2048) value = 0; //Bad value - if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed - if (value >= 0xFFFE and value <= 0xFFFF) value = 0; - return 3; - } - if ((c[0] & 0xF8) == 0xF0) { // 11111000b, 11110000b - value = ((c[0] & 0x0E) << 18) | ((c[1] & 0x3F) << 12) | ((c[2] & 0x3F) << 6) | (c[3] & 0x3F); - if (value < 65536) value = 0; //Bad value - return 4; - } - value = 0; //Something wrong happenned - return 1; -} - -u32int WChar::affectUtf16(const char* c) { - if ((c[0] & 0xFC) == 0xD8 and // 11111100b, 11011000b - (c[2] & 0xFC) == 0xDC) { // 11111100b, 11011100b - u32int w = ((c[0] & 0x03) << 2) | ((c[1] & 0xC0) >> 6); - u32int x = (c[1] & 0x3F); - u32int y = ((c[2] & 0x03) << 8) | (c[2]); - value = ((w + 1) << 16) | (x << 10) | y; - if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed - if (value >= 0xFFFE and value <= 0xFFFF) value = 0; - return 4; - } else { - value = (c[0] << 8) | (c[1]); - if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed - if (value >= 0xFFFE and value <= 0xFFFF) value = 0; - return 2; - } -} - -u32int WChar::affectUtf32(const char* c) { - value = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; - if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed - if (value >= 0xFFFE and value <= 0xFFFF) value = 0; - return 4; -} - -u8int WChar::toAscii() { - if (value < 128) return (char)value; - for (int i = 0; i < 128; i++) { - if (CP437[i] == value) return (i + 128); - } - return '?'; -} - -uchar_repr_t WChar::toUtf8() { - uchar_repr_t r; - r.i = 0; - if (value < 128) { - r.c[0] = value; - } else if (value < 4096) { - r.c[0] = 0xC0 | ((value & 0x07C0) >> 6); - r.c[1] = 0x80 | (value & 0x3F); - } else if (value < 65536) { - r.c[0] = 0xE0 | ((value & 0xF000) >> 12); - r.c[1] = 0x80 | ((value & 0x0FC0) >> 6); - r.c[2] = 0x80 | (value & 0x003F); - } else { - r.c[0] = 0xF0 | ((value & 0x1C0000) >> 18); - r.c[1] = 0x80 | ((value & 0x3F000) >> 12); - r.c[2] = 0x80 | ((value & 0x0FC0) >> 6); - r.c[3] = 0x80 | (value & 0x003F); - } - return r; -} - -//TODO : code WChar::toUtf16 - -uchar_repr_t WChar::toUtf32() { - uchar_repr_t r; - r.c[0] = (value >> 24) & 0xFF; - r.c[1] = (value >> 16) & 0xFF; - r.c[2] = (value >> 8) & 0xFF; - r.c[3] = value & 0xFF; - return r; -} diff --git a/Source/Kernel/Library/WChar.class.h b/Source/Kernel/Library/WChar.class.h deleted file mode 100644 index e4da603..0000000 --- a/Source/Kernel/Library/WChar.class.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef DEF_UCHAR_CLASS_H -#define DEF_UCHAR_CLASS_H - -#include <Core/types.wtf.h> - -#ifndef THIS_IS_NOT_MELON -#include <Core/common.wtf.h> -#endif - -enum { - UE_UTF8, - UE_UTF16, - UE_UTF32, -}; - -union uchar_repr_t { - char c[4]; - u32int i; -}; - -struct WChar { - u32int value; - static WChar CP437[]; //Codepage 437, used for conversion from/to ascii - - WChar(); //Creates a null character - WChar(char c); //From ascii character - WChar(const char* c, u8int encoding = UE_UTF8); //From utf8 string - - static u32int ucharLen(const char* c, u8int encoding = UE_UTF8); //Returns count of bytes in one unicode character - static u32int utfLen(const char* c, u8int encoding = UE_UTF8); //Returns count of utf8 characters in string - - void affectAscii(char c); - u32int affectUtf8(const char* c); - u32int affectUtf16(const char* c); - u32int affectUtf32(const char* c); - - u32int affect(const char* c, u8int encoding = UE_UTF8) { - if (encoding == UE_UTF8) return affectUtf8(c); - if (encoding == UE_UTF16) return affectUtf16(c); - if (encoding == UE_UTF32) return affectUtf32(c); - affectAscii(c[0]); //Default case :/ - return 1; - } - - u8int toAscii(); - - uchar_repr_t toUtf8(); - uchar_repr_t toUtf16(); - uchar_repr_t toUtf32(); - - uchar_repr_t encode(u8int encoding = UE_UTF8) { - if (encoding == UE_UTF8) return toUtf8(); - //if (encoding == UE_UTF16) return toUtf16(); - if (encoding == UE_UTF32) return toUtf32(); - uchar_repr_t x; - x.c[0] = toAscii(); - return x; - } - - inline WChar operator+ (u32int other) { - WChar r; - r.value = value + other; - return r; - } - inline WChar operator- (u32int other) { - WChar r; - r.value = value - other; - return r; - } - inline WChar& operator+= (u32int other) { - value += other; - return *this; - } - inline WChar& operator-= (u32int other) { - value -= other; - return *this; - } - inline bool operator== (u32int other) { - return value == other; - } - inline u32int operator= (u32int v) { - value = v; - return v; - } - - inline operator u32int () { return value; } -}; - -#endif diff --git a/Source/Kernel/Linker/Binary.proto.cpp b/Source/Kernel/Linker/Binary.proto.cpp new file mode 100644 index 0000000..c0345da --- /dev/null +++ b/Source/Kernel/Linker/Binary.proto.cpp @@ -0,0 +1,21 @@ +#include "Binary.proto.h" + +#include <Linker/MelonBinary.class.h> +#include <Linker/ElfBinary.class.h> + +Binary* (*loaders[])(File& file) = { + &MelonBinary::load, + &ElfBinary::load, +0 }; + +Binary* Binary::load(File& file) { + Binary* r = 0; + u32int i = 0; + while (loaders[i] != 0) { + file.seek(0, SM_BEGINNING); + r = loaders[i](file); //Call loader + if (r != 0) break; + i++; + } + return r; +} diff --git a/Source/Kernel/Linker/Binary.proto.h b/Source/Kernel/Linker/Binary.proto.h new file mode 100644 index 0000000..d0bd039 --- /dev/null +++ b/Source/Kernel/Linker/Binary.proto.h @@ -0,0 +1,16 @@ +#ifndef DEF_BINARY_PROTO_H +#define DEF_BINARY_PROTO_H + +#include <VFS/File.class.h> +#include <TaskManager/Process.class.h> +#include <TaskManager/Thread.class.h> + +class Binary { + public: + static Binary* load(File& file); + virtual ~Binary() {} + + virtual thread_entry_t toProcess(Process* p) = 0; +}; + +#endif diff --git a/Source/Kernel/Linker/ElfBinary.class.cpp b/Source/Kernel/Linker/ElfBinary.class.cpp new file mode 100644 index 0000000..27e5474 --- /dev/null +++ b/Source/Kernel/Linker/ElfBinary.class.cpp @@ -0,0 +1,55 @@ +#include "ElfBinary.class.h" +#include <TaskManager/Task.ns.h> + +ElfBinary::~ElfBinary() { + for (SimpleList<phdr_t> *iter = m_phdr; iter != 0; iter = iter->next()) { + delete iter->v().data; + } +} + +Binary* ElfBinary::load(File& file) { + elf_ehdr_t hdr; + file.read<elf_ehdr_t> (&hdr); + //Verify we have an elf file + if (hdr.e_ident[0] != 0x7F or hdr.e_ident[1] != 'E' or hdr.e_ident[2] != 'L' or hdr.e_ident[3] != 'F') return 0; + + //Store elf header into a new ElfBinary + ElfBinary* b = new ElfBinary(); + memcpy((u8int*)&b->m_ehdr, (const u8int*) &hdr, sizeof(elf_ehdr_t)); + b->m_phdr = 0; + + //Load program headers + file.seek(hdr.e_phoff, SM_BEGINNING); + for (u32int i = 0; i < hdr.e_phnum; i++) { + b->m_phdr = b->m_phdr->cons(phdr_t()); + file.read<elf_phdr_t>(&b->m_phdr->v().h); //Load current entry from file + } + //Load data + for (SimpleList<phdr_t> *iter = b->m_phdr; iter != 0; iter = iter->next()) { + iter->v().data = (u8int*)Mem::alloc(iter->v().h.p_filesz); + file.seek(iter->v().h.p_offset, SM_BEGINNING); + file.read(iter->v().h.p_filesz, iter->v().data); + } + + return b; +} + +thread_entry_t ElfBinary::toProcess(Process* p) { + for (SimpleList<phdr_t> *iter = m_phdr; iter != 0; iter = iter->next()) { + phdr_t &e = iter->v(); + if (e.h.p_type == PT_LOAD) { + for (u32int i = e.h.p_vaddr; i < e.h.p_vaddr + e.h.p_memsz; i += 0x1000) { + p->getPagedir()->allocFrame(i, true, true); + } + p->getPagedir()->switchTo(); + memcpy((u8int*)e.h.p_vaddr, (const u8int*)e.data, e.h.p_filesz); + if (e.h.p_memsz > e.h.p_filesz) { //set to zero all the remaining space + u8int* x = (u8int*)e.h.p_vaddr; + for (u32int i = e.h.p_vaddr + e.h.p_filesz; i < e.h.p_filesz; i++) { + x[i] = 0; + } + } + } + } + return (thread_entry_t)m_ehdr.e_entry; +} diff --git a/Source/Kernel/Linker/ElfBinary.class.h b/Source/Kernel/Linker/ElfBinary.class.h new file mode 100644 index 0000000..1fb9929 --- /dev/null +++ b/Source/Kernel/Linker/ElfBinary.class.h @@ -0,0 +1,68 @@ +#ifndef DEF_ELFBINARY_CLASS_H +#define DEF_ELFBINARY_CLASS_H + +#include <Linker/Binary.proto.h> +#include <SimpleList.class.h> + +/* p_type */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +struct elf_ehdr_t { + u8int e_ident[16]; /* ELF identification */ + u16int e_type; /* 2 (exec file) */ + u16int e_machine; /* 3 (intel architecture) */ + u32int e_version; /* 1 */ + u32int e_entry; /* starting point */ + u32int e_phoff; /* program header table offset */ + u32int e_shoff; /* section header table offset */ + u32int e_flags; /* various flags */ + u16int e_ehsize; /* ELF header (this) size */ + + u16int e_phentsize; /* program header table entry size */ + u16int e_phnum; /* number of entries */ + + u16int e_shentsize; /* section header table entry size */ + u16int e_shnum; /* number of entries */ + + u16int e_shstrndx; /* index of the section name string table */ +}; + +struct elf_phdr_t { + u32int p_type; /* type of segment */ + u32int p_offset; + u32int p_vaddr; + u32int p_paddr; + u32int p_filesz; + u32int p_memsz; + u32int p_flags; + u32int p_align; +}; + +struct phdr_t { + elf_phdr_t h; + u8int* data; +}; + +class ElfBinary : public Binary { + private: + elf_ehdr_t m_ehdr; + SimpleList<phdr_t> *m_phdr; + + ElfBinary() {} + + public: + virtual ~ElfBinary(); + static Binary* load(File& file); + + thread_entry_t toProcess(Process* p); +}; + +#endif diff --git a/Source/Kernel/Linker/MelonBinary.class.cpp b/Source/Kernel/Linker/MelonBinary.class.cpp new file mode 100644 index 0000000..0737b71 --- /dev/null +++ b/Source/Kernel/Linker/MelonBinary.class.cpp @@ -0,0 +1,30 @@ +#include "MelonBinary.class.h" + +Binary* MelonBinary::load(File& file) { + u32int magic; + file.read<u32int>(&magic); + if (magic == 0xFEEDBEEF) { + MelonBinary* r = new MelonBinary; + file.read<u32int>(&r->m_size); + file.read<u32int>(&r->m_org); + r->m_data = (u8int*)Mem::alloc(r->m_size); + file.read(r->m_size, r->m_data); + return r; + } else { + return 0; + } +} + +MelonBinary::~MelonBinary() { + delete m_data; +} + +thread_entry_t MelonBinary::toProcess(Process* p) { + if (p == 0) return 0; + for (u32int i = m_org; i < m_org + m_size; i += 0x1000) { + p->getPagedir()->allocFrame(i, true, true); + } + p->getPagedir()->switchTo(); + memcpy((u8int*)m_org, m_data, m_size); + return (thread_entry_t)m_org; +} diff --git a/Source/Kernel/Linker/MelonBinary.class.h b/Source/Kernel/Linker/MelonBinary.class.h new file mode 100644 index 0000000..4300c7e --- /dev/null +++ b/Source/Kernel/Linker/MelonBinary.class.h @@ -0,0 +1,21 @@ +#ifndef DEF_MELONBINARY_CLASS_H +#define DEF_MELONBINARY_CLASS_H + +#include <Linker/Binary.proto.h> + +class MelonBinary : public Binary { + private: + u32int m_size; + u32int m_org; + u8int* m_data; + + MelonBinary() {} + + public: + virtual ~MelonBinary(); + static Binary* load(File& file); + + thread_entry_t toProcess(Process* p); +}; + +#endif diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 56754d0..55c5fb0 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -5,7 +5,7 @@ CXX = g++ LD = ld LDFLAGS = -T Link.ld -Map Map.txt --oformat=elf32-i386 CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra -Werror -I . -CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON -D RANDOM_SEED=1`date +%N`LL +CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -I ../Library/Common -I ../Library/Interface -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON_KERNEL -D RANDOM_SEED=1`date +%N`LL -g ASM = nasm ASMFLAGS = -f elf @@ -14,11 +14,8 @@ Objects = Core/loader.wtf.o \ Core/kmain.wtf.o \ Core/cppsupport.wtf.o \ Core/Sys.ns.o \ - Core/CMem.ns.o \ Core/Log.ns.o \ MemoryManager/Mem.ns.o \ - MemoryManager/Heap.class.o \ - MemoryManager/Heap-index.class.o \ MemoryManager/PhysMem.ns.o \ MemoryManager/GDT.wtf.o \ MemoryManager/GDT.ns.o \ @@ -32,30 +29,40 @@ Objects = Core/loader.wtf.o \ TaskManager/Thread.class.o \ TaskManager/Task.ns.o \ TaskManager/Task.wtf.o \ - TaskManager/Mutex.class.o \ VTManager/VirtualTerminal.proto.o \ VTManager/SimpleVT.class.o \ VTManager/ScrollableVT.class.o \ VTManager/PipeVT.class.o \ VTManager/FileVT.class.o \ VTManager/VirtualTerminal-kbd.proto.o \ + VTManager/VirtualTerminal-sc.proto.o \ VTManager/VT.ns.o \ Shell/KernelShell.class.o \ Shell/KernelShell-fs.class.o \ Shell/KernelShell-sys.class.o \ - Library/Bitset.class.o \ - Library/String.class.o \ - Library/ByteArray.class.o \ - Library/WChar.class.o \ - Library/Rand.ns.o \ + Linker/Binary.proto.o \ + Linker/MelonBinary.class.o \ + Linker/ElfBinary.class.o \ + ../Library/Common/Bitset.class.o \ + ../Library/Common/String.class.o \ + ../Library/Common/ByteArray.class.o \ + ../Library/Common/WChar.class.o \ + ../Library/Common/Rand.ns.o \ + ../Library/Common/CMem.ns.o \ + ../Library/Common/Heap.class.o \ + ../Library/Common/Heap-index.class.o \ + ../Library/Common/Mutex.class.o \ VFS/Partition.class.o \ VFS/Part.ns.o \ VFS/VFS.ns.o \ + VFS/FSNode-sc.proto.o \ VFS/File.class.o \ VFS/TextFile.class.o \ VFS/DirectoryNode.class.o \ FileSystems/RamFS/RamFS.class.o \ SyscallManager/IDT.ns.o \ + SyscallManager/Ressource.class.o \ + SyscallManager/Res.ns.o \ SyscallManager/IDT.wtf.o \ Devices/Display/VGATextOutput.class.o \ Devices/Keyboard/PS2Keyboard.class.o \ @@ -89,6 +96,7 @@ clean: rm -rf *.o rm -rf */*.o rm -rf */*/*.o + rm -rf ../Library/Common/*.o mrproper: clean echo "* Removing executable : $(OutFile)" diff --git a/Source/Kernel/MemoryManager/GDT.ns.cpp b/Source/Kernel/MemoryManager/GDT.ns.cpp index 0bb606d..f1f5c94 100644 --- a/Source/Kernel/MemoryManager/GDT.ns.cpp +++ b/Source/Kernel/MemoryManager/GDT.ns.cpp @@ -1,6 +1,9 @@ #include "GDT.ns.h" extern "C" void gdt_flush(u32int); +extern "C" void tss_flush(); + +using namespace CMem; //For memset #define GDT_ENTRIES 6 @@ -8,6 +11,7 @@ namespace GDT { gdt_entry_t gdt_entries[GDT_ENTRIES]; gdt_ptr_t gdt_ptr; +tss_entry_t tss_entry; void setGate(s32int num, u32int base, u32int limit, u8int access, u8int gran) { gdt_entries[num].base_low = (base & 0xFFFF); @@ -20,6 +24,22 @@ void setGate(s32int num, u32int base, u32int limit, u8int access, u8int gran) { gdt_entries[num].access = access; } +void writeTSS(s32int num, u16int ss0, u32int esp0) { + u32int base = (u32int)&tss_entry; + u32int limit = base + sizeof(tss_entry); + + setGate(num, base, limit, 0xE9, 0x00); + + memset((u8int*)&tss_entry, 0, sizeof(tss_entry_t)); + + tss_entry.ss0 = ss0; + tss_entry.esp0 = esp0; + + tss_entry.cs = 0x0B; //0x0B = Kernel code segment + RPL=3 (meaning it is supposed to be called from user mode) + //0x13 = Kernel data segment + RPL=3 (meaning to be called from ring3) + tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13; +} + void init() { gdt_ptr.limit = (sizeof(gdt_entry_t) * GDT_ENTRIES) - 1; gdt_ptr.base = (u32int)&gdt_entries; @@ -29,8 +49,10 @@ void init() { 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 + writeTSS(5, 0x10, 0x0); gdt_flush((u32int)&gdt_ptr); + tss_flush(); } } diff --git a/Source/Kernel/MemoryManager/GDT.ns.h b/Source/Kernel/MemoryManager/GDT.ns.h index 7a9f95f..9505433 100644 --- a/Source/Kernel/MemoryManager/GDT.ns.h +++ b/Source/Kernel/MemoryManager/GDT.ns.h @@ -1,7 +1,7 @@ #ifndef DEF_GDT_NS_H #define DEF_GDT_NS_H -#include <Core/common.wtf.h> +#include <common.h> namespace GDT { struct gdt_entry_t { @@ -13,12 +13,44 @@ namespace GDT { u8int base_high; } __attribute__((packed)); + // A struct describing a Task State Segment. + struct tss_entry_t { + u32int prev_tss; // The previous TSS - if we used hardware task switching this would form a linked list. + u32int esp0; // The stack pointer to load when we change to kernel mode. + u32int ss0; // The stack segment to load when we change to kernel mode. + u32int esp1; // Unused... + u32int ss1; + u32int esp2; + u32int ss2; + u32int cr3; + u32int eip; + u32int eflags; + u32int eax; + u32int ecx; + u32int edx; + u32int ebx; + u32int esp; + u32int ebp; + u32int esi; + u32int edi; + u32int es; // The value to load into ES when we change to kernel mode. + u32int cs; // The value to load into CS when we change to kernel mode. + u32int ss; // The value to load into SS when we change to kernel mode. + u32int ds; // The value to load into DS when we change to kernel mode. + u32int fs; // The value to load into FS when we change to kernel mode. + u32int gs; // The value to load into GS when we change to kernel mode. + u32int ldt; // Unused... + u16int trap; + u16int iomap_base; + } __attribute__((packed)); + struct gdt_ptr_t { u16int limit; u32int base; } __attribute__((packed)); void init(); + extern tss_entry_t tss_entry; //Used for setting kernel stack } #endif diff --git a/Source/Kernel/MemoryManager/GDT.wtf.asm b/Source/Kernel/MemoryManager/GDT.wtf.asm index eb216ed..beb668d 100644 --- a/Source/Kernel/MemoryManager/GDT.wtf.asm +++ b/Source/Kernel/MemoryManager/GDT.wtf.asm @@ -15,3 +15,9 @@ gdt_flush: .flush: ret + +[GLOBAL tss_flush] +tss_flush: + mov ax, 0x2B ;entry 5 = 0x28, with RPL=3 + ltr ax + ret diff --git a/Source/Kernel/MemoryManager/Heap-index.class.cpp b/Source/Kernel/MemoryManager/Heap-index.class.cpp deleted file mode 100644 index 3280736..0000000 --- a/Source/Kernel/MemoryManager/Heap-index.class.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "Heap.class.h" - -/* - * Implementation of the functions for managing heap index - */ - -void Heap::insertIntoIndex(heap_header_t *e) { - //If index is full, return - if ((m_index.size * sizeof(heap_header_t*) + (u32int)m_index.data) >= m_start) return; - - u32int iterator = 0; - while (iterator < m_index.size && m_index.data[iterator]->size < e->size) { - if (m_index.data[iterator] == e) return; - iterator++; - } - if (iterator == m_index.size) { - m_index.data[m_index.size++] = e; - } else { - u32int pos = iterator; - iterator = m_index.size; - while (iterator > pos) { - m_index.data[iterator] = m_index.data[iterator - 1]; - iterator--; - } - m_index.size++; - m_index.data[pos] = e; - } -} - -u32int Heap::findIndexEntry(heap_header_t *e) { - for (u32int i = 0; i < m_index.size; i++) { - if (m_index.data[i] == e) - return i; - } - return (u32int) - 1; -} - -void Heap::removeFromIndex(u32int idx) { - m_index.size--; - while (idx < m_index.size) { - m_index.data[idx] = m_index.data[idx + 1]; - idx++; - } -} - -void Heap::removeFromIndex(heap_header_t *e) { - u32int i = findIndexEntry(e); - if (i != (u32int) - 1) { - removeFromIndex(i); - } -} diff --git a/Source/Kernel/MemoryManager/Heap.class.cpp b/Source/Kernel/MemoryManager/Heap.class.cpp deleted file mode 100644 index 7331cd0..0000000 --- a/Source/Kernel/MemoryManager/Heap.class.cpp +++ /dev/null @@ -1,211 +0,0 @@ -#include "Heap.class.h" -#include <MemoryManager/PageDirectory.class.h> - -Heap::Heap() : m_mutex(MUTEX_FALSE) { - m_usable = false; - m_index.data = 0; - m_index.size = 0; -} - -Heap::~Heap() { - //TODO (optionnal) : free pages. -} - -void Heap::create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw) { - if (m_usable) return; - - if (start & 0x0FFF) start = (start & 0xFFFFF000) + 0x1000; - if (size & 0x0FFF) size = (size & 0xFFFFF000) + 0x1000; - m_start = start + idxsize; //m_start is start of real data, start is start of index. - m_end = start + size; - - m_pagedir = pagedir; - m_user = user; - m_rw = rw; - - //Allocate frames for heap - for (u32int i = start ; i < m_end; i += 0x1000) { - m_pagedir->allocFrame(i, m_user, m_rw); - } - - m_index.data = (heap_header_t **)start; //Set index start. start == start of all heap - m_index.size = 0; - - heap_header_t *hole = (heap_header_t*) m_start; //m_start == start of data - hole->size = (m_end - m_start); - hole->magic = HEAP_MAGIC; - hole->is_hole = true; - - heap_footer_t *hole_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t)); - hole_footer->header = hole; - hole_footer->magic = HEAP_MAGIC; - - insertIntoIndex(hole); - - m_usable = true; - m_free = (m_end - m_start); - - m_mutex.unlock(); -} - -void Heap::expand(u32int quantity) { - if (quantity & 0x00000FFF) - quantity = (quantity & 0xFFFFF000) + 0x1000; - - u32int newEnd = m_end + quantity; - - for (u32int i = m_end; i < newEnd; i++) { - m_pagedir->allocFrame(i, m_user, m_rw); - } - - heap_footer_t *last_footer = (heap_footer_t*) (m_end - 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 - removeFromIndex(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; - - insertIntoIndex(last_header); - } else { //Last block is not a hole. Just add a new hole at the end - last_header = (heap_header_t*)m_end; - 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; - - insertIntoIndex(last_header); - } - - m_end = newEnd; - m_free += quantity; -} - -void Heap::contract() { //Automatically work out how much we can contract - heap_footer_t *last_footer = (heap_footer_t*) (m_end - 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 ((m_end - m_start) - 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 = m_end - quantity; - m_free -= quantity; - - removeFromIndex(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; - insertIntoIndex(last_header); - - for (u32int i = newEnd; i < m_end; i += 0x1000) { - m_pagedir->freeFrame(i); - } - - m_end = newEnd; -} - -void *Heap::alloc(u32int sz, bool no_expand) { - m_mutex.waitLock(); - - u32int newsize = sz + sizeof(heap_header_t) + sizeof(heap_footer_t); - u32int iterator = 0; - while (iterator < m_index.size) { - if (m_index.data[iterator]->size >= newsize) break; - iterator++; - } - if (iterator == m_index.size) { //No hole is big enough - if (no_expand) { - m_mutex.unlock(); - return 0; - } - expand((sz & 0xFFFFF000) + 0x1000); - m_mutex.unlock(); - return alloc(sz, true); //Recurse call - } - - heap_header_t *loc = m_index.data[iterator]; - heap_footer_t *footer = (heap_footer_t*)((u32int)loc + loc->size - sizeof(heap_footer_t)); - loc->is_hole = false; //Update current header - - removeFromIndex(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; - - insertIntoIndex(nextloc); - } - - m_free -= loc->size; - - m_mutex.unlock(); - - return (void*)((u32int)loc + sizeof(heap_header_t)); -} - -void Heap::free(void *ptr) { - 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; - - m_mutex.waitLock(); - - m_free += 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; - removeFromIndex(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) { - removeFromIndex(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; - - insertIntoIndex(header); - - if ((u32int)footer == (m_end - sizeof(heap_footer_t)) and - header->size >= 0x2000 and (m_end - m_start > HEAP_MIN_SIZE)) { - contract(); - } - - m_mutex.unlock(); -} diff --git a/Source/Kernel/MemoryManager/Heap.class.h b/Source/Kernel/MemoryManager/Heap.class.h deleted file mode 100644 index 930a589..0000000 --- a/Source/Kernel/MemoryManager/Heap.class.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef DEF_HEAP_CLASS_H -#define DEF_HEAP_CLASS_H - -#include <Core/common.wtf.h> -#include <TaskManager/Mutex.class.h> - -//Heap minimum size : 2M -#define HEAP_MIN_SIZE 0x00200000 -//Heap magic number, for verifications -#define HEAP_MAGIC 0xBEEF1337 - -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; -}; - -class PageDirectory; - -class Heap { - private: - bool m_usable, m_user, m_rw; - u32int m_free, m_start, m_end; - heap_index_t m_index; - PageDirectory* m_pagedir; - - Mutex m_mutex; - - void insertIntoIndex(heap_header_t *e); - u32int findIndexEntry(heap_header_t *e); - void removeFromIndex(u32int idx); - void removeFromIndex(heap_header_t *e); - - void expand(u32int quantity); - void contract(); //Quantity is automatically calculated - - public: - Heap(); - ~Heap(); - - void create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw); - - void* alloc(u32int sz, bool no_expand = false); - void free(void* ptr); - - bool usable() { - m_mutex.waitLock(); - bool ret = m_usable; - m_mutex.unlock(); - return ret; - } - - u32int size() { - m_mutex.waitLock(); - u32int ret = m_end - m_start; - m_mutex.unlock(); - return ret; - } - - u32int free() { - m_mutex.waitLock(); - u32int ret = m_free; - m_mutex.unlock(); - return ret; - } -}; - - -#endif diff --git a/Source/Kernel/MemoryManager/Mem.ns.cpp b/Source/Kernel/MemoryManager/Mem.ns.cpp index b2f2d59..144b9f3 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.cpp +++ b/Source/Kernel/MemoryManager/Mem.ns.cpp @@ -1,6 +1,7 @@ -#include <Core/common.wtf.h> +#include <common.h> #include <MemoryManager/PhysMem.ns.h> -#include <MemoryManager/Heap.class.h> +#include <TaskManager/Task.ns.h> +#include <Heap.class.h> namespace Mem { @@ -19,7 +20,7 @@ void *kallocInternal(u32int sz, bool align) { u32int temp = placementAddress; placementAddress += sz; for (u32int i = temp; i < placementAddress; i += 0x1000) { - if (pagingEnabled) kernelPageDirectory->allocFrame(i, true, false); + if (pagingEnabled) kernelPageDirectory->allocFrame(i, false, false); } return (void*)temp; } @@ -39,17 +40,21 @@ void createHeap() { kheap.create(heapStart, heapSize, heapIndexSize, kernelPageDirectory, false, false); } -void *kalloc(u32int sz, bool align) { +void *alloc(u32int sz, bool align) { if (!kheap.usable()) return kallocInternal(sz, align); if (align) return 0; return kheap.alloc(sz); } -void kfree(void *ptr) { +void free(void *ptr) { kheap.free(ptr); } +void* mkXchgSpace(u32int sz) { + return Task::currThread()->mkXchgSpace(sz); +} + u32int kheapSize() { return kheap.size(); } diff --git a/Source/Kernel/MemoryManager/Mem.ns.h b/Source/Kernel/MemoryManager/Mem.ns.h index 15935c0..b06ab79 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.h +++ b/Source/Kernel/MemoryManager/Mem.ns.h @@ -8,8 +8,10 @@ namespace Mem { extern u32int placementAddress; void createHeap(); - void *kalloc(u32int sz, bool align = false); - void kfree(void *ptr); + void *alloc(u32int sz, bool align = false); + void free(void *ptr); + + void* mkXchgSpace(u32int sz); //This creates a space between userland and kernel land where data can be exchanged u32int kheapSize(), kheapFree(); } diff --git a/Source/Kernel/MemoryManager/PageAlloc.ns.cpp b/Source/Kernel/MemoryManager/PageAlloc.ns.cpp index 34d4f74..d8ede2a 100644 --- a/Source/Kernel/MemoryManager/PageAlloc.ns.cpp +++ b/Source/Kernel/MemoryManager/PageAlloc.ns.cpp @@ -14,7 +14,7 @@ bool usable = false, locked = false; void init() { freec = CACHED_PAGES; for (u32int i = 0; i < CACHED_PAGES; i++) { - freePage[i] = Mem::kalloc(0x1000, true); + freePage[i] = Mem::alloc(0x1000, true); } usable = true; } @@ -26,7 +26,7 @@ void* alloc(u32int* phys) { locked = true; void* next = 0; if (!Mem::pagingEnabled) { - next = Mem::kalloc(0x1000, true); + next = Mem::alloc(0x1000, true); } else { u32int i = 0xFFFFF000; page_t *p; diff --git a/Source/Kernel/MemoryManager/PageAlloc.ns.h b/Source/Kernel/MemoryManager/PageAlloc.ns.h index 894defa..d0b376a 100644 --- a/Source/Kernel/MemoryManager/PageAlloc.ns.h +++ b/Source/Kernel/MemoryManager/PageAlloc.ns.h @@ -1,7 +1,7 @@ #ifndef DEF_PAGEALLOC_NS_H #define DEF_PAGEALLOC_NS_H -#include <Core/common.wtf.h> +#include <common.h> namespace PageAlloc { void init(); diff --git a/Source/Kernel/MemoryManager/PageDirectory.class.h b/Source/Kernel/MemoryManager/PageDirectory.class.h index e06b546..14b78ca 100644 --- a/Source/Kernel/MemoryManager/PageDirectory.class.h +++ b/Source/Kernel/MemoryManager/PageDirectory.class.h @@ -1,7 +1,7 @@ #ifndef DEF_PAGEDIRECTORY_CLASS_H #define DEF_PAGEDIRECTORY_CLASS_H -#include <Core/common.wtf.h> +#include <common.h> struct page_t { u32int present : 1; diff --git a/Source/Kernel/MemoryManager/PhysMem.ns.cpp b/Source/Kernel/MemoryManager/PhysMem.ns.cpp index 382e8a4..1b40e88 100644 --- a/Source/Kernel/MemoryManager/PhysMem.ns.cpp +++ b/Source/Kernel/MemoryManager/PhysMem.ns.cpp @@ -1,5 +1,5 @@ #include "PhysMem.ns.h" -#include <Library/Bitset.class.h> +#include <Bitset.class.h> #include <VTManager/VirtualTerminal.proto.h> PageDirectory* kernelPageDirectory; @@ -14,12 +14,12 @@ void initPaging(u32int mem_size) { frames = new Bitset(nframes); - kernelPageDirectory = new (Mem::kalloc(sizeof(PageDirectory), true)) PageDirectory(); + kernelPageDirectory = new (Mem::alloc(sizeof(PageDirectory), true)) PageDirectory(); u32int i = 0xC0000000; while (i < Mem::placementAddress) { page_t *p2 = kernelPageDirectory->getPage(i, true); - allocFrame(p2, true, false); + allocFrame(p2, false, false); i += 0x1000; } //Also map thoses pages at begning of virtual memory @@ -28,7 +28,6 @@ void initPaging(u32int mem_size) { 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 !"); diff --git a/Source/Kernel/Ressources/Keymaps/Keymap.h b/Source/Kernel/Ressources/Keymaps/Keymap.h index 304e52c..9d1079d 100644 --- a/Source/Kernel/Ressources/Keymaps/Keymap.h +++ b/Source/Kernel/Ressources/Keymaps/Keymap.h @@ -1,4 +1,4 @@ -#include <Library/WChar.class.h> +#include <WChar.class.h> struct melon_keymap_t { WChar normal[128]; diff --git a/Source/Kernel/Ressources/Keymaps/MakeMKM.sh b/Source/Kernel/Ressources/Keymaps/MakeMKM.sh index ac54ce8..056abe2 100755 --- a/Source/Kernel/Ressources/Keymaps/MakeMKM.sh +++ b/Source/Kernel/Ressources/Keymaps/MakeMKM.sh @@ -7,11 +7,11 @@ for KM in `ls | grep cxd`; do echo "#define THIS_IS_NOT_MELON" > kmtemp.cpp echo "#include <cstring>" >> kmtemp.cpp - echo "#include <Library/WChar.class.cpp>" >> kmtemp.cpp + echo "#include <WChar.class.cpp>" >> kmtemp.cpp echo "#include \"$KM\"" >> kmtemp.cpp cat WriteKeymap.cpp >> kmtemp.cpp - g++ kmtemp.cpp -o kmtemp -I ../.. + g++ kmtemp.cpp -o kmtemp -I ../../../Library/Common ./kmtemp done diff --git a/Source/Kernel/Shell/KernelShell-fs.class.cpp b/Source/Kernel/Shell/KernelShell-fs.class.cpp index 3ac7b20..cd52810 100644 --- a/Source/Kernel/Shell/KernelShell-fs.class.cpp +++ b/Source/Kernel/Shell/KernelShell-fs.class.cpp @@ -1,6 +1,8 @@ #include "KernelShell.class.h" #include <VFS/VFS.ns.h> #include <VFS/File.class.h> +#include <TaskManager/Task.ns.h> +#include <MemoryManager/PhysMem.ns.h> void KernelShell::ls(Vector<String>& args) { DirectoryNode* d = m_cwd; @@ -53,11 +55,11 @@ void KernelShell::cat(Vector<String>& args) { for (u32int i = 1; i < args.size(); i++) { File f(args[i], FM_READ, m_cwd); if (f.valid()) { - u8int *buff = (u8int*)Mem::kalloc(f.length() + 1); + u8int *buff = (u8int*)Mem::alloc(f.length() + 1); f.read(f.length(), buff); buff[f.length()] = 0; *m_vt << String((const char*) buff); - Mem::kfree(buff); + Mem::free(buff); } else { *m_vt << "Error reading from file " << args[i] << "\n"; } @@ -102,3 +104,19 @@ void KernelShell::wf(Vector<String>& args) { } } } + +void KernelShell::run(Vector<String>& args) { + if (args.size() == 1) { + *m_vt << "No app to run !\n"; + } else { + Process* p = Process::run(args[1], m_cwd, 0); + if (p == 0) { + *m_vt << "Error while launching process.\n"; + } else { + p->setVirtualTerminal(m_vt); + p->start(); + while (p->getState() != P_FINISHED) Task::currThread()->sleep(10); + delete p; + } + } +} diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index e2fbb69..d90fc4c 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -1,9 +1,10 @@ #include "KernelShell.class.h" #include <VTManager/ScrollableVT.class.h> #include <DeviceManager/Kbd.ns.h> -#include <Library/Rand.ns.h> -#include <Library/SimpleList.class.h> +#include <SimpleList.class.h> +#include <MemoryManager/PhysMem.ns.h> #include <VFS/VFS.ns.h> +#include <TaskManager/Task.ns.h> u32int KernelShell::m_instances = 0; @@ -18,6 +19,7 @@ u32int shellRun(void* ks) { void KernelShell::setup(DirectoryNode* cwd, VirtualTerminal *vt) { m_vt = vt; + Task::currProcess()->setVirtualTerminal(vt); ((ScrollableVT*)m_vt)->map(9); Kbd::setFocus(m_vt); m_cwd = cwd; @@ -51,6 +53,7 @@ u32int KernelShell::run() { {"mkdir", &KernelShell::mkdir}, {"rm", &KernelShell::rm}, {"wf", &KernelShell::wf}, + {"run", &KernelShell::run}, {"devices", &KernelShell::devices}, {"loadkeys", &KernelShell::loadkeys}, diff --git a/Source/Kernel/Shell/KernelShell.class.h b/Source/Kernel/Shell/KernelShell.class.h index 39e1ebd..e7549c2 100644 --- a/Source/Kernel/Shell/KernelShell.class.h +++ b/Source/Kernel/Shell/KernelShell.class.h @@ -4,7 +4,7 @@ #include <VTManager/VirtualTerminal.proto.h> #include <VFS/DirectoryNode.class.h> #include <TaskManager/Thread.class.h> -#include <Library/Vector.class.h> +#include <Vector.class.h> class KernelShell { friend u32int shellRun(void* ks); @@ -26,6 +26,7 @@ class KernelShell { void mkdir(Vector<String>& args); void rm(Vector<String>& args); void wf(Vector<String>& args); + void run(Vector<String>& args); //in KernelShell-sys void devices(Vector<String>& args); diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index fcab741..63b340a 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -2,6 +2,7 @@ #include <VTManager/SimpleVT.class.h> #include <DeviceManager/Dev.ns.h> #include <TaskManager/Task.ns.h> +#include <SyscallManager/Res.ns.h> using namespace Sys; //For outb @@ -55,6 +56,7 @@ extern "C" void irq13(); extern "C" void irq14(); extern "C" void irq15(); +extern "C" void int64(); //Main syscall extern "C" void int65(); //Syscall to request a task switch extern "C" void int66(); //Syscall to signal that thread ended @@ -73,6 +75,23 @@ extern "C" void interrupt_handler(registers_t regs) { Dev::handleIRQ(regs, (regs.int_no - 32)); doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32); } + if (regs.int_no == 64) { + u32int res = (regs.eax >> 8); + u8int wat = (regs.eax & 0xFF); + if (res == 0xFFFFFF) { + if (regs.eax == 0xFFFFFF01) { + Task::currProcess()->getVirtualTerminal()->put(WChar(regs.ebx)); + } else if (regs.eax == 0xFFFFFF02) { + Task::currThread()->sleep(regs.ebx); + } else if (regs.eax == 0xFFFFFF03) { + Task::currProcess()->getVirtualTerminal()->writeHex(regs.ebx); + } + } else { + regs.eax = Res::call(res, wat, regs.ebx, regs.ecx, regs.edx, regs.edi, regs.esi); + } + //Some syscalls have maybee modified current page directory, set it back to one for current process + Task::currProcess()->getPagedir()->switchTo(); + } if (regs.int_no == 66) { //This syscall signals to kernel that thread ended. Task::currentThreadExits(regs.eax); //DO NOT COUNT ON COMMING BACK FROM HERE } @@ -89,7 +108,7 @@ void setGate(u8int num, u32int base, u16int sel, u8int flags) { idt_entries[num].base_hi = (base >> 16) & 0xFFFF; idt_entries[num].sel = sel; - idt_entries[num].flags = flags; + idt_entries[num].flags = flags | 0x60; idt_entries[num].always0 = 0; } @@ -161,6 +180,7 @@ void init() { setGate(46, (u32int)irq14, 0x08, 0x8E); setGate(47, (u32int)irq15, 0x08, 0x8E); + setGate(64, (u32int)int64, 0x08, 0x8E); setGate(65, (u32int)int65, 0x08, 0x8E); setGate(66, (u32int)int66, 0x08, 0x8E); diff --git a/Source/Kernel/SyscallManager/IDT.ns.h b/Source/Kernel/SyscallManager/IDT.ns.h index 52f1ed5..e73a885 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.h +++ b/Source/Kernel/SyscallManager/IDT.ns.h @@ -1,7 +1,7 @@ #ifndef DEF_IDT_NS_H #define DEF_IDT_NS_H -#include <Core/common.wtf.h> +#include <common.h> struct registers_t { u32int ds; // Data segment selector diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp new file mode 100644 index 0000000..048d17a --- /dev/null +++ b/Source/Kernel/SyscallManager/Res.ns.cpp @@ -0,0 +1,75 @@ +#include "Res.ns.h" + +#include <VirtualTerminal.iface.h> +#include <Process.iface.h> +#include <Thread.iface.h> +#include <FSNode.iface.h> +#include <TaskManager/Task.ns.h> + +namespace Res { + +typedef u32int (*staticcall)(u8int, u32int, u32int, u32int, u32int); + +struct static_call_t { + u32int id; + staticcall call; +}; + +static_call_t staticCalls[] = { + {VTIF_OBJTYPE, VirtualTerminal::scall}, + {PRIF_OBJTYPE, Process::scall}, + {THIF_OBJTYPE, Thread::scall}, + {FNIF_OBJTYPE, FSNode::scall}, + {0, 0} +}; + +Ressource** ressources = 0; +u32int size = 0; + +void expand() { //Expands size of ressources array of 20 entries + size += 20; + Ressource** tmp = (Ressource**)Mem::alloc(size * sizeof(Ressource*)); + for (u32int i = 0; i < size; i++) { + if (i < size - 20) tmp[i] = ressources[i]; + else tmp[i] = 0; + } + Mem::free(ressources); + ressources = tmp; +} + +u32int registerRes(Ressource* r) { + if (ressources == 0 or size == 0) { + ressources = (Ressource**)Mem::alloc(20 * sizeof(Ressource*)); + size = 20; + for (u32int i = 0; i < 20; i++) ressources[i] = 0; + } + for (u32int i = 0; i < size; i++) { + if (ressources[i] == 0) { + ressources[i] = r; + return i; + } + } + expand(); + return registerRes(r); +} + +void unregisterRes(u32int id) { + ressources[id] = 0; +} + +u32int call(u32int ressource, u8int wat, u32int a, u32int b, u32int c, u32int d, u32int e) { + if (ressource == 0xFFFFFE) { //TODO : return ressource id for some stuff for current process + for (u32int i = 0; staticCalls[i].id != 0; i++) { + if (staticCalls[i].id == a) return staticCalls[i].call(wat, b, c, d, e); + } + return 0; + } else { + if (ressource > size or ressources[ressource] == 0) { + return (u32int) - 1; + } else { + return ressources[ressource]->doCall(wat, a, b, c, d, e); + } + } +} + +} diff --git a/Source/Kernel/SyscallManager/Res.ns.h b/Source/Kernel/SyscallManager/Res.ns.h new file mode 100644 index 0000000..e454693 --- /dev/null +++ b/Source/Kernel/SyscallManager/Res.ns.h @@ -0,0 +1,15 @@ +#ifndef DEF_RES_NS_H +#define DEF_RES_NS_H + +#include <SyscallManager/Ressource.class.h> + +namespace Res { + +u32int registerRes(Ressource* r); +void unregisterRes(u32int id); + +u32int call(u32int ressource, u8int wat, u32int a, u32int b, u32int c, u32int d, u32int e); + +} + +#endif diff --git a/Source/Kernel/SyscallManager/Ressource.class.cpp b/Source/Kernel/SyscallManager/Ressource.class.cpp new file mode 100644 index 0000000..f2aaccb --- /dev/null +++ b/Source/Kernel/SyscallManager/Ressource.class.cpp @@ -0,0 +1,41 @@ +#include "Ressource.class.h" +#include <SyscallManager/Res.ns.h> + +Ressource::Ressource(u8int type, call_t* callTable) { + m_id = Res::registerRes(this); + m_type = type; + m_callTables = 0; + + addCallTable(callTable); +} + +Ressource::~Ressource() { + Res::unregisterRes(m_id); + delete m_callTables; +} + +void Ressource::addCallTable(call_t* callTable) { + if (callTable != 0) m_callTables = m_callTables->cons(callTable); +} + +u32int Ressource::doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e) { + if (id == 0) return m_type; + + for (SimpleList<call_t*> *iter = m_callTables; iter != 0; iter = iter->next()) { + call_t* ct = iter->v(); + u32int i = 0; + while (ct[i].id != 0) { + call_t &ce = ct[i]; + if (ce.id == id) { + if (ce.params == 0) return (this->*(ce.c0))(); + if (ce.params == 1) return (this->*(ce.c1))(a); + if (ce.params == 2) return (this->*(ce.c2))(a, b); + if (ce.params == 3) return (this->*(ce.c3))(a, b, c); + if (ce.params == 4) return (this->*(ce.c4))(a, b, c, d); + if (ce.params == 5) return (this->*(ce.c5))(a, b, c, d, e); + } + i++; + } + } + return (u32int) - 1; +} diff --git a/Source/Kernel/SyscallManager/Ressource.class.h b/Source/Kernel/SyscallManager/Ressource.class.h new file mode 100644 index 0000000..f58276b --- /dev/null +++ b/Source/Kernel/SyscallManager/Ressource.class.h @@ -0,0 +1,56 @@ +#ifndef DEF_RESSOURCE_CLASS_H +#define DEF_RESSOURCE_CLASS_H + +#include <SimpleList.class.h> + +class Ressource; + +typedef u32int (Ressource::*call0)(); +typedef u32int (Ressource::*call1)(u32int); +typedef u32int (Ressource::*call2)(u32int, u32int); +typedef u32int (Ressource::*call3)(u32int, u32int, u32int); +typedef u32int (Ressource::*call4)(u32int, u32int, u32int, u32int); +typedef u32int (Ressource::*call5)(u32int, u32int, u32int, u32int, u32int); + +#define CALL0(id, ptr) {0, id, {(call0)ptr}} +#define CALL1(id, ptr) {1, id, {c1: (call1)ptr}} +#define CALL2(id, ptr) {2, id, {c2: (call2)ptr}} +#define CALL3(id, ptr) {3, id, {c3: (call3)ptr}} +#define CALL4(id, ptr) {4, id, {c4: (call4)ptr}} +#define CALL5(id, ptr) {5, id, {c5: (call5)ptr}} + +struct call_t { + u8int params; + u8int id; + union { + call0 c0; + call1 c1; + call2 c2; + call3 c3; + call4 c4; + call5 c5; + }; +}; + +class Ressource { + private: + Ressource(const Ressource&); + Ressource& operator=(const Ressource&); + + u32int m_id; + u32int m_type; + SimpleList<call_t*> *m_callTables; + + protected: + Ressource(u8int type, call_t* callTable = 0); + ~Ressource(); + + void addCallTable(call_t* callTable); + + public: + u32int doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e); + u32int resId() { return m_id; } + u32int resType() { return m_type; } +}; + +#endif diff --git a/Source/Kernel/TaskManager/Mutex.class.cpp b/Source/Kernel/TaskManager/Mutex.class.cpp deleted file mode 100644 index 8ba274f..0000000 --- a/Source/Kernel/TaskManager/Mutex.class.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "Mutex.class.h" -#include <TaskManager/Task.ns.h> - -extern "C" u32int atomic_exchange(u32int* ptr, u32int newval); - -Mutex::Mutex(u32int locked) { - m_locked = locked; -} - -bool Mutex::lock() { - if (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) return false; //The lock was already locked - return true; -} - -void Mutex::waitLock() { - while (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) { - if (Task::currThread() != 0) Task::currThread()->sleep(10); //Wait 10ms - else return; - } -} - -void Mutex::unlock() { - m_locked = MUTEX_FALSE; -} - -bool Mutex::locked() { - return m_locked; -} diff --git a/Source/Kernel/TaskManager/Mutex.class.h b/Source/Kernel/TaskManager/Mutex.class.h deleted file mode 100644 index 5545559..0000000 --- a/Source/Kernel/TaskManager/Mutex.class.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef DEF_MUTEX_CLASS_H -#define DEF_MUTEX_CLASS_H - -#include <Core/common.wtf.h> - -#define MUTEX_FALSE 0 -#define MUTEX_TRUE 1 - -class Mutex { - private: - u32int m_locked; - - public: - Mutex(u32int locked = MUTEX_FALSE); - bool lock(); //Locks the mutex if it is not locked. Returns true if mutex could be locked, false if already locked - void waitLock(); //Locks the mutex, waiting for it to be unlocked before if necessary - void unlock(); - bool locked(); -}; - -#endif diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index cf8f00a..a2bbfb4 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -2,12 +2,26 @@ #include <TaskManager/Task.ns.h> #include <MemoryManager/PhysMem.ns.h> #include <VFS/File.class.h> +#include <Linker/Binary.proto.h> +#include <Process.iface.h> namespace Mem { extern Heap kheap; } -Process::Process() { //Private constructor, does nothing +call_t Process::m_callTable[] = { + CALL0(PRIF_EXIT, &Process::exitSC), + CALL1(PRIF_ALLOCPAGE, &Process::allocPageSC), + CALL1(PRIF_FREEPAGE, &Process::freePageSC), + CALL0(0, 0) +}; + +u32int Process::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) { + if (wat == PRIF_SGETCPR) return Task::currProcess()->resId(); + return (u32int) - 1; +} + +Process::Process() : Ressource(PRIF_OBJTYPE, m_callTable) { //Private constructor, does nothing } Process* Process::createKernel(String cmdline, VirtualTerminal *vt) { @@ -35,13 +49,31 @@ Process* Process::createKernel(String cmdline, VirtualTerminal *vt) { return p; } -Process::Process(String cmdline, u32int uid) { +Process* Process::run(String filename, FSNode* cwd, u32int uid) { + File file(filename, FM_READ, cwd); + if (!file.valid()) return 0; + Binary* b = Binary::load(file); + if (b == 0) return 0; + Process* p = new Process(filename, uid); + thread_entry_t e = b->toProcess(p); + delete b; + if (e != 0) { + new Thread(p, e, 0); + return p; + } else { + delete p; + return 0; + } +} + +Process::Process(String cmdline, u32int uid) : Ressource(PRIF_OBJTYPE, m_callTable) { m_pid = Task::nextPid(); m_cmdline = cmdline; m_retval = 0; - m_state = P_RUNNING; + m_state = P_STARTING; m_uid = uid; m_vt = Task::currProcess()->getVirtualTerminal(); + m_fileDescriptors = 0; //Create page directory and user heap m_pagedir = new PageDirectory(kernelPageDirectory); m_pagedir->switchTo(); @@ -56,6 +88,10 @@ Process::~Process() { delete m_userHeap; } +void Process::start() { + if (m_state == P_STARTING) m_state = P_RUNNING; +} + void Process::exit() { for (u32int i = 0; i < m_threads.size(); i++) { delete m_threads[i]; @@ -65,7 +101,7 @@ void Process::exit() { iter->v()->close(false); delete iter->v(); } - delete m_fileDescriptors; //Will recursively delete whole list + if (m_fileDescriptors != 0) delete m_fileDescriptors; //Will recursively delete whole list m_state = P_FINISHED; } @@ -76,7 +112,7 @@ void Process::registerThread(Thread* t) { void Process::threadFinishes(Thread* thread, u32int retval) { // If it is the main thread of the process, or if it pagefaulted - if (thread == m_threads[0] or retval == E_PAGEFAULT) { + if (thread == m_threads[0] or retval == E_PAGEFAULT or retval == E_EXIT) { exit(); } else { //Simply unregister thread @@ -110,3 +146,25 @@ VirtualTerminal* Process::getVirtualTerminal() { void Process::setVirtualTerminal(VirtualTerminal* vt) { m_vt = vt; } + +u32int Process::exitSC() { + if (Task::currProcess() != this) return 1; + Task::currentThreadExits(E_EXIT); + return 0; +} + +u32int Process::allocPageSC(u32int pos) { + if (Task::currProcess() != this) return 1; + if ((pos & 0x00000FFF) != 0) pos = (pos & 0xFFFFF000) + 0x1000; + if (pos >= 0xC0000000) return 1; + m_pagedir->allocFrame(pos, true, true); + return 0; +} + +u32int Process::freePageSC(u32int pos) { + if (Task::currProcess() != this) return 1; + if ((pos & 0x00000FFF) != 0) pos = (pos & 0xFFFFF000) + 0x1000; + if (pos >= 0xC0000000) return 1; + m_pagedir->freeFrame(pos); + return 0; +} diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h index ac9614e..89efd0c 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -1,19 +1,23 @@ #ifndef DEF_PROCESS_CLASS_H #define DEF_PROCESS_CLASS_H -#include <Library/String.class.h> -#include <Library/Vector.class.h> -#include <Library/SimpleList.class.h> +#include <String.class.h> +#include <Vector.class.h> +#include <SimpleList.class.h> #include <MemoryManager/PageDirectory.class.h> -#include <MemoryManager/Heap.class.h> +#include <Heap.class.h> #include <VTManager/VirtualTerminal.proto.h> +#include <VFS/File.class.h> + +#include <SyscallManager/Ressource.class.h> #define P_ZOMBIE 0 #define P_RUNNING 1 -#define P_FINISHED 2 +#define P_STARTING 2 +#define P_FINISHED 3 #define E_PAGEFAULT 0x0FFFFF00 -#define E_ABORTED 0x0FFFFF01 +#define E_EXIT 0x0FFFFF01 #define E_UNHANDLED_EXCEPTION 0x0FFFFF02 #define STACKSIZE 4096 //Could change @@ -24,7 +28,7 @@ class Thread; class File; -class Process { +class Process : public Ressource { friend class Thread; private: @@ -42,14 +46,23 @@ class Process { Vector<Thread*> m_threads; SimpleList<File*> *m_fileDescriptors; + + //System calls + static call_t m_callTable[]; + u32int exitSC(); + u32int allocPageSC(u32int); public: + static u32int scall(u8int, u32int, u32int, u32int, u32int); + static Process* createKernel(String cmdline, VirtualTerminal *vt); //Also creates a Thread for what's curently happening + static Process* run(String filename, FSNode* cwd, u32int uid); Process(String cmdline, u32int uid); ~Process(); Heap& heap() { return *m_userHeap; } + void start(); //Starts thread execution - sets m_state to P_RUNNING if == P_STARTING void exit(); //Exits properly process by killing all threads and deleting file descriptors void registerThread(Thread* t); //Called when a thread starts void threadFinishes(Thread* thread, u32int retval); //Called when a thread finishes @@ -61,7 +74,8 @@ class Process { VirtualTerminal* getVirtualTerminal(); void setVirtualTerminal(VirtualTerminal* vt); - + u32int getState() { return m_state; } + u32int freePageSC(u32int); }; #endif diff --git a/Source/Kernel/TaskManager/Task.ns.cpp b/Source/Kernel/TaskManager/Task.ns.cpp index a34f14f..aef07f3 100644 --- a/Source/Kernel/TaskManager/Task.ns.cpp +++ b/Source/Kernel/TaskManager/Task.ns.cpp @@ -1,5 +1,4 @@ #include "Task.ns.h" -#include <Library/Vector.class.h> #include <MemoryManager/PhysMem.ns.h> #define INVALID_TASK_MAGIC 0xBEEFFEED @@ -94,8 +93,11 @@ void doSwitch() { eip = t->getEip(); cr3 = currentProcess->getPagedir()->physicalAddr; + asm volatile("cli"); + + t->setKernelStack(); + asm volatile(" \ - cli; \ mov %0, %%ebp; \ mov %1, %%esp; \ mov %2, %%ecx; \ @@ -138,6 +140,7 @@ void currThreadExitProceed(u32int errcode) { } void currentThreadExits(u32int errcode) { //Call currThreadExitProceed with a working stack (we use temp_stack) + asm volatile("cli"); u32int* stack = &temp_stack[TEMP_STACK_SIZE]; stack--; *stack = errcode; @@ -146,7 +149,6 @@ void currentThreadExits(u32int errcode) { //Call currThreadExitProceed with a wo u32int esp = (u32int)(stack), ebp = (u32int)(stack + 1), eip = (u32int)currThreadExitProceed; asm volatile(" \ - cli; \ mov %0, %%ebp; \ mov %1, %%esp; \ mov %2, %%ecx; \ diff --git a/Source/Kernel/TaskManager/Task.ns.h b/Source/Kernel/TaskManager/Task.ns.h index c7c3d23..056e4c0 100644 --- a/Source/Kernel/TaskManager/Task.ns.h +++ b/Source/Kernel/TaskManager/Task.ns.h @@ -3,7 +3,7 @@ #include <TaskManager/Thread.class.h> #include <VTManager/VirtualTerminal.proto.h> -#include <Library/SimpleList.class.h> +#include <SimpleList.class.h> namespace Task { Thread* currThread(); diff --git a/Source/Kernel/TaskManager/Task.wtf.asm b/Source/Kernel/TaskManager/Task.wtf.asm index 77db18e..9f27bec 100644 --- a/Source/Kernel/TaskManager/Task.wtf.asm +++ b/Source/Kernel/TaskManager/Task.wtf.asm @@ -9,13 +9,6 @@ idle_task: hlt jmp idle_task -[GLOBAL atomic_exchange] -atomic_exchange: - mov ecx, [esp+4] ; Get lock address - mov eax, [esp+8] ; Get new value - xchg eax, [ecx] ; Old value goes in eax - ret - [GLOBAL copy_page_physical] copy_page_physical: push ebx ; According to __cdecl, we must preserve the contents of EBX. @@ -47,3 +40,5 @@ copy_page_physical: popf ; Pop EFLAGS back. pop ebx ; Get the original value of EBX back. ret + + diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 6d62474..21ef954 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -2,17 +2,71 @@ #include <TaskManager/Task.ns.h> #include <MemoryManager/PageAlloc.ns.h> #include <DeviceManager/Time.ns.h> +#include <MemoryManager/GDT.ns.h> + +#include <Thread.iface.h> + +call_t Thread::m_callTable[] = { + CALL1(THIF_SLEEP, &Thread::sleepSC), + CALL1(THIF_FINISH, &Thread::finishSC), + CALL0(0, 0) +}; + +u32int Thread::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) { + if (wat == THIF_SGETCTH) return Task::currThread()->resId(); + return (u32int) - 1; +} void runThread(Thread* thread, void* data, thread_entry_t entry_point) { - asm volatile("sti"); - u32int ret = entry_point(data); //Run ! - asm volatile("mov %0, %%eax; int $66;" : : "r"(ret)); //Syscall for thread ending + if (thread->m_isKernel) { + asm volatile("sti"); + u32int ret = entry_point(data); //Run ! + asm volatile("mov %0, %%eax; int $66;" : : "r"(ret)); //Syscall for thread ending + } else { + //Setup values on user stack + u32int *stack = (u32int*)((u32int)thread->m_userStack.addr + thread->m_userStack.size); + stack--; + *stack = (u32int)data; + stack--; + *stack = 0; + u32int esp = (u32int)stack, eip = (u32int)entry_point; + //Setup a false structure for returning from an interrupt : + //- update data segments to 0x23 = user data segment with RPL=3 + //- mov esp in ebx and eip in ecx + //- push value for ss : 0x23 (user data seg rpl3) + //- push value for esp + //- push flags + //- update flags, set IF = 1 (interrupts flag) + //- push value for cs : 0x1B = user code segment with RPL=3 + //- push eip + //- return from fake interrupt + asm volatile(" \ + mov $0x23, %%ax; \ + mov %%ax, %%ds; \ + mov %%ax, %%es; \ + mov %%ax, %%fs; \ + mov %%ax, %%gs; \ + \ + mov %0, %%ebx; \ + mov %1, %%ecx; \ + pushl $0x23; \ + pushl %%ebx; \ + pushf; \ + pop %%eax; \ + or $0x200, %%eax; \ + push %%eax; \ + pushl $0x1B; \ + push %%ecx; \ + iret; \ + " : : "r"(esp), "r"(eip)); + } } -Thread::Thread() { //Private constructor, does nothing +Thread::Thread() : Ressource(THIF_OBJTYPE, m_callTable) { //Private constructor, does nothing + m_xchgspace = 0; } -Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) { +Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) : Ressource(THIF_OBJTYPE, m_callTable) { if (iskernel) { setup(Task::getKernelProcess(), entry_point, data, true); } else { @@ -20,22 +74,28 @@ Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) { } } -Thread::Thread(Process* process, thread_entry_t entry_point, void* data) { +Thread::Thread(Process* process, thread_entry_t entry_point, void* data) : Ressource(THIF_OBJTYPE, m_callTable) { setup(process, entry_point, data, false); } Thread::~Thread() { Task::unregisterThread(this); - Mem::kfree(m_kernelStack.addr); - if (!m_isKernel) m_process->heap().free(m_userStack.addr); + Mem::free(m_kernelStack.addr); + m_process->getPagedir()->switchTo(); + if (m_userStack.addr != 0) { + m_process->heap().free(m_userStack.addr); + } + if (m_xchgspace != 0) { + m_process->heap().free(m_xchgspace); + } //Don't unregister thread in process, it has probably already been done } void Thread::setup(Process* process, thread_entry_t entry_point, void* data, bool isKernel) { - DEBUG("new Thread :: setup"); + m_xchgspace = 0; m_isKernel = isKernel; m_process = process; - m_kernelStack.addr = Mem::kalloc(STACKSIZE); + m_kernelStack.addr = Mem::alloc(STACKSIZE); m_kernelStack.size = STACKSIZE; if (m_isKernel) { @@ -111,11 +171,11 @@ void Thread::handleException(registers_t regs, int no) { *(m_process->m_vt) << "At:" << (u32int)faddr; *(m_process->m_vt) << "\nThread finishing.\n"; - finish(E_PAGEFAULT); + Task::currentThreadExits(E_PAGEFAULT); //Calling this will setup a new stack return; } *(m_process->m_vt) << "\nThread finishing.\n"; - finish(E_UNHANDLED_EXCEPTION); + Task::currentThreadExits(E_UNHANDLED_EXCEPTION); } void Thread::setState(u32int esp, u32int ebp, u32int eip) { @@ -124,12 +184,22 @@ void Thread::setState(u32int esp, u32int ebp, u32int eip) { m_eip = eip; } +void Thread::setKernelStack() { + GDT::tss_entry.esp0 = (u32int)(m_kernelStack.addr) + m_kernelStack.size; +} + u32int Thread::getEsp() { return m_esp; } u32int Thread::getEbp() { return m_ebp; } u32int Thread::getEip() { return m_eip; } Process* Thread::getProcess() { return m_process; } +void* Thread::mkXchgSpace(u32int sz) { + if (m_xchgspace != 0) m_process->heap().free(m_xchgspace); + m_xchgspace = m_process->heap().alloc(sz); + return m_xchgspace; +} + void Thread::sleep(u32int msecs) { m_state = T_SLEEPING; waitfor.m_time = Time::time() + msecs; @@ -145,6 +215,7 @@ void Thread::waitIRQ(u8int irq) { } bool Thread::runnable() { + if (m_process->getState() != P_RUNNING) return false; if (m_state == T_RUNNING) return true; if (m_state == T_SLEEPING and Time::time() >= waitfor.m_time) { m_state = T_RUNNING; @@ -152,3 +223,17 @@ bool Thread::runnable() { } return false; } + +u32int Thread::sleepSC(u32int msecs) { + if (this != Task::currThread()) return 1; + sleep(msecs); + return 0; +} + +u32int Thread::finishSC(u32int errcode) { + if (this != Task::currThread()) return 1; + Task::currentThreadExits(errcode); + return 0; +} + + diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h index 9c8fa26..35a9fd6 100644 --- a/Source/Kernel/TaskManager/Thread.class.h +++ b/Source/Kernel/TaskManager/Thread.class.h @@ -11,7 +11,7 @@ typedef u32int(*thread_entry_t)(void*); -class Thread { +class Thread : public Ressource { friend class Process; //This might be useful friend void runThread(Thread*, void*, thread_entry_t); @@ -22,6 +22,8 @@ class Thread { u32int m_esp, m_ebp, m_eip; u8int m_state; //Is one of T_* defined above + void* m_xchgspace; + union { //What the thread might be waiting for u32int m_time; u8int m_irq; //An IRQ number @@ -35,7 +37,14 @@ class Thread { void setup(Process* process, thread_entry_t entry_point, void* data, bool isKernel); + //Syscalls + static call_t m_callTable[]; + u32int sleepSC(u32int msecs); + u32int finishSC(u32int errcode); + public: + static u32int scall(u8int, u32int, u32int, u32int, u32int); + Thread(thread_entry_t entry_point, void* data, bool iskernel = false); //Assumes process is current process, or is kprocess if isk Thread(Process* process, thread_entry_t entry_point, void* data); ~Thread(); @@ -43,11 +52,14 @@ class Thread { void handleException(registers_t regs, int no); void setState(u32int esp, u32int ebp, u32int eip); + void setKernelStack(); u32int getEsp(); u32int getEbp(); u32int getEip(); Process* getProcess(); + void* mkXchgSpace(u32int sz); + void sleep(u32int msecs); void waitIRQ(u8int irq); bool runnable(); //Called by scheduler diff --git a/Source/Kernel/VFS/DirectoryNode.class.h b/Source/Kernel/VFS/DirectoryNode.class.h index 2130458..346c4ab 100644 --- a/Source/Kernel/VFS/DirectoryNode.class.h +++ b/Source/Kernel/VFS/DirectoryNode.class.h @@ -2,7 +2,7 @@ #define DEF_DIRECTORYNODE_CLASS_H #include <VFS/FileNode.class.h> -#include <Library/Vector.class.h> +#include <Vector.class.h> class DirectoryNode : public FSNode { protected: diff --git a/Source/Kernel/VFS/FSNode-sc.proto.cpp b/Source/Kernel/VFS/FSNode-sc.proto.cpp new file mode 100644 index 0000000..9e485e1 --- /dev/null +++ b/Source/Kernel/VFS/FSNode-sc.proto.cpp @@ -0,0 +1,34 @@ +#include "FSNode.proto.h" +#include <VFS/VFS.ns.h> + +call_t FSNode::m_callTable[] = { + CALL0(FNIF_GETNAME, &FSNode::getNameSC), + CALL0(FNIF_TYPE, &FSNode::typeSC), + CALL0(FNIF_GETPARENT, &FSNode::getParentSC), + CALL0(FNIF_GETLENGTH, &FSNode::getLengthSC), + CALL0(0, 0) +}; + +u32int FSNode::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) { + if (wat == FNIF_SGETRFN) return VFS::getRootNode()->resId(); + return (u32int) - 1; +} + +u32int FSNode::getNameSC() { + return getName().serialize(); +} + +u32int FSNode::typeSC() { + return type(); +} + +u32int FSNode::getLengthSC() { + u64int* a = (u64int*)Mem::mkXchgSpace(sizeof(u64int)); + *a = getLength(); + return (u32int)a; +} + +u32int FSNode::getParentSC() { + if (m_parent != 0) return m_parent->resId(); + return (u32int) - 1; +} diff --git a/Source/Kernel/VFS/FSNode.proto.h b/Source/Kernel/VFS/FSNode.proto.h index 8773543..b648141 100644 --- a/Source/Kernel/VFS/FSNode.proto.h +++ b/Source/Kernel/VFS/FSNode.proto.h @@ -1,10 +1,13 @@ #ifndef DEF_FSNODE_PROTO_H #define DEF_FSNODE_PROTO_H -#include <Core/common.wtf.h> -#include <Library/String.class.h> +#include <common.h> +#include <String.class.h> class FSNode; #include <VFS/FileSystem.proto.h> +#include <SyscallManager/Ressource.class.h> + +#include <FSNode.iface.h> enum { NT_FILE = 1, @@ -13,18 +16,27 @@ enum { NT_MOUNTPOINT = 4 }; -class FSNode { +class FSNode : public Ressource { protected: String m_name; u64int m_length; u32int m_permissions, m_uid, m_gid; FileSystem *m_fs; FSNode *m_parent; + + //Syscall related + static call_t m_callTable[]; + u32int getNameSC(); + u32int getLengthSC(); + u32int typeSC(); + u32int getParentSC(); public: + static u32int scall(u8int, u32int, u32int, u32int, u32int); + FSNode(String name, FileSystem* fs, FSNode* parent, u64int length = 0, u32int permissions = 0777, u32int uid = 0, u32int gid = 0) : - m_name(name), m_length(length), m_permissions(permissions), + Ressource(FNIF_OBJTYPE, m_callTable), m_name(name), m_length(length), m_permissions(permissions), m_uid(uid), m_gid(gid), m_fs(fs), m_parent(parent) {} virtual ~FSNode() {} diff --git a/Source/Kernel/VFS/File.class.h b/Source/Kernel/VFS/File.class.h index 7831fb5..f5d0c56 100644 --- a/Source/Kernel/VFS/File.class.h +++ b/Source/Kernel/VFS/File.class.h @@ -2,7 +2,7 @@ #define DEF_FILE_CLASS_H #include <VFS/FileNode.class.h> -#include <Library/ByteArray.class.h> +#include <ByteArray.class.h> enum { FM_READ = 0, //Open for read, put cursor at beginning diff --git a/Source/Kernel/VFS/Part.ns.h b/Source/Kernel/VFS/Part.ns.h index 07a45f9..40a0fb2 100644 --- a/Source/Kernel/VFS/Part.ns.h +++ b/Source/Kernel/VFS/Part.ns.h @@ -2,7 +2,7 @@ #define DEF_PART_NS_H #include <Devices/BlockDevice.proto.h> -#include <Library/Vector.class.h> +#include <Vector.class.h> #include <VFS/Partition.class.h> namespace Part { diff --git a/Source/Kernel/VTManager/SimpleVT.class.cpp b/Source/Kernel/VTManager/SimpleVT.class.cpp index 89391b2..d304a5f 100644 --- a/Source/Kernel/VTManager/SimpleVT.class.cpp +++ b/Source/Kernel/VTManager/SimpleVT.class.cpp @@ -132,5 +132,5 @@ void SimpleVT::put(WChar c, bool updatecsr) { void SimpleVT::hexDump(u8int *ptr, u32int sz, bool addnl) { if (m_cols < 76) return; //Not enough space - VirtualTerminal::hexDump(ptr, sz, (m_cols == 76)); + VirtualTerminal::hexDump(ptr, sz, (m_cols > 76)); } diff --git a/Source/Kernel/VTManager/VT.ns.cpp b/Source/Kernel/VTManager/VT.ns.cpp index 87586bc..ee7299d 100644 --- a/Source/Kernel/VTManager/VT.ns.cpp +++ b/Source/Kernel/VTManager/VT.ns.cpp @@ -1,5 +1,5 @@ #include "VT.ns.h" -#include <Library/Vector.class.h> +#include <Vector.class.h> #include <DeviceManager/Disp.ns.h> namespace VT { diff --git a/Source/Kernel/VTManager/VT.ns.h b/Source/Kernel/VTManager/VT.ns.h index 55556b9..9390636 100644 --- a/Source/Kernel/VTManager/VT.ns.h +++ b/Source/Kernel/VTManager/VT.ns.h @@ -1,7 +1,7 @@ #ifndef DEF_VT_NS_H #define DEF_VT_NS_H -#include <Core/common.wtf.h> +#include <common.h> #include <VTManager/SimpleVT.class.h> namespace VT { diff --git a/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp index 59f66a6..b5ed9c3 100644 --- a/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp @@ -28,8 +28,9 @@ keypress_t VirtualTerminal::getKeypress(bool show, bool block) { return keypress_t(); } - while (m_kbdbuff.empty()) + while (m_kbdbuff.empty()) { Task::currThread()->sleep(10); + } m_kbdbuffMutex.waitLock(); keypress_t ret = m_kbdbuff[0]; diff --git a/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp new file mode 100644 index 0000000..0a4e14b --- /dev/null +++ b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp @@ -0,0 +1,46 @@ +#include "VirtualTerminal.proto.h" + +u32int VirtualTerminal::writeHexSC(u32int number) { + writeHex(number); + return 0; +} + +u32int VirtualTerminal::writeDecSC(u32int n_hi, u32int n_lo) { + s64int n = ((u64int)n_hi << 32) | n_lo; + writeDec(n); + return 0; +} + +u32int VirtualTerminal::writeSC(u32int wat) { + String *s = (String*)wat; + write(*s); + return 0; +} + +u32int VirtualTerminal::putSC(u32int code) { + put(WChar(code)); + return 0; +} + +u32int VirtualTerminal::readLineSC() { + return readLine().serialize(); +} + +u32int VirtualTerminal::setColorSC(u32int x) { + setColor((x >> 8) & 0xFF, x & 0xFF); + return 0; +} + +u32int VirtualTerminal::setCursorLineSC(u32int l) { + setCursorLine(l); + return 0; +} + +u32int VirtualTerminal::setCursorColSC(u32int c) { + setCursorCol(c); + return 0; +} + +u32int VirtualTerminal::isBoxedSC() { + return (isBoxed() ? 1 : 0); +} diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp index 7a9ffa8..9b0b862 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp @@ -1,8 +1,30 @@ #include "VirtualTerminal.proto.h" #include <DeviceManager/Disp.ns.h> #include <VTManager/VT.ns.h> +#include <TaskManager/Task.ns.h> -VirtualTerminal::VirtualTerminal() : m_kbdMutex(false), m_kbdbuffMutex(false) { +#include <VirtualTerminal.iface.h> + +call_t VirtualTerminal::m_callTable[] = { + CALL1(VTIF_WRITEHEX, &VirtualTerminal::writeHexSC), + CALL2(VTIF_WRITEDEC, &VirtualTerminal::writeDecSC), + CALL1(VTIF_WRITE, &VirtualTerminal::writeSC), + CALL1(VTIF_PUT, &VirtualTerminal::putSC), + CALL0(VTIF_READLINE, &VirtualTerminal::readLineSC), + CALL1(VTIF_SETCOLOR, &VirtualTerminal::setColorSC), + CALL1(VTIF_SETCSRLINE, &VirtualTerminal::setCursorLineSC), + CALL1(VTIF_SETCSRCOL, &VirtualTerminal::setCursorColSC), + CALL0(VTIF_ISBOXED, &VirtualTerminal::isBoxedSC), + CALL0(0, 0) +}; + +u32int VirtualTerminal::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) { + if (wat == VTIF_SGETPRVT) return Task::currProcess()->getVirtualTerminal()->resId(); + return (u32int) - 1; +} + +VirtualTerminal::VirtualTerminal() : + Ressource(VTIF_OBJTYPE, m_callTable), m_kbdMutex(false), m_kbdbuffMutex(false), m_kbdbuff() { } VirtualTerminal::~VirtualTerminal() { diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.h b/Source/Kernel/VTManager/VirtualTerminal.proto.h index ea6284f..936e4d4 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.h +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h @@ -1,23 +1,39 @@ #ifndef DEF_VIRTUALTERMINAL_CLASS_H #define DEF_VIRTUALTERMINAL_CLASS_H -#include <Core/common.wtf.h> -#include <Library/String.class.h> -#include <TaskManager/Mutex.class.h> +#include <common.h> +#include <String.class.h> +#include <Mutex.class.h> #include <DeviceManager/Kbd.ns.h> -#include <Library/Vector.class.h> +#include <Vector.class.h> + +#include <SyscallManager/Ressource.class.h> struct vtchr { u8int color; WChar c; }; -class VirtualTerminal { +class VirtualTerminal : public Ressource { protected: Mutex m_kbdMutex, m_kbdbuffMutex; Vector<Kbd::keypress_t> m_kbdbuff; //Key press events buffer + //SYSCALLS : + static call_t m_callTable[]; + u32int writeHexSC(u32int); + u32int writeDecSC(u32int, u32int); + u32int writeSC(u32int); + u32int putSC(u32int); + u32int readLineSC(); + u32int setColorSC(u32int); + u32int setCursorLineSC(u32int); + u32int setCursorColSC(u32int); + u32int isBoxedSC(); + public: + static u32int scall(u8int, u32int, u32int, u32int, u32int); + VirtualTerminal(); virtual ~VirtualTerminal(); diff --git a/Source/Kernel/Core/common.wtf.h b/Source/Kernel/common.h index 5fb67b4..86d76cd 100644 --- a/Source/Kernel/Core/common.wtf.h +++ b/Source/Kernel/common.h @@ -7,9 +7,9 @@ #define NULL 0 -#include <Core/types.wtf.h> +#include <types.h> -#include <Core/CMem.ns.h> +#include <CMem.ns.h> #include <Core/Sys.ns.h> #include <MemoryManager/Mem.ns.h> @@ -20,9 +20,9 @@ inline void* operator new[](u32int, void *p) { return p; } inline void operator delete(void*, void*) { } inline void operator delete[](void*, void*) { } -inline void* operator new(u32int sz) { return Mem::kalloc(sz); } -inline void* operator new[](u32int sz) { return Mem::kalloc(sz); } -inline void operator delete(void *ptr) { Mem::kfree(ptr); } -inline void operator delete[](void *ptr) { Mem::kfree(ptr); } +inline void* operator new(u32int sz) { return Mem::alloc(sz); } +inline void* operator new[](u32int sz) { return Mem::alloc(sz); } +inline void operator delete(void *ptr) { Mem::free(ptr); } +inline void operator delete[](void *ptr) { Mem::free(ptr); } #endif |