diff options
Diffstat (limited to 'Source/Kernel')
20 files changed, 317 insertions, 118 deletions
diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index a7bb6e0..19888c9 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -19,6 +19,9 @@ #include <SyscallManager/IDT.ns.h> #include <Library/String.class.h> #include <VFS/Part.ns.h> +#include <FileSystems/RamFS/RamFS.class.h> +#include <VFS/FileNode.class.h> +#include <VFS/DirectoryNode.class.h> #include <Ressources/logo.cd> #include <Ressources/keymap-fr.wtf.c> @@ -109,6 +112,13 @@ void kmain(multiboot_info_t* mbd, u32int magic) { asm volatile("sti"); + FileSystem* fs = new RamFS(1024 * 1024); + DirectoryNode* rd; + rd = fs->getRootNode(); + FileNode* f; + f = rd->createFile(String("test")); + f->write(0, 4, (u8int*)"plop"); + while(1) { kvt->setColor(0); *kvt << "> "; @@ -123,6 +133,22 @@ void kmain(multiboot_info_t* mbd, u32int magic) { *kvt << " - free shows memory usage (physical frames and kernel heap)\n"; *kvt << " - uptime shows seconds since boot\n"; *kvt << " - part shows all detected block devices and partitions\n"; + } else if (tmp == "ls") { + for (u32int i = 0; i < rd->getLength(); i++) { + FSNode* n = rd->getChild(i); + if (n->type() == NT_FILE) { + FileNode* f = (FileNode*)n; + *kvt << "Found file " << f->getName() << ", length " << (s32int)f->getLength() << " :\n"; + u8int* d = (u8int*)Mem::kalloc(f->getLength() + 1); + f->read(0, f->getLength(), d); + d[f->getLength()] = 0; + *kvt << String((const char*)d); + Mem::kfree(d); + *kvt << "\n"; + } else if (n->type() == NT_DIRECTORY) { + *kvt << "Found directory " << n->getName() << " :\n"; + } + } } else if (tmp == "reboot") { Sys::reboot(); } else if (tmp == "devices") { diff --git a/Source/Kernel/FileSystems/RamFS/RamDirNode.class.cpp b/Source/Kernel/FileSystems/RamFS/RamDirNode.class.cpp deleted file mode 100644 index e69de29..0000000 --- a/Source/Kernel/FileSystems/RamFS/RamDirNode.class.cpp +++ /dev/null diff --git a/Source/Kernel/FileSystems/RamFS/RamDirNode.class.h b/Source/Kernel/FileSystems/RamFS/RamDirNode.class.h deleted file mode 100644 index e69de29..0000000 --- a/Source/Kernel/FileSystems/RamFS/RamDirNode.class.h +++ /dev/null diff --git a/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp b/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp index e69de29..c8ed27c 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp +++ b/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp @@ -0,0 +1,86 @@ +#include "RamFS.class.h" +#include <VFS/DirectoryNode.class.h> +#include "RamFileNode.class.h" + +RamFS::RamFS(u32int maxSize) { + m_maxSize = maxSize; + m_usedSize = 0; + m_isWritable = true; + m_rootNode = new DirectoryNode("/", this, NULL); +} + +bool RamFS::setName(FSNode* node, String name) { return true; } +bool RamFS::setPermissions(FSNode* node, u32int permissions) { return true; } +bool RamFS::setUid(FSNode* node, u32int uid) { return true; } +bool RamFS::setGid(FSNode* node, u32int gid) { return true; } +bool RamFS::setParent(FSNode* node, FSNode* parent) { + if (parent->getFS() == this) return true; + return false; +} + +u32int RamFS::read(FileNode* file, u64int position, u32int max_length, u8int *data) { + RamFileNode *node = (RamFileNode*) file; + if (file->getLength() <= position) return 0; + u32int length = file->getLength() - position; + if (length > max_length) length = max_length; + memcpy(data, node->m_data + position, length); + return length; +} + +bool RamFS::write(FileNode* file, u64int position, u32int length, u8int *data) { + if (!m_isWritable) return false; + RamFileNode *node = (RamFileNode*) file; + + u32int end = position + length; + if (end > node->getLength()) { + if (m_usedSize - node->getLength() + end > m_maxSize) return false; + m_usedSize -= node->getLength(); + m_usedSize += end; + + u8int* data = (u8int*)Mem::kalloc(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); + } + node->m_data = data; + node->setLength(end); + } + memcpy(node->m_data + position, data, length); + return true; +} + +bool RamFS::truncate(FileNode* file) { + if (!m_isWritable) return false; + RamFileNode *node = (RamFileNode*) file; + + Mem::kfree(node->m_data); + node->setLength(0); + node->m_data = 0; + + return true; +} + +bool RamFS::loadContents(DirectoryNode* dir) { return true; } //Nothing to do. + +FileNode* RamFS::createFile(DirectoryNode* parent, String name) { + if (!m_isWritable) return NULL; + if (parent->getFS() != this) return NULL; + + RamFileNode* n = new RamFileNode(name, this, parent); + parent->loadContent(); + parent->getChildren().push(n); + + return n; +} + +DirectoryNode* RamFS::createDirectory(DirectoryNode* parent, String name) { + if (!m_isWritable) return NULL; + if (parent->getFS() != this) return NULL; + + DirectoryNode* d = new DirectoryNode(name, this, parent); + parent->loadContent(); + parent->getChildren().push(d); + + return d; +} diff --git a/Source/Kernel/FileSystems/RamFS/RamFS.class.h b/Source/Kernel/FileSystems/RamFS/RamFS.class.h index e69de29..427019c 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFS.class.h +++ b/Source/Kernel/FileSystems/RamFS/RamFS.class.h @@ -0,0 +1,30 @@ +#ifndef DEF_RAMFS_CLASS_H +#define DEF_RAMFS_CLASS_H + +#include <VFS/FileSystem.proto.h> + +class RamFS : public FileSystem { + private: + u32int m_maxSize; + u32int m_usedSize; + + public: + RamFS(u32int maxSize); //Creates an empty RAM file system + RamFS(u8int* ptr, u32int maxSize); //Creates a RAM file system from data loaded in memory. format to be defined + + bool setName(FSNode* node, String name); + bool setPermissions(FSNode* node, u32int permissions); + bool setUid(FSNode* node, u32int uid); + bool setGid(FSNode* node, u32int gid); + bool setParent(FSNode* node, FSNode* parent); + + u32int read(FileNode* file, u64int position, u32int max_length, u8int *data); + bool write(FileNode* file, u64int position, u32int length, u8int *data); + bool truncate(FileNode* file); + + bool loadContents(DirectoryNode* dir); + FileNode* createFile(DirectoryNode* parent, String name); + DirectoryNode* createDirectory(DirectoryNode* parent, String name); +}; + +#endif diff --git a/Source/Kernel/FileSystems/RamFS/RamFileNode.class.cpp b/Source/Kernel/FileSystems/RamFS/RamFileNode.class.cpp deleted file mode 100644 index e69de29..0000000 --- a/Source/Kernel/FileSystems/RamFS/RamFileNode.class.cpp +++ /dev/null diff --git a/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h b/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h index e69de29..142d763 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h +++ b/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h @@ -0,0 +1,19 @@ +#ifndef DEF_RAMFILENODE_CLASS_H +#define DEF_RAMFILENODE_CLASS_H + +#include <VFS/FileNode.class.h> + +class RamFileNode : public FileNode { + friend class RamFS; + + private: + RamFileNode (String name, FileSystem* fs, FSNode* parent, u32int permissions = 0777, + u32int uid = 0, u32int gid = 0) : + FileNode(name, fs, parent, 0, permissions, uid, gid), m_data(0) {} + + u8int *m_data; + + void setLength(u32int length) { m_length = length; } +}; + +#endif diff --git a/Source/Kernel/Library/String.class.cpp b/Source/Kernel/Library/String.class.cpp index e70d19f..8df5cbf 100644 --- a/Source/Kernel/Library/String.class.cpp +++ b/Source/Kernel/Library/String.class.cpp @@ -54,7 +54,7 @@ String::String() { m_length = 0; } -String::String(char* string) { +String::String(const char* string) { m_length = WChar::utf8len(string); if (m_length == 0) { m_string = 0; @@ -100,7 +100,7 @@ void String::operator= (const String &other) { m_string[m_length] = 0; } -void String::operator= (char* string) { +void String::operator= (const char* string) { m_length = WChar::utf8len(string); if (m_string != 0) delete [] m_string; if (m_length == 0) { @@ -116,7 +116,7 @@ void String::operator= (char* string) { m_string[m_length] = 0; } -bool String::operator== (String &other) { +bool String::operator== (const String &other) { if (m_length != other.m_length) return false; for (u32int i = 0; i < m_length; i++) { if (m_string[i] != other.m_string[i]) return false; @@ -124,7 +124,7 @@ bool String::operator== (String &other) { return true; } -bool String::operator== (char* string) { +bool String::operator== (const char* string) { if (m_length != WChar::utf8len(string)) return false; int i = 0, l = strlen(string), c = 0; WChar tmp; @@ -151,7 +151,7 @@ String& String::operator+= (String &other) { return *this; } -String& String::operator+= (char* other) { +String& String::operator+= (const char* other) { WChar* newdata = new WChar[m_length + WChar::utf8len(other) + 1]; for (u32int i = 0; i < m_length; i++) { newdata[i] = m_string[i]; @@ -186,7 +186,7 @@ String& String::operator+ (String &other) { //Can be optimized return (ret += other); } -String& String::operator+ (char* other) { //Can be optimized +String& String::operator+ (const char* other) { //Can be optimized String ret(*this); return (ret += other); } diff --git a/Source/Kernel/Library/String.class.h b/Source/Kernel/Library/String.class.h index ecbc2a0..85ec268 100644 --- a/Source/Kernel/Library/String.class.h +++ b/Source/Kernel/Library/String.class.h @@ -15,21 +15,21 @@ class String { static String hex(u32int number); static String number(s32int number); - String(char* string); + String(const char* string); String(); String(const String &other); ~String(); void operator= (const String &other); - void operator= (char* string); + void operator= (const char* string); - bool operator== (String &other); - bool operator== (char* string); + bool operator== (const String &other); + bool operator== (const char* string); String &operator+= (String &other); - String &operator+= (char* other); + String &operator+= (const char* other); String &operator+= (WChar other); String &operator+ (String &other); - String &operator+ (char* other); + String &operator+ (const char* other); String &operator+ (WChar other); s32int toInt(); u32int toInt16(); //From HEX diff --git a/Source/Kernel/Library/WChar.class.cpp b/Source/Kernel/Library/WChar.class.cpp index c1a1977..bb1269d 100644 --- a/Source/Kernel/Library/WChar.class.cpp +++ b/Source/Kernel/Library/WChar.class.cpp @@ -19,11 +19,11 @@ WChar::WChar(char c) { affectAscii(c); } -WChar::WChar(char* c) { +WChar::WChar(const char* c) { affectUtf8(c); } -u32int WChar::utf8len(char* c) { +u32int WChar::utf8len(const char* c) { int i = 0, l = CMem::strlen(c), co = 0; while (i < l) { if ((c[i] & 0x80) == 0) i += 1; @@ -41,7 +41,7 @@ void WChar::affectAscii(char c) { else value = CP437[c + 128]; } -u32int WChar::affectUtf8(char* c) { //Returns the number of bytes for the character +u32int WChar::affectUtf8(const char* c) { //Returns the number of bytes for the character /*if ((c[0] & 0xB0) == 0x80) { //11000000b == 10000000b, means we are IN a sequence value = 0; return 1; diff --git a/Source/Kernel/Library/WChar.class.h b/Source/Kernel/Library/WChar.class.h index c582017..9ddccd1 100644 --- a/Source/Kernel/Library/WChar.class.h +++ b/Source/Kernel/Library/WChar.class.h @@ -9,14 +9,14 @@ struct WChar { WChar(); //Creates a null character WChar(char c); //From ascii character - WChar(char* c); //From utf8 string + WChar(const char* c); //From utf8 string - static u32int utf8len(char* c); //Returns count of utf8 characters in string + static u32int utf8len(const char* c); //Returns count of utf8 characters in string void affectAscii(char c); - u32int affectUtf8(char* c); - void affectUtf16(char* c); - void affectUtf32(char* c); + u32int affectUtf8(const char* c); + void affectUtf16(const char* c); + void affectUtf32(const char* c); u8int toAscii(); inline WChar operator+ (u32int other) { diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index e0f2068..7f2bf29 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -38,6 +38,7 @@ Objects = Core/loader.wtf.o \ Library/WChar.class.o \ VFS/Partition.class.o \ VFS/Part.ns.o \ + FileSystems/RamFS/RamFS.class.o \ SyscallManager/IDT.ns.o \ SyscallManager/IDT.wtf.o \ Devices/Display/VGATextOutput.class.o \ diff --git a/Source/Kernel/Melon.ke b/Source/Kernel/Melon.ke Binary files differindex 552d00c..575395c 100755 --- a/Source/Kernel/Melon.ke +++ b/Source/Kernel/Melon.ke diff --git a/Source/Kernel/VFS/DirectoryNode.class.h b/Source/Kernel/VFS/DirectoryNode.class.h new file mode 100644 index 0000000..cb1574c --- /dev/null +++ b/Source/Kernel/VFS/DirectoryNode.class.h @@ -0,0 +1,60 @@ +#ifndef DEF_DIRECTORYNODE_CLASS_H +#define DEF_DIRECTORYNODE_CLASS_H + +#include <VFS/FileNode.class.h> +#include <Library/Vector.class.h> + +class DirectoryNode : public FSNode { + protected: + Vector<FSNode*> m_children; + bool m_contentLoaded; + + public: + DirectoryNode(String name, FileSystem* fs, FSNode* parent, u32int permissions = 0777, + u32int uid = 0, u32int gid = 0) : + FSNode(name, fs, parent, 0, permissions, uid, gid), m_children(), m_contentLoaded(false) {} + + Vector<FSNode*> &getChildren() { return m_children; } //MUST BE USED ONLY BY FILESYSTEMS + + u8int type() { return NT_DIRECTORY; } + + bool loadContent() { + if (m_contentLoaded) return true; + bool b = m_fs->loadContents(this); + if (!b) return false; + m_length = m_children.size(); + m_contentLoaded = true; + return b; + } + + FSNode* getChild(u32int index) { + if (!m_contentLoaded) + if (!loadContent()) + return NULL; + if (index >= m_children.size()) return NULL; + return m_children[index]; + } + + FSNode* getChild(String name) { + if (!m_contentLoaded) + if (!loadContent()) + return NULL; + for (u32int i = 0; i < m_children.size(); i++) { + if (name == m_children[i]->getName()) + return m_children[i]; + } + return NULL; + } + FileNode* createFile(String name) { + FileNode* n = m_fs->createFile(this, name); + m_length = m_children.size(); + return n; + } + DirectoryNode* createDirectory(String name) { + DirectoryNode* n = m_fs->createDirectory(this, name); + m_length = m_children.size(); + return n; + } +}; + +#endif diff --git a/Source/Kernel/VFS/DirectoryNode.proto.h b/Source/Kernel/VFS/DirectoryNode.proto.h deleted file mode 100644 index f9c1c9f..0000000 --- a/Source/Kernel/VFS/DirectoryNode.proto.h +++ /dev/null @@ -1,46 +0,0 @@ -#ifndef DEF_DIRECTORYNODE_PROTO_H -#define DEF_DIRECTORYNODE_PROTO_H - -#include <VFS/FSNode.proto.h> -#include <Library/Vector.class.h> - -class DirectoryNode : public virtual FSNode { - protected: - Vector<FSNode*> m_children; - bool m_contentLoaded; - - protected: - DirectoryNode() : m_children(), m_contentLoaded(false) {} - - virtual bool FSLoadContent() = 0; - - public: - bool loadContent() { - if (m_contentLoaded) return true; - bool b = FSLoadContent(); - m_length = m_children.size(); - if (b) m_contentLoaded = true; - return b; - } - - FSNode* getChild(u32int index) { - if (!m_contentLoaded) - if (!loadContent) - return NULL; - if (index >= m_children.size()) return NULL; - return m_children[index]; - } - - FSNode* getChild(String name) { - if (!m_contentLoaded) - if (!loadContent) - return NULL; - for (u32int i = 0; i < m_children.size(); i++) { - if (m_children[i]->getName() == name) - return m_children[i]; - } - return NULL; - } -}; - -#endif diff --git a/Source/Kernel/VFS/FSNode.proto.h b/Source/Kernel/VFS/FSNode.proto.h index 62d28be..fb24a82 100644 --- a/Source/Kernel/VFS/FSNode.proto.h +++ b/Source/Kernel/VFS/FSNode.proto.h @@ -3,8 +3,8 @@ #include <Core/common.wtf.h> #include <Library/String.class.h> - -class FileSystem; +class FSNode; +#include <VFS/FileSystem.proto.h> enum { NT_FILE = 1, @@ -20,12 +20,11 @@ class FSNode { u32int m_permissions, m_uid, m_gid; FileSystem *m_fs; FSNode *m_parent; - u32int m_inode; - FSNode(String name, FileSystem* fs, FSNode* parent, u32int inode, u32int length = 0, u32int permissions = 0777, + FSNode(String name, FileSystem* fs, FSNode* parent, u32int length = 0, u32int permissions = 0777, u32int uid = 0, u32int gid = 0) : - m_name(name), m_fs(fs), m_parent(parent), m_inode(inode), m_length(length), m_premissions(permissions), - m_uid(uid), m_gid(gid) {} + m_name(name), m_length(length), m_permissions(permissions), + m_uid(uid), m_gid(gid), m_fs(fs), m_parent(parent) {} public: @@ -38,49 +37,33 @@ class FSNode { u32int getGid() { return m_gid; } FileSystem *getFS() { return m_fs; } FSNode* getParent() { return m_parent; } - u32int getInode() { return m_inode; } - - protected: - //Must be implemented by *FSNode - virtual bool FSSetName(String name) = 0; - virtual bool FSTruncate() = 0; - virtual bool FSSetPermissions(u32int permissions) = 0; - virtual bool FSSetUid(u32int uid) = 0; - virtual bool FSSetGid(u32int gid) = 0; - virtual bool FSSetParent(FSNode* parent) = 0; public: bool setName(String name) { - bool b = FSSetName(name); + bool b = m_fs->setName(this, name); if (b) m_name = name; return b; } - bool truncate() { - bool b = FSTruncate(); - if (b) m_length = 0; - return b; - } bool setPermissions(u32int permissions) { - bool b = FSSetPermissions(permissions); + bool b = m_fs->setPermissions(this, permissions); if (b) m_permissions = permissions; return b; } bool setUid(u32int uid) { - bool b = FSSetUid(uid); + bool b = m_fs->setUid(this, uid); if (b) m_uid = uid; return b; } bool setGid(u32int gid) { - bool b = FSSetGid(gid); + bool b = m_fs->setGid(this, gid); if (b) m_gid = gid; return b; } bool setParent(FSNode* parent) { - bool b = FSSetParent(parent); //FSSetParent is only expected to move files/directories in the same filesystem + bool b = m_fs->setParent(this, parent); //FSSetParent is only expected to move files/directories in the same filesystem if (b) m_parent = parent; return b; } - void setInode(u32int inode) { m_inode = inode; } }; #endif diff --git a/Source/Kernel/VFS/FileNode.class.h b/Source/Kernel/VFS/FileNode.class.h new file mode 100644 index 0000000..29fab45 --- /dev/null +++ b/Source/Kernel/VFS/FileNode.class.h @@ -0,0 +1,28 @@ +#ifndef DEF_FILENODE_CLASS_H +#define DEF_FILENODE_CLASS_H + +#include <VFS/FSNode.proto.h> + +class FileNode : public FSNode { + protected: + FileNode(String name, FileSystem* fs, FSNode* parent, u32int length = 0, u32int permissions = 0777, + u32int uid = 0, u32int gid = 0): FSNode(name, fs, parent, length, permissions, uid, gid) {} + + public: + u8int type() { return NT_FILE; } + + u32int read(u64int position, u32int max_length, u8int *data) { + return m_fs->read(this, position, max_length, data); + } + + bool write(u64int position, u32int length, u8int *data) { + return m_fs->write(this, position, length, data); + } + + bool truncate() { + return m_fs->truncate(this); + } + +}; + +#endif diff --git a/Source/Kernel/VFS/FileNode.proto.h b/Source/Kernel/VFS/FileNode.proto.h deleted file mode 100644 index b02c277..0000000 --- a/Source/Kernel/VFS/FileNode.proto.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef DEF_FILENODE_PROTO_H -#define DEF_FILENODE_PROTO_H - -#include <VFS/FSNode.proto.h> - -class FileNode : public virtual FSNode { - protected: - DirectoryNode() {} - - virtual bool FSRead(u64int position, u32int max_length, u8int *data) = 0; - virtual bool FSWrite(u64int position, u32int length, u8int *data) = 0; - - public: - bool read(u64int position, u32int max_length, u8int *data) { - return FSRead(position, max_length, data); - } - - bool write(u64int position, u32int length, u8int *data) { - return FSWrite(position, length, data); - } - -}; - -#endif diff --git a/Source/Kernel/VFS/FileSystem.proto.h b/Source/Kernel/VFS/FileSystem.proto.h index 523caf7..79bb84c 100644 --- a/Source/Kernel/VFS/FileSystem.proto.h +++ b/Source/Kernel/VFS/FileSystem.proto.h @@ -1,4 +1,35 @@ #ifndef DEF_FILESYSTEM_PROTO_H #define DEF_FILESYSTEM_PROTO_H +#include <VFS/Partition.class.h> +class FSNode; +class FileNode; +class DirectoryNode; + +//This abstract class describes a filesystem +class FileSystem { + protected: + bool m_isWritable; //false = read only + DirectoryNode* m_rootNode; + + public: + bool isWritable() { return m_isWritable; } + DirectoryNode* getRootNode() { return m_rootNode; } + + //Must be implemented by the filesystem + virtual bool setName(FSNode* node, String name) = 0; + virtual bool setPermissions(FSNode* node, u32int permissions) = 0; + virtual bool setUid(FSNode* node, u32int uid) = 0; + virtual bool setGid(FSNode* node, u32int gid) = 0; + virtual bool setParent(FSNode* node, FSNode* parent) = 0; + + virtual u32int read(FileNode* file, u64int position, u32int max_length, u8int *data) = 0; + virtual bool write(FileNode* file, u64int position, u32int length, u8int *data) = 0; + virtual bool truncate(FileNode* file) = 0; + + virtual bool loadContents(DirectoryNode* dir) = 0; + virtual FileNode* createFile(DirectoryNode* parent, String name) = 0; + virtual DirectoryNode* createDirectory(DirectoryNode* parent, String name) = 0; +}; + #endif diff --git a/Source/Kernel/VFS/VFS.ns.h b/Source/Kernel/VFS/VFS.ns.h index cdd6e23..622d120 100644 --- a/Source/Kernel/VFS/VFS.ns.h +++ b/Source/Kernel/VFS/VFS.ns.h @@ -2,9 +2,14 @@ #define DEF_VFS_NS_H #include <VFS/FSNode.proto.h> +#include <VFS/FileSystem.proto.h> -namespace VFS { +typedef FileSystem* (* mountcallback)(Partition* partition); +namespace VFS { + void registerMountCallback(mountcallback mcb); + bool mount(Partition* partition); + bool setRootNode(FSNode* root); } #endif |