diff --git a/src/kernel/datatypes/dynarray.h b/src/kernel/datatypes/dynarray.h index a0cf43b..72715ca 100644 --- a/src/kernel/datatypes/dynarray.h +++ b/src/kernel/datatypes/dynarray.h @@ -27,7 +27,7 @@ namespace xnoe { uint32_t old_size = size; size *= 2; T* buffer_tmp = new T[size]; - memcpy((uint8_t*)buffer, (uint8_t*)buffer_tmp, sizeof(T)*old_size); + memcpy((uint8_t*)buffer_tmp, (uint8_t*)buffer, sizeof(T)*old_size); delete buffer; buffer = buffer_tmp; lock.unlock(); diff --git a/src/kernel/filesystem/devfs.cpp b/src/kernel/filesystem/devfs.cpp index e481cba..883ab8b 100644 --- a/src/kernel/filesystem/devfs.cpp +++ b/src/kernel/filesystem/devfs.cpp @@ -1,27 +1,5 @@ #include "devfs.h" -bool DevFS::exists(Path p) { - if (p.start->elem == PathEntry{3, "ata"}) - return true; - return false; -} - -FSType DevFS::type(Path p) { - if (p.start->elem == PathEntry{3, "ata"}) - return BlockDev; -} - - -ReadWriter* DevFS::open(Path p) { - if (p.start->elem == PathEntry{3, "ata"}) { - return new ATAReadWriter(0, 0); - } - return 0; -} - - -uint32_t DevFS::getDentsSize(Path p) { - return 0; -} - -void DevFS::getDents(Path p, FSDirectoryListing* buffer) {} \ No newline at end of file +DevFS::DevFS() { + addEntry(createPathFromString("ata"), [](){return new ATAReadWriter(0,0);}); +} \ No newline at end of file diff --git a/src/kernel/filesystem/devfs.h b/src/kernel/filesystem/devfs.h index 761632a..2439ab4 100644 --- a/src/kernel/filesystem/devfs.h +++ b/src/kernel/filesystem/devfs.h @@ -4,15 +4,11 @@ #include "fstree.h" #include "../ata.h" #include "../kernel.h" +#include "vfs.h" -class DevFS: public FSTree { - bool exists(Path p) override; - FSType type(Path p) override; - - ReadWriter* open(Path p) override; - - uint32_t getDentsSize(Path p) override; - void getDents(Path p, FSDirectoryListing* buffer) override; +class DevFS : public VFS { +public: + DevFS(); }; #endif \ No newline at end of file diff --git a/src/kernel/filesystem/fat16.cpp b/src/kernel/filesystem/fat16.cpp index 00759dd..95cb7f7 100644 --- a/src/kernel/filesystem/fat16.cpp +++ b/src/kernel/filesystem/fat16.cpp @@ -21,13 +21,16 @@ FAT16FileReadWriter::FAT16FileReadWriter(uint32_t owner, uint32_t firstCluster, } uint32_t FAT16FileReadWriter::read(uint32_t count, uint8_t* buffer) { - uint8_t* clusterBuffer = new uint8_t[this->clusterSize]; + //uint8_t* clusterBuffer = new uint8_t[this->clusterSize]; + uint8_t clusterBuffer[this->clusterSize]; uint32_t clusterToRead = offsetBytesToCluster(this->currentPosition); uint32_t sectorToRead = this->backingFS->clusterToSector(clusterToRead); this->backingFS->backingDevice->seek(sectorToRead * this->clusterSize); this->backingFS->backingDevice->read(this->clusterSize, clusterBuffer); uint32_t currentClusterIndex = this->currentPosition % this->clusterSize; + if (this->currentPosition >= this->sizeBytes) + return 0; uint32_t remaining = count; @@ -45,9 +48,10 @@ uint32_t FAT16FileReadWriter::read(uint32_t count, uint8_t* buffer) { buffer[index++] = clusterBuffer[currentClusterIndex++]; remaining--; + this->currentPosition++; } - delete[] clusterBuffer; + //delete[] clusterBuffer; return index; } @@ -321,10 +325,10 @@ PathEntry name83ToPathEntry(char* name83, char* text) { while (name83[index] == ' ' && index-- > 7) extLength--; - memcpy(name83, text, mainLength); + memcpy(text, name83, mainLength); if (name83[8] != ' ') { text[mainLength] = '.'; - memcpy(name83+8, text+mainLength+1, extLength); + memcpy(text+mainLength+1, name83+8, extLength); } text[mainLength+extLength+1] = 0; return PathEntry{mainLength+extLength+1, text}; diff --git a/src/kernel/filesystem/fstree.cpp b/src/kernel/filesystem/fstree.cpp index 7e1bdfc..9c1b1b1 100644 --- a/src/kernel/filesystem/fstree.cpp +++ b/src/kernel/filesystem/fstree.cpp @@ -212,7 +212,7 @@ void RootFSTree::getDents(Path p, FSDirectoryListing* buffer){ buffer->entries[i].path.path += addCount*sizeof(FSDirectoryEntry); while (current) { strings += addCount*sizeof(FSDirectoryEntry) + buffer->stringsLength; - memcpy(current->elem->self.path, strings, current->elem->self.length); + memcpy(strings, current->elem->self.path, current->elem->self.length); buffer->entries[buffer->count++] = FSDirectoryEntry { PathEntry{ current->elem->self.length, diff --git a/src/kernel/filesystem/sysfs.cpp b/src/kernel/filesystem/sysfs.cpp new file mode 100644 index 0000000..a536346 --- /dev/null +++ b/src/kernel/filesystem/sysfs.cpp @@ -0,0 +1,28 @@ +#include "sysfs.h" + +SysFS::SysFS() { + addEntry(createPathFromString("remainingPages"), [](){ + uint32_t remainingPages = Global::kernel->phys->remainingPages; + char str[11]; + uint32_t offset = int_to_decimal(remainingPages, str); + return new OneShotReadWriter(0, str+offset); + }); + addEntry(createPathFromString("initPages"), [](){ + uint32_t initPages = Global::kernel->phys->initPages; + char str[11]; + uint32_t offset = int_to_decimal(initPages, str); + return new OneShotReadWriter(0, str+offset); + }); + addEntry(createPathFromString("terminalWidth"), [](){ + uint32_t termWidth = Global::kernel->terminal->width; + char str[11]; + uint32_t offset = int_to_decimal(termWidth, str); + return new OneShotReadWriter(0, str+offset); + }); + addEntry(createPathFromString("terminalHeight"), [](){ + uint32_t termHeight = Global::kernel->terminal->height; + char str[11]; + uint32_t offset = int_to_decimal(termHeight, str); + return new OneShotReadWriter(0, str+offset); + }); +} \ No newline at end of file diff --git a/src/kernel/filesystem/sysfs.h b/src/kernel/filesystem/sysfs.h new file mode 100644 index 0000000..48b9ec0 --- /dev/null +++ b/src/kernel/filesystem/sysfs.h @@ -0,0 +1,14 @@ +#ifndef SYSFS_H +#define SYSFS_H + +#include "vfs.h" +#include "../kernel.h" +#include "../strings.h" +#include "../stdio/oneshotreadwriter.h" + +class SysFS : public VFS { +public: + SysFS(); +}; + +#endif \ No newline at end of file diff --git a/src/kernel/filesystem/vfs.cpp b/src/kernel/filesystem/vfs.cpp new file mode 100644 index 0000000..940ca3c --- /dev/null +++ b/src/kernel/filesystem/vfs.cpp @@ -0,0 +1,133 @@ +#include "vfs.h" + +void VFS::addEntry(Path p, ReadWriter*(*constructor)(Path)) { + PathElement* currentPathElement = p.start; + + VFSTreeNode* currentNode = this->root; + + if (!currentPathElement) + return currentNode; + +nextPE: + while (currentPathElement) { + xnoe::linkedlistelem* currentChild = currentNode->children.start; + while (currentChild) { + if (currentChild->elem->self == currentPathElement->elem) { + currentNode = currentChild->elem; + currentPathElement = currentPathElement->next; + goto nextPE; + } + currentChild = currentChild->next; + } + if (currentPathElement = p.end) { + currentNode->children.append(new VFSTreeNode{currentPathElement->elem, xnoe::linkedlist(), constructor, false}); + } else { + if (currentPathElement->elem == PathEntry{1, "*"}) + currentNode->children.append(new VFSTreeNode{currentPathElement->elem, xnoe::linkedlist(), 0, true}); + else + currentNode->children.append(new VFSTreeNode{currentPathElement->elem, xnoe::linkedlist(), 0, false}); + } + currentNode = currentNode->children.end->elem; + currentPathElement = currentPathElement->next; + } + + return currentNode; +} + +Constructor VFS::getEntry(Path p) { + PathElement* currentPathElement = p.start; + VFSTreeNode* currentNode = this->root; + + if (!currentPathElement) + return 0; + +nextPE: + while (currentPathElement) { + xnoe::linkedlistelem* currentChild = currentNode->children.start; + while (currentChild) { + if (currentChild->elem->self == currentPathElement->elem || currentChild->elem->wildcard) { + currentNode = currentChild->elem; + currentPathElement = currentPathElement->next; + goto nextPE; + } + currentChild = currentChild->next; + } + return 0; + } + if (currentNode->children.length == 0) + return currentNode->constructor; + return 0; +} + +VFSTreeNode* VFS::getNode(Path p) { + PathElement* currentPathElement = p.start; + VFSTreeNode* currentNode = this->root; + +nextPE: + while (currentPathElement) { + xnoe::linkedlistelem* currentChild = currentNode->children.start; + while (currentChild) { + if (currentChild->elem->self == currentPathElement->elem || currentChild->elem->wildcard) { + currentNode = currentChild->elem; + currentPathElement = currentPathElement->next; + goto nextPE; + } + currentChild = currentChild->next; + } + return 0; + } + return currentNode; +} + +bool VFS::exists(Path p) { + return false; +} + +ReadWriter* VFS::open(Path p) { + Constructor c = getEntry(p); + return c(p); +} + +uint32_t VFS::getDentsSize(Path p) { + VFSTreeNode* node = getNode(p); + if (!node) + return 0; + + uint32_t total = sizeof(FSDirectoryListing); + xnoe::linkedlistelem* currentNode = node->children.start; + while (currentNode) { + total += sizeof(FSDirectoryEntry); + total += currentNode->elem->self.length; + currentNode = currentNode->next; + } + return total; +} + +void VFS::getDents(Path p, FSDirectoryListing* buffer) { + VFSTreeNode* node = getNode(p); + if (!node) + return; + + uint32_t total = sizeof(FSDirectoryListing); + xnoe::linkedlistelem* currentNode = node->children.start; + buffer->count = 0; + while (currentNode) { + buffer->count++; + currentNode = currentNode->next; + } + + uint8_t* strings = (uint8_t*)(buffer) + sizeof(FSDirectoryListing) + sizeof(FSDirectoryEntry) * buffer->count; + currentNode = node->children.start; + uint32_t index = 0; + while (currentNode) { + memcpy(strings, currentNode->elem->self.path, currentNode->elem->self.length); + buffer->entries[index++] = FSDirectoryEntry{ + PathEntry{currentNode->elem->self.length, strings}, + File, + 0 + }; + strings += currentNode->elem->self.length; + buffer->stringsLength += currentNode->elem->self.length; + currentNode = currentNode->next; + } +} \ No newline at end of file diff --git a/src/kernel/filesystem/vfs.h b/src/kernel/filesystem/vfs.h new file mode 100644 index 0000000..163b2d9 --- /dev/null +++ b/src/kernel/filesystem/vfs.h @@ -0,0 +1,29 @@ +#ifndef VFS_H +#define VFS_H + +#include "fstree.h" + +using Constructor = ReadWriter*(*)(Path); + +struct VFSTreeNode { + PathEntry self; + xnoe::linkedlist children; + ReadWriter*(*constructor)(Path); + bool wildcard; +}; + +class VFS : public FSTree { + VFSTreeNode* root = new VFSTreeNode{PathEntry{0,0},xnoe::linkedlist(),0,false}; +public: + + void addEntry(Path p, ReadWriter*(*)(Path)); + Constructor getEntry(Path p); + VFSTreeNode* getNode(Path p); + + bool exists(Path p) override; + ReadWriter* open(Path p) override; + uint32_t getDentsSize(Path p) override; + void getDents(Path p, FSDirectoryListing* buffer) override; +}; + +#endif \ No newline at end of file diff --git a/src/kernel/global.cpp b/src/kernel/global.cpp index 29a4dd5..785553a 100644 --- a/src/kernel/global.cpp +++ b/src/kernel/global.cpp @@ -32,4 +32,12 @@ void* operator new[] (uint32_t size) { void operator delete[] (void* ptr) { Global::allocator->deallocate((uint32_t)ptr); +} + +int clamp(int a, int b, int c) { + if (a < b) + return b; + if (a > c) + return c; + return a; } \ No newline at end of file diff --git a/src/kernel/global.h b/src/kernel/global.h index 0cf4d83..de1df7a 100644 --- a/src/kernel/global.h +++ b/src/kernel/global.h @@ -27,4 +27,6 @@ void operator delete (void* ptr, unsigned int size); void* operator new[] (uint32_t size); void operator delete[] (void* ptr); +int clamp(int a, int b, int c); + #endif \ No newline at end of file diff --git a/src/kernel/kernel.cpp b/src/kernel/kernel.cpp index ff3a788..fbca1f2 100644 --- a/src/kernel/kernel.cpp +++ b/src/kernel/kernel.cpp @@ -87,7 +87,7 @@ void Kernel::v86(uint16_t ax, uint16_t bx, uint16_t cx, uint16_t es, uint16_t di // Copy 19 bytes from payload to 0x7c00 - memcpy(payload, (uint8_t*)0x7c00, 21); + memcpy((uint8_t*)0x7c00, payload, 21); asm("lea _after_iret, %eax"); asm("push %eax"); diff --git a/src/kernel/kmain.cpp b/src/kernel/kmain.cpp index 316550f..0f445d7 100644 --- a/src/kernel/kmain.cpp +++ b/src/kernel/kmain.cpp @@ -16,6 +16,7 @@ #include "filesystem/fstree.h" #include "filesystem/fat16.h" #include "filesystem/devfs.h" +#include "filesystem/sysfs.h" struct KernelInformationStruct { PDE* pde; @@ -58,6 +59,7 @@ int main(KernelInformationStruct kstruct) { kernel.rootfs = new RootFSTree(); kernel.rootfs->mount(createPathFromString("/dev"), new DevFS()); + kernel.rootfs->mount(createPathFromString("/sys"), new SysFS()); kernel.rootfs->mount(createPathFromString("/"), new FAT16FS(kernel.rootfs->open(createPathFromString("/dev/ata")))); ReadWriter* worldbin = kernel.rootfs->open(createPathFromString("/world.bin")); diff --git a/src/kernel/memory.cpp b/src/kernel/memory.cpp index bb7076d..c501917 100644 --- a/src/kernel/memory.cpp +++ b/src/kernel/memory.cpp @@ -5,7 +5,7 @@ void memset(uint8_t* address, uint32_t count, uint8_t value) { address[i] = value; } -void memcpy(uint8_t* src, uint8_t* dst, uint32_t count) { +void memcpy(uint8_t* dst, uint8_t* src, uint32_t count) { for (int i = 0; ilength = strlen(toRead); + + this->buffer = new uint8_t[this->length]; + + memcpy(this->buffer, toRead, this->length); +} + +uint32_t OneShotReadWriter::read(uint32_t count, uint8_t* buffer) { + uint32_t c=0; + while (index < length && c < count) { + buffer[c++] = this->buffer[index++]; + } + return c; +} + +uint32_t OneShotReadWriter::size() { + return length; +} + +uint32_t OneShotReadWriter::seek(uint32_t position) { + index = clamp(0, length, position); + return index; +} \ No newline at end of file diff --git a/src/kernel/stdio/oneshotreadwriter.h b/src/kernel/stdio/oneshotreadwriter.h new file mode 100644 index 0000000..5dbf490 --- /dev/null +++ b/src/kernel/stdio/oneshotreadwriter.h @@ -0,0 +1,22 @@ +#ifndef ONESHOTREADWRITER_H +#define ONESHOTREADWRITER_H + +#include "readwriter.h" +#include "../strings.h" +#include "../memory.h" + +class OneShotReadWriter : public ReadWriter { +private: + uint8_t* buffer=0; + uint32_t length; + uint32_t index=0; + +public: + OneShotReadWriter(uint32_t owner, uint8_t* toRead); + + uint32_t read(uint32_t count, uint8_t* buffer) override; + uint32_t size() override; + uint32_t seek(uint32_t position) override; +}; + +#endif \ No newline at end of file diff --git a/src/kernel/strings.cpp b/src/kernel/strings.cpp index 3d4b851..31ce3f8 100644 --- a/src/kernel/strings.cpp +++ b/src/kernel/strings.cpp @@ -1,5 +1,11 @@ #include "strings.h" +uint32_t strlen(char* s) { + uint32_t c = 0; + while (s[c++]); + return c; +} + bool strcmp(char* a, char* b, int max) { int index = 0; while (index < max) { diff --git a/src/kernel/strings.h b/src/kernel/strings.h index 300138c..ebe1a74 100644 --- a/src/kernel/strings.h +++ b/src/kernel/strings.h @@ -1,6 +1,9 @@ #ifndef STRINGS_H #define STRINGS_H +#include "types.h" + +uint32_t strlen(char* s); bool strcmp(char* a, char* b, int max); char* split_on_first(char delimeter, char* string); int string_split(char delimeter, char* string, char** pointer_array); diff --git a/src/kernel/terminal.cpp b/src/kernel/terminal.cpp index 6c3e6aa..33625d1 100644 --- a/src/kernel/terminal.cpp +++ b/src/kernel/terminal.cpp @@ -11,14 +11,6 @@ int strToInt(char* str, uint32_t max) { return r; } -int clamp(int a, int b, int c) { - if (a < b) - return b; - if (a > c) - return c; - return a; -} - void Terminal::scroll_up(uint32_t count) { for (int i=0; i\n", selectedBuf); writeStrToBuf(":clear\n", selectedBuf); writeStrToBuf(" Clears the buffer\n", selectedBuf); + writeStrToBuf(":type \n", selectedBuf); + writeStrToBuf(" Writes out the contents of the file \n", selectedBuf); writeStrToBuf("--------\n", selectedBuf); } else if (strcmpcnt(4, buf, "kill")) { @@ -295,6 +297,12 @@ int main() { free(listing); } else if (strcmpcnt(5, buf, "clear")) { clearBuf(selectedBuf); + } else if (strcmpcnt(4, buf, "type")) { + uint32_t f = fopen(buf+5); + char c; + while (read(1, f, &c)) + writeCountToBuf(1, &c, selectedBuf); + fclose(f); } } else { if (selectedBuf->process)