From 21bfca4ad4b84768f05eb4fa2bc0ad7a76b6c536 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 15 Nov 2009 13:17:58 +0100 Subject: Mount points seem to work, mostly owing to dark magic. --- Source/Kernel/Core/kmain.wtf.cpp | 5 +-- Source/Kernel/FileSystems/RamFS/RamFS.class.cpp | 11 ++++- Source/Kernel/FileSystems/RamFS/RamFS.class.h | 4 +- .../Kernel/FileSystems/RamFS/RamFileNode.class.h | 2 + Source/Kernel/Shell/KernelShell.class.cpp | 47 ++++++++++++++++++++++ Source/Kernel/VFS/DirectoryNode.class.cpp | 45 ++++++++++++++++++++- Source/Kernel/VFS/DirectoryNode.class.h | 15 +++---- Source/Kernel/VFS/FSNode.proto.h | 4 +- Source/Kernel/VFS/FileSystem.proto.h | 13 ++++-- Source/Kernel/VFS/VFS.ns.cpp | 35 ++++++++++++---- Source/Kernel/VFS/VFS.ns.h | 12 ++++-- 11 files changed, 163 insertions(+), 30 deletions(-) (limited to 'Source') diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 0486702..d0751d1 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -182,11 +182,10 @@ void kmain(multiboot_info_t* mbd, u32int magic) { //*************************************** MOUNT ROOT FILESYSTEM - FileSystem* fs = RamFS::mount((u8int*)mods[0].mod_start, 1024 * 1024, NULL); + RamFS::mount((u8int*)mods[0].mod_start, 1024 * 1024, NULL); DirectoryNode* cwd; - cwd = fs->getRootNode(); + cwd = VFS::getRootNode(); Task::currProcess()->setCwd(cwd); - VFS::setRootNode(cwd); if (keymap != "builtin") { if (!Kbd::loadKeymap(keymap)) *kvt << "\nWARNING : Could not load keymap " << keymap << ", using built-in keymap instead."; diff --git a/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp b/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp index 5997841..e6370d0 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp +++ b/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp @@ -1,30 +1,36 @@ #include "RamFS.class.h" #include #include "RamFileNode.class.h" +#include RamFS::RamFS() { } RamFS::~RamFS() { - delete m_rootNode; } RamFS* RamFS::mount(u32int maxSize, DirectoryNode* mountpoint) { + if (mountpoint != 0 and !mountpoint->mountpointable()) return 0; RamFS* rfs = new RamFS(); rfs->m_maxSize = maxSize; rfs->m_usedSize = 0; rfs->m_isWritable = true; rfs->m_rootNode = new DirectoryNode("/", rfs, mountpoint); + if (mountpoint != 0) mountpoint->mount(rfs->m_rootNode); + VFS::registerFilesystem(rfs); return rfs; } RamFS* RamFS::mount(u8int *ptr, u32int maxSize, DirectoryNode* mountpoint, bool writable) { + if (mountpoint != 0 and !mountpoint->mountpointable()) return 0; RamFS* rfs = new RamFS(); rfs->m_maxSize = maxSize; rfs->m_usedSize = 0; rfs->m_isWritable = true; rfs->m_rootNode = new DirectoryNode("/", rfs, mountpoint); + if (mountpoint != 0) mountpoint->mount(rfs->m_rootNode); + VFS::registerFilesystem(rfs); union { u8int* c; @@ -81,7 +87,7 @@ RamFS* RamFS::mount(u8int *ptr, u32int maxSize, DirectoryNode* mountpoint, bool } bool RamFS::unmount() { - return m_rootNode->unmountable(); + return true; } bool RamFS::setName(FSNode* node, String name) { return true; } @@ -164,6 +170,7 @@ bool RamFS::remove(DirectoryNode* parent, FSNode* node) { if (node->type() == NT_FILE) { u8int *d = ((RamFileNode*)node)->m_data; if (d != 0) Mem::free(d); + ((RamFileNode*)node)->m_data = 0; } return true; } diff --git a/Source/Kernel/FileSystems/RamFS/RamFS.class.h b/Source/Kernel/FileSystems/RamFS/RamFS.class.h index 1d60796..5ce85f1 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFS.class.h +++ b/Source/Kernel/FileSystems/RamFS/RamFS.class.h @@ -17,10 +17,10 @@ struct initrd_file_header { class RamFS : public FileSystem { private: - ~RamFS(); + virtual ~RamFS(); RamFS(const RamFS& other); RamFS(); - bool unmount(); //TO BE USED ONLY BY VFS::UNMOUNT (when will exist...) + bool unmount(); u32int m_maxSize; u32int m_usedSize; diff --git a/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h b/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h index d600630..2abad64 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h +++ b/Source/Kernel/FileSystems/RamFS/RamFileNode.class.h @@ -11,6 +11,8 @@ class RamFileNode : public FileNode { u32int uid = 0, u32int gid = 0) : FileNode(name, fs, parent, 0, permissions, uid, gid), m_data(0) {} + ~RamFileNode() { if (m_data != 0) delete m_data; } + u8int *m_data; //We don't take care of allocation/freeing here, RamFS:: does that for us void setLength(u32int length) { m_length = length; } diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index d62d822..8f71b9f 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include u32int KernelShell::m_instances = 0; @@ -92,6 +93,52 @@ u32int KernelShell::run() { } else if (tokens[0] == "exit") { if (tokens.size() == 1) return 0; return tokens[1].toInt(); + } else if (tokens[0] == "mount") { + if (tokens.size() == 1) { + for (u32int i = 0; i < VFS::filesystems.size(); i++) { + *m_vt << VFS::path(VFS::filesystems[i]->getRootNode()) << "\n"; + } + } else if (tokens.size() == 3) { + if (tokens[1] == "ramfs") { + FSNode* n = VFS::find(tokens[2], m_cwd); + if (n == 0) { + *m_vt << "No such directory.\n"; + } else if (n->type() != NT_DIRECTORY) { + *m_vt << "Not a directory.\n"; + } else { + if (RamFS::mount(100000, (DirectoryNode*)n) != 0) { + *m_vt << "Ok...\n"; + } else { + *m_vt << "Error !\n"; + } + } + } else { + *m_vt << "Not supported yet.\n"; + } + } else { + *m_vt << "Usage: mount [ \n"; + } + } else if (tokens[0] == "unmount") { + if (tokens.size() == 2) { + FSNode* n = VFS::find(tokens[1], m_cwd); + bool ok = false; + if (n == 0) { + ok = false; + } else { + String p = VFS::path(n); + for (u32int i = 0; i < VFS::filesystems.size(); i++) { + if (VFS::path(VFS::filesystems[i]->getRootNode()) == p) { + VFS::unmount(VFS::filesystems[i]); + ok = true; + break; + } + } + } + if (ok) *m_vt << "Ok, filesystem unmounted.\n"; + else *m_vt << "Error.\n"; + } else { + *m_vt << "Usage: unmount \n"; + } } else if (tokens[0] != "" or tokens.size() != 1) { u32int i = 0; bool found = false; diff --git a/Source/Kernel/VFS/DirectoryNode.class.cpp b/Source/Kernel/VFS/DirectoryNode.class.cpp index 74c1ff8..7da6fe6 100644 --- a/Source/Kernel/VFS/DirectoryNode.class.cpp +++ b/Source/Kernel/VFS/DirectoryNode.class.cpp @@ -6,6 +6,15 @@ call_t DirectoryNode::m_callTable[] = { CALL0(0, 0) }; +DirectoryNode::~DirectoryNode() { + if (m_contentLoaded) { + for (u32int i = 0; i < m_children.size(); i++) { + delete m_children[i]; + } + } + if (m_name == "/") ((DirectoryNode*)(m_parent))->unmount(); +} + u32int DirectoryNode::getIdxChildSC(u32int idx) { if (!runnable()) return (u32int) - 1; FSNode* n = getChild(idx); @@ -21,15 +30,29 @@ u32int DirectoryNode::getNameChildSC(u32int name) { return (u32int) - 1; } +u64int DirectoryNode::getLength() { + if (m_mounts != 0) return m_mounts->getLength(); + if (!m_contentLoaded) + if (!loadContent()) + return 0; + return m_length; +} + +FSNode* DirectoryNode::getParent() { + //if (m_name == "/" and m_parent != 0) return m_parent->getParent(); + return m_parent; +} + bool DirectoryNode::removable() { if (!m_contentLoaded) if (!loadContent()) return false; - return m_children.empty(); + return m_children.empty() && (m_mounts == 0); } bool DirectoryNode::unmountable() { if (!m_contentLoaded) return true; + if (m_mounts != 0) return false; for (u32int i = 0; i < m_children.size(); i++) { if (m_children[i]->type() == NT_DIRECTORY) { if (!((DirectoryNode*)m_children[i])->unmountable()) return false; @@ -40,7 +63,22 @@ bool DirectoryNode::unmountable() { return true; } +bool DirectoryNode::mountpointable() { + if (!m_contentLoaded) + if (!loadContent()) return false; + return m_children.empty(); +} + +void DirectoryNode::mount(DirectoryNode* childRoot) { + m_mounts = childRoot; +} + +void DirectoryNode::unmount() { + m_mounts = 0; +} + bool DirectoryNode::loadContent() { + if (m_mounts != 0) return m_mounts->loadContent(); if (m_contentLoaded) return true; bool b = m_fs->loadContents(this); if (!b) return false; @@ -50,6 +88,7 @@ bool DirectoryNode::loadContent() { } FSNode* DirectoryNode::getChild(u32int index) { + if (m_mounts != 0) return m_mounts->getChild(index); if (!m_contentLoaded) if (!loadContent()) return NULL; @@ -58,6 +97,7 @@ FSNode* DirectoryNode::getChild(u32int index) { } FSNode* DirectoryNode::getChild(const String& name) { + if (m_mounts != 0) return m_mounts->getChild(name); if (!m_contentLoaded) if (!loadContent()) return NULL; @@ -69,18 +109,21 @@ FSNode* DirectoryNode::getChild(const String& name) { } FileNode* DirectoryNode::createFile(const String& name) { + if (m_mounts != 0) return m_mounts->createFile(name); FileNode* n = m_fs->createFile(this, name); m_length = m_children.size(); return n; } DirectoryNode* DirectoryNode::createDirectory(const String& name) { + if (m_mounts != 0) return m_mounts->createDirectory(name); DirectoryNode* n = m_fs->createDirectory(this, name); m_length = m_children.size(); return n; } bool DirectoryNode::remove(FSNode* child) { + if (m_mounts != 0) return m_mounts->remove(child); //Check node is indeed one of our childs if (!m_contentLoaded) if (!loadContent()) diff --git a/Source/Kernel/VFS/DirectoryNode.class.h b/Source/Kernel/VFS/DirectoryNode.class.h index 4d9b211..1fc4c52 100644 --- a/Source/Kernel/VFS/DirectoryNode.class.h +++ b/Source/Kernel/VFS/DirectoryNode.class.h @@ -8,6 +8,7 @@ class DirectoryNode : public FSNode { protected: Vector m_children; bool m_contentLoaded; + DirectoryNode* m_mounts; //Root node of the filesystem mounted here, null if none //Syscalls static call_t m_callTable[]; @@ -19,20 +20,20 @@ class DirectoryNode : public FSNode { u32int uid = 0, u32int gid = 0) : FSNode(name, fs, parent, 0, permissions, uid, gid), m_children(), m_contentLoaded(false) { addCallTable(m_callTable); + m_mounts = 0; } - virtual ~DirectoryNode() { - if (m_contentLoaded) { - for (u32int i = 0; i < m_children.size(); i++) { - delete m_children[i]; - } - } - } + virtual ~DirectoryNode(); Vector &getChildren() { return m_children; } //MUST BE USED ONLY BY FILESYSTEMS u8int type() { return NT_DIRECTORY; } + u64int getLength(); + FSNode* getParent(); bool removable(); bool unmountable(); + bool mountpointable(); + void mount(DirectoryNode* childRoot); + void unmount(); bool loadContent(); FSNode* getChild(u32int index); diff --git a/Source/Kernel/VFS/FSNode.proto.h b/Source/Kernel/VFS/FSNode.proto.h index 0aafc8a..a46c79d 100644 --- a/Source/Kernel/VFS/FSNode.proto.h +++ b/Source/Kernel/VFS/FSNode.proto.h @@ -44,12 +44,12 @@ class FSNode : public Ressource { virtual bool used() { return false; } //True if file is read/written from/to const String& getName() { return m_name; } - u64int getLength() { return m_length; } + virtual u64int getLength() { return m_length; } u32int getPermissions() { return m_permissions; } u32int getUid() { return m_uid; } u32int getGid() { return m_gid; } FileSystem *getFS() { return m_fs; } - FSNode* getParent() { return m_parent; } + virtual FSNode* getParent() { return m_parent; } //Helper functions bool readable(User* user = 0); diff --git a/Source/Kernel/VFS/FileSystem.proto.h b/Source/Kernel/VFS/FileSystem.proto.h index a614c13..93b37f8 100644 --- a/Source/Kernel/VFS/FileSystem.proto.h +++ b/Source/Kernel/VFS/FileSystem.proto.h @@ -5,17 +5,24 @@ class FSNode; class FileNode; class DirectoryNode; +class FileSystem; + +namespace VFS { + bool unmount(FileSystem*); +} //This abstract class describes a filesystem class FileSystem { + friend bool VFS::unmount(FileSystem*); + protected: - virtual ~FileSystem() {} + virtual ~FileSystem(); bool m_isWritable; //false = read only DirectoryNode* m_rootNode; - public: - bool unmount(); + virtual bool unmount() = 0; //Sync data with the disk + public: bool isWritable() { return m_isWritable; } DirectoryNode* getRootNode() { return m_rootNode; } diff --git a/Source/Kernel/VFS/VFS.ns.cpp b/Source/Kernel/VFS/VFS.ns.cpp index e95b911..5ebb697 100644 --- a/Source/Kernel/VFS/VFS.ns.cpp +++ b/Source/Kernel/VFS/VFS.ns.cpp @@ -1,19 +1,40 @@ #include "VFS.ns.h" #include +#include + +FileSystem::~FileSystem() { delete m_rootNode; } namespace VFS { -DirectoryNode *rootNode; +DirectoryNode *rootNode = 0; +Vector filesystems; -//TODO : mount stuff +DirectoryNode* getRootNode() { + return rootNode; +} -bool setRootNode(DirectoryNode* node) { - rootNode = node; - return true; +void registerFilesystem(FileSystem* fs) { + unregisterFilesystem(fs); + filesystems.push(fs); + if (rootNode == 0) rootNode = fs->getRootNode(); } -DirectoryNode* getRootNode() { - return rootNode; +void unregisterFilesystem(FileSystem* fs) { + for (u32int i = 0; i < filesystems.size(); i++) { + if (filesystems[i] == fs) { + filesystems[i] = filesystems.back(); + filesystems.pop(); + break; + } + } +} + +bool unmount(FileSystem* fs) { + if (!fs->getRootNode()->unmountable()) return false; + if (fs->getRootNode() == rootNode) return false; + if (!fs->unmount()) return false; + delete fs; //Will automatically delete the root node (destructor is in this file); + return true; } FSNode* find(const String& path, FSNode* start) { diff --git a/Source/Kernel/VFS/VFS.ns.h b/Source/Kernel/VFS/VFS.ns.h index f1d628f..21a1e77 100644 --- a/Source/Kernel/VFS/VFS.ns.h +++ b/Source/Kernel/VFS/VFS.ns.h @@ -3,15 +3,21 @@ #include #include +#include -typedef FileSystem* (* mountcallback)(Partition* partition); +typedef FileSystem* (* mount_callback_t)(Partition* partition); namespace VFS { - void registerMountCallback(mountcallback mcb); + extern Vector filesystems; + + void registerMountCallback(mount_callback_t mcb); bool mount(Partition* partition, DirectoryNode *mountpoint); - bool setRootNode(DirectoryNode* root); DirectoryNode* getRootNode(); + void registerFilesystem(FileSystem* fs); + void unregisterFilesystem(FileSystem* fs); + bool unmount(FileSystem* fs); + FSNode* find(const String& path, FSNode* start = 0); FSNode* createFile(const String& path, FSNode* start = 0, bool vrfyperm = false); FSNode* createDirectory(const String& path, FSNode* start = 0, bool vrfyperm = false); -- cgit v1.2.3 From ca1b573ef87498595a30b757d6d9c66d12d14ae6 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 15 Nov 2009 17:42:07 +0100 Subject: Reading from the FAT12-formatted floppy works \o --- Source/Applications/Demos/GOL.cpp | 31 ++-- Source/Kernel/Core/Sys.ns.h | 3 + Source/Kernel/Core/kmain.wtf.cpp | 7 +- .../FileSystems/FAT/FATDirectoryNode.class.h | 16 ++ Source/Kernel/FileSystems/FAT/FATFS.class.cpp | 201 +++++++++++++++++++++ Source/Kernel/FileSystems/FAT/FATFS.class.h | 130 +++++++++++++ Source/Kernel/FileSystems/FAT/FATFileNode.class.h | 16 ++ Source/Kernel/Makefile | 1 + Source/Kernel/Shell/KernelShell.class.cpp | 3 +- Source/Library/Common/Rand.ns.cpp | 2 +- 10 files changed, 392 insertions(+), 18 deletions(-) create mode 100644 Source/Kernel/FileSystems/FAT/FATDirectoryNode.class.h create mode 100644 Source/Kernel/FileSystems/FAT/FATFS.class.cpp create mode 100644 Source/Kernel/FileSystems/FAT/FATFS.class.h create mode 100644 Source/Kernel/FileSystems/FAT/FATFileNode.class.h (limited to 'Source') diff --git a/Source/Applications/Demos/GOL.cpp b/Source/Applications/Demos/GOL.cpp index 5848c2c..32eb30a 100644 --- a/Source/Applications/Demos/GOL.cpp +++ b/Source/Applications/Demos/GOL.cpp @@ -40,20 +40,24 @@ int main(Vector args) { outvt << String(tmp, w*h) << "Press Ctrl+h for help"; //Compute next generation - for (u32int y = 0; y < h; y++) { - for (u32int x = 0; x < w; x++) { + for (int y = 0; y < h; y++) { + for (int x = 0; x < w; x++) { u8int n = 0; - for (u32int yy = y - 1; yy <= y + 1; yy++) { - for (u32int xx = x - 1; xx <= x + 2; xx++) { - if (xx < w and yy < h and cells[xx * h + yy]) n++; + for (int yy = y - 1; yy < y + 2; yy++) { + for (int xx = x - 1; xx < x + 2; xx++) { + if (xx < w and yy < h and xx >= 0 and yy >= 0 + and cells[xx * h + yy]) n++; } } - if (cells[x * h + y]) n--; - if ((cells[x * h + y] and n == 2) or n == 3) { - newcells[x * h + y] = true; + newcells[x * h + y] = cells[x * h + y]; + if (cells[x * h + y]) { + n--; + if (n < 2) newcells[x * h + y] = false; + if (n > 3) newcells[x * h + y] = false; } else { - newcells[x * h + y] = false; + if (n == 3) newcells[x* h + y] = true; } + } } for (u32int x = 0; x < w; x++) { @@ -73,11 +77,10 @@ int main(Vector args) { cells[x * h + y] = true; } } else if (kp.character == WChar("R")) { - for (u32int i = 0; i < h; i++) { - cells[i] = true; - cells[(2 * i) % (h - i)] = true; - cells[(w * i) % (h * w - i)] = true; - cells[(w * i) % (h * w - i) + w] = true; + for (u32int i = 0; i < 150; i++) { + u64int x = Rand::rand() * w / Rand::max(); + u64int y = Rand::rand() * h / Rand::max(); + cells[x * h + y] = true; } } else if (kp.character == WChar("h")) { outvt << "\n\n** Melon's demo Game Of Life Simulator help :\n"; diff --git a/Source/Kernel/Core/Sys.ns.h b/Source/Kernel/Core/Sys.ns.h index 4d15676..9b34dbf 100644 --- a/Source/Kernel/Core/Sys.ns.h +++ b/Source/Kernel/Core/Sys.ns.h @@ -18,9 +18,12 @@ //This file contains system-relative functions class String; +class SimpleVT; class VirtualTerminal; struct registers_t; +extern SimpleVT* kvt; + namespace Sys { void outb(u16int port, u8int value); u8int inb(u16int port); diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index d0751d1..bb77eeb 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -37,6 +38,8 @@ extern u32int end; //Placement address extern "C" void kmain(multiboot_info_t* mbd, u32int magic); +SimpleVT* kvt; + u32int logoAnimation(void* p) { SimpleVT& vt = *((SimpleVT*)p); vt.setColor(8); @@ -140,7 +143,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { Disp::setText(vgaout); //Create a VT for logging what kernel does - SimpleVT *kvt = new ScrollableVT(25, 80, 20, KVT_FGCOLOR, KVT_BGCOLOR); + kvt = new ScrollableVT(25, 80, 20, KVT_FGCOLOR, KVT_BGCOLOR); kvt->map(0, 0); *kvt << "Melon is loading..."; @@ -187,6 +190,8 @@ void kmain(multiboot_info_t* mbd, u32int magic) { cwd = VFS::getRootNode(); Task::currProcess()->setCwd(cwd); + FATFS::mount(Part::partitions[0], (DirectoryNode*)VFS::createDirectory("/Mount")); + if (keymap != "builtin") { if (!Kbd::loadKeymap(keymap)) *kvt << "\nWARNING : Could not load keymap " << keymap << ", using built-in keymap instead."; } diff --git a/Source/Kernel/FileSystems/FAT/FATDirectoryNode.class.h b/Source/Kernel/FileSystems/FAT/FATDirectoryNode.class.h new file mode 100644 index 0000000..c2f55e1 --- /dev/null +++ b/Source/Kernel/FileSystems/FAT/FATDirectoryNode.class.h @@ -0,0 +1,16 @@ +#ifndef DEF_FATDIRECTORYNODE_CLASS_H +#define DEF_FATDIRECTORYNODE_CLASS_H + +#include + +class FATDirectoryNode : public DirectoryNode { + friend class FATFS; + FATDirectoryNode(String name, FileSystem* fs, FSNode* parent, u32int permissions = 0777, + u32int uid = 0, u32int gid = 0) : + DirectoryNode(name, fs, parent, permissions, uid, gid) {} + + u32int m_firstCluster; + u32int m_firstDirEntryID; //id of the first directory entry corresponding to this file in parent directory +}; + +#endif diff --git a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp new file mode 100644 index 0000000..2590785 --- /dev/null +++ b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp @@ -0,0 +1,201 @@ +#include "FATFS.class.h" +#include +#include "FATFileNode.class.h" +#include "FATDirectoryNode.class.h" +#include + +#define FIRSTCLUS(node) ((u32int&)(node->type() == NT_DIRECTORY ? \ + ((FATDirectoryNode*)(node))->m_firstCluster : \ + ((FATFileNode*)(node))->m_firstCluster)) +#define FIRSTDEID(node) ((u32int&)(node->type() == NT_DIRECTORY ? \ + ((FATDirectoryNode*)(node))->m_firstDirEntryID : \ + ((FATFileNode*)(node))->m_firstDirEntryID)) + +FATFS* FATFS::mount(Partition* p, DirectoryNode* mountpoint) { + if (mountpoint != 0 and !mountpoint->mountpointable()) return 0; + // *** READ BOOT SECTOR *** + union { + fat_BS_t s; + u8int c[512]; + } bs; + p->readBlocks(0, 1, bs.c); + // *** CHECK FILESYSTEM TYPE *** + if (bs.s.extBS_16.boot_signature != 0x28 and bs.s.extBS_16.boot_signature != 0x29 + and bs.s.extBS_32.boot_signature != 0x28 and bs.s.extBS_32.boot_signature != 0x29) return 0; + // *** DO SOME CALCULATIONS *** + FATFS* fs = new FATFS(); + fs->m_fatSize = (bs.s.table_size_16 == 0 ? bs.s.extBS_32.table_size_32 : bs.s.table_size_16); + fs->m_totalSectors = (bs.s.total_sectors_16 == 0 ? bs.s.total_sectors_32 : bs.s.total_sectors_16); + fs->m_rootDirSectors = ((bs.s.root_entry_count * 32) + (bs.s.bytes_per_sector - 1)) / bs.s.bytes_per_sector; + fs->m_firstDataSector = bs.s.reserved_sector_count + (fs->m_fatSize * bs.s.table_count); + fs->m_clusterSize = bs.s.bytes_per_sector * bs.s.sectors_per_cluster; + u32int dataSectors = fs->m_totalSectors - (fs->m_firstDataSector + fs->m_rootDirSectors); + fs->m_countOfClusters = dataSectors / bs.s.sectors_per_cluster; + if (fs->m_countOfClusters < 4085) { //Find out FAT type + fs->m_fatType = 12; + } else if (fs->m_countOfClusters < 65525) { + fs->m_fatType = 16; + } else { + fs->m_fatType = 32; + } + fs->m_readOnly = true; + fs->m_bs = bs.s; + fs->m_part = p; + // *** CREATE ROOT DIRECTORY NODE *** + fs->m_rootNode = new FATDirectoryNode("/", fs, mountpoint); + FIRSTCLUS(fs->m_rootNode) = 2; + if (fs->m_fatType == 32) FIRSTCLUS(fs->m_rootNode) = bs.s.extBS_32.root_cluster; + if (mountpoint != 0) mountpoint->mount(fs->m_rootNode); + VFS::registerFilesystem(fs); + *kvt << "\nDetected a FAT" << (s64int)fs->m_fatType << " filesystem.\n" << + "root_dir_sectors:" << fs->m_rootDirSectors << " fat_size:" << fs->m_fatSize << " total_sectors:" << + fs->m_totalSectors << " data_sectors:" << dataSectors << " count_of_clusters:" << fs->m_countOfClusters << + " sizeof(fat_dir_entry_t):" << sizeof(fat_dir_entry_t) << " first_data_sector:" << fs->m_firstDataSector; + return 0; +} + +u32int FATFS::nextCluster(u32int cluster) { + u8int fat_table[m_part->getBlockSize()]; + u32int val; + if (m_fatType == 12) { + u32int fat_offset = cluster + (cluster / 2); + u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->getBlockSize()); + u32int ent_offset = fat_offset % m_part->getBlockSize(); + m_part->readBlocks(fat_sector, 1, fat_table); + u16int tblval = *(u16int*)&fat_table[ent_offset]; + if (cluster & 1) val = tblval >> 4; + else val = tblval & 0x0FFF; + if (val >= 0xFF7) val = 0; + } else if (m_fatType == 16) { + u32int fat_offset = cluster * 2; + u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->getBlockSize()); + u32int ent_offset = fat_offset % m_part->getBlockSize(); + m_part->readBlocks(fat_sector, 1, fat_table); + u16int tblval = *(u16int*)&fat_table[ent_offset]; + val = tblval; + if (tblval >= 0xFFF7) val = 0; + } else if (m_fatType == 32) { + u32int fat_offset = cluster * 4; + u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->getBlockSize()); + u32int ent_offset = fat_offset % m_part->getBlockSize(); + m_part->readBlocks(fat_sector, 1, fat_table); + val = *(u32int*)&fat_table[ent_offset] & 0x0FFFFFFF; + if (val >= 0x0FFFFFF7) val = 0; + } + return val; +} + +void FATFS::readCluster(u32int cluster, u8int* data) { + u32int firstSector = ((cluster - 2) * m_bs.sectors_per_cluster) + m_firstDataSector; + if (cluster > 2 and m_fatType != 32) firstSector += m_rootDirSectors; + m_part->readBlocks(firstSector, m_bs.sectors_per_cluster, data); +} + +bool FATFS::unmount() { + if (m_readOnly) return true; + return false; +} + +bool FATFS::setName(FSNode* node, String name) { + if (m_readOnly) return false; + return false; +} + +bool FATFS::setPermissions(FSNode* node, u32int permissions) { + if (m_readOnly) return false; + return false; +} + +bool FATFS::setUid(FSNode* node, u32int uid) { + if (m_readOnly) return false; + return false; +} + +bool FATFS::setGid(FSNode* node, u32int gid) { + if (m_readOnly) return false; + return false; +} + +bool FATFS::setParent(FSNode* node, FSNode* parent) { + if (m_readOnly) return false; + return false; +} + +u32int FATFS::read(FileNode* file, u64int position, u32int max_length, u8int *data) { + return 0; +} + +bool FATFS::write(FileNode* file, u64int position, u32int length, u8int* data) { + if (m_readOnly) return false; + return false; +} + +bool FATFS::truncate(FileNode* file) { + if (m_readOnly) return false; + return false; +} + +bool FATFS::loadContents(DirectoryNode* dir) { + u32int cluster = FIRSTCLUS(dir); + union { + u8int *c; + fat_dir_entry_t *e; + } e; + + u32int entries = m_clusterSize / sizeof(fat_dir_entry_t); + if (cluster == 2 and m_fatType != 32) { //This is the value we use for the root directory + e.c = (u8int*)Mem::alloc(m_rootDirSectors * m_part->getBlockSize()); + m_part->readBlocks(m_firstDataSector, m_rootDirSectors, e.c); + } else { + e.c = (u8int*)Mem::alloc(m_clusterSize); + } + + while (cluster != 0) { + if (cluster != 2 or m_fatType == 32) readCluster(cluster, e.c); + for (u32int i = 0; i < entries; i++) { + if (e.e[i].name[0] == 0 or e.e[i].name[0] == 0xE5) continue; //Nothing intresting here. + if (e.e[i].attributes == FA_LFN) continue; //Long file name entry, nothing intresting + if (e.e[i].attributes & FA_VOLUMEID) continue; + String name; + for (int j = 0; j < 8; j++) { + if (e.e[i].name[j] == ' ') break; + name += WChar(e.e[i].name[j]); + } + for (int j = 0; j < 3; j++) { + if (e.e[i].extension[j] == ' ') break; + if (j == 0) name += "."; + name += WChar(e.e[i].extension[j]); + } + u32int first_clus = (e.e[i].first_clust_high << 16) + e.e[i].first_clust_low; + FSNode* n; + if (e.e[i].attributes & FA_DIRECTORY) { + if (name == "." or name == "..") continue; + n = new FATDirectoryNode(name, this, dir); + } else { + n = new FATFileNode(name, this, dir, e.e[i].size); + } + FIRSTCLUS(n) = first_clus; + dir->getChildren().push(n); + } + if (cluster == 2 && m_fatType != 32) break; //We are in a FAT12/16 root directory + cluster = nextCluster(cluster); + } + + Mem::free(e.c); + return true; +} + +FileNode* FATFS::createFile(DirectoryNode* parent, String name) { + if (m_readOnly) return false; + return 0; +} + +DirectoryNode* FATFS::createDirectory(DirectoryNode* parent, String name) { + if (m_readOnly) return false; + return 0; +} + +bool FATFS::remove(DirectoryNode* parent, FSNode* node) { + if (m_readOnly) return false; + return false; +} diff --git a/Source/Kernel/FileSystems/FAT/FATFS.class.h b/Source/Kernel/FileSystems/FAT/FATFS.class.h new file mode 100644 index 0000000..50ff479 --- /dev/null +++ b/Source/Kernel/FileSystems/FAT/FATFS.class.h @@ -0,0 +1,130 @@ +#ifndef DEF_FATFS_CLASS_H +#define DEF_FATFS_CLASS_H + +#include +#include + +struct fat_extBS_32_t { //Extended boot sector for FAT32 + unsigned int table_size_32; + unsigned short extended_flags; + unsigned short fat_version; + unsigned int root_cluster; + unsigned short fat_info; + unsigned short backup_BS_sector; + unsigned char reserved_0[12]; + unsigned char drive_number; + unsigned char reserved_1; + unsigned char boot_signature; + unsigned int volume_id; + unsigned char volume_label[11]; + unsigned char fat_type_label[8]; +}__attribute__((packed)); + +struct fat_extBS_16_t { //Extended boot sector for FAT12 and FAT16 + unsigned char bios_drive_num; + unsigned char reserved1; + unsigned char boot_signature; + unsigned int volume_id; + unsigned char volume_label[11]; + unsigned char fat_type_label[8]; +}__attribute__((packed)); + +struct fat_BS_t { //Boot sector + unsigned char bootjmp[3]; + unsigned char oem_name[8]; + unsigned short bytes_per_sector; + unsigned char sectors_per_cluster; + unsigned short reserved_sector_count; + unsigned char table_count; + unsigned short root_entry_count; + unsigned short total_sectors_16; + unsigned char media_type; + unsigned short table_size_16; + unsigned short sectors_per_track; + unsigned short head_side_count; + unsigned int hidden_sector_count; + unsigned int total_sectors_32; + union { + fat_extBS_32_t extBS_32; + fat_extBS_16_t extBS_16; + }; +}__attribute__((packed)); + +struct fat_date_t { + u16int year : 7; + u16int month : 4; + u16int day : 5; +}__attribute__((packed)); + +struct fat_time_t { + u16int hour : 5; + u16int minutes : 6; + u16int seconds : 5; +}__attribute__((packed)); + +struct fat_dir_entry_t { + char name[8]; + char extension[3]; + u8int attributes; + u8int reserved; + u8int createtenthsofseconds; + fat_time_t created_time; + fat_date_t created_date; + fat_date_t accessed_date; + u16int first_clust_high; //always 0 on FAT12/16 + fat_time_t modified_time; + fat_date_t modified_date; + u16int first_clust_low; + u32int size; +}__attribute__((packed)); + +#define FA_READONLY 0x01 +#define FA_HIDDEN 0x02 +#define FA_SYSTEM 0x04 +#define FA_VOLUMEID 0x08 +#define FA_DIRECTORY 0x10 +#define FA_ARCHIVE 0x20 +#define FA_LFN 0x0F + +class FATFS : public FileSystem { + private: + FATFS() {} + ~FATFS() {} + + fat_BS_t m_bs; + bool m_readOnly; + u32int m_fatSize; //Size of one FAT, in sectors + u32int m_totalSectors; //Total sectors used by the FAT + u32int m_rootDirSectors; //Sectors used by the root directory + u32int m_firstDataSector; //First data sector, start of cluster 2 + u32int m_countOfClusters; //Count of usable clusters, EXCLUDING the ones used by the root directory + u32int m_clusterSize; //size of a cluster in bytes + u32int m_fatType; //12, 16 or 32 + Partition* m_part; + + u32int nextCluster(u32int cluster); //Get the next cluster number in the chain (0 = EOF) + void readCluster(u32int cluster, u8int* data); //Read the content of a cluster to a buffer + + public: + static FATFS* mount(Partition* p, DirectoryNode* mountpoint); + + bool unmount(); + + 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); + bool remove(DirectoryNode* parent, FSNode* node); +}; + +#endif + diff --git a/Source/Kernel/FileSystems/FAT/FATFileNode.class.h b/Source/Kernel/FileSystems/FAT/FATFileNode.class.h new file mode 100644 index 0000000..b64f911 --- /dev/null +++ b/Source/Kernel/FileSystems/FAT/FATFileNode.class.h @@ -0,0 +1,16 @@ +#ifndef DEF_FATFILENODE_CLASS_H +#define DEF_FATFILENODE_CLASS_H + +#include + +class FATFileNode : public FileNode { + friend class FATFS; + FATFileNode (String name, FileSystem* fs, FSNode* parent, u32int size, u32int permissions = 0777, + u32int uid = 0, u32int gid = 0) : + FileNode(name, fs, parent, size, permissions, uid, gid){} + + u32int m_firstCluster; + u32int m_firstDirEntryID; //id of the first directory entry corresponding to this file in parent directory +}; + +#endif diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index a70c8c5..2005cd2 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -66,6 +66,7 @@ Objects = Core/loader.wtf.o \ VFS/DirectoryNode.class.o \ UserManager/Usr.ns.o \ FileSystems/RamFS/RamFS.class.o \ + FileSystems/FAT/FATFS.class.o \ SyscallManager/IDT.ns.o \ SyscallManager/Ressource.class.o \ SyscallManager/Res.ns.o \ diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index 8f71b9f..7f57f8b 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -128,8 +128,7 @@ u32int KernelShell::run() { String p = VFS::path(n); for (u32int i = 0; i < VFS::filesystems.size(); i++) { if (VFS::path(VFS::filesystems[i]->getRootNode()) == p) { - VFS::unmount(VFS::filesystems[i]); - ok = true; + ok = VFS::unmount(VFS::filesystems[i]); break; } } diff --git a/Source/Library/Common/Rand.ns.cpp b/Source/Library/Common/Rand.ns.cpp index 6323ccc..65b450c 100644 --- a/Source/Library/Common/Rand.ns.cpp +++ b/Source/Library/Common/Rand.ns.cpp @@ -2,7 +2,7 @@ namespace Rand { -u32int m = 2073741824, a = 50000, b = 1534; +u32int m = 2073741978, a = 50023, b = 1534097; u64int current = RANDOM_SEED; u64int rand() { -- cgit v1.2.3 From 3833a92d5823f0f54030dedbcadbda4ef8583b41 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 15 Nov 2009 19:33:04 +0100 Subject: Screwy implementation of FATFS::read --- Source/Kernel/Core/Sys.ns.cpp | 2 +- Source/Kernel/FileSystems/FAT/FATFS.class.cpp | 28 +++++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 3 deletions(-) (limited to 'Source') diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp index eeb92ee..49b2725 100644 --- a/Source/Kernel/Core/Sys.ns.cpp +++ b/Source/Kernel/Core/Sys.ns.cpp @@ -83,7 +83,7 @@ void dumpRegs(registers_t *regs, VirtualTerminal& vt) { void stackTrace(u32int ebp, VirtualTerminal& vt, u32int maxframes) { u32int *stack = (u32int*)ebp; - for (u32int i = 0; i < maxframes and (u32int)stack > 0xC0000000; i++) { + for (u32int i = 0; i < maxframes and (u32int)stack > 0xC0000000 and (u32int)stack < (ebp + 0x10000); i++) { vt << "Frame: " << (u32int)stack << " n:" << stack[0] << " r:" << stack[1] << "\n"; stack = (u32int*)stack[0]; } diff --git a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp index 2590785..00107e5 100644 --- a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp +++ b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp @@ -50,7 +50,8 @@ FATFS* FATFS::mount(Partition* p, DirectoryNode* mountpoint) { *kvt << "\nDetected a FAT" << (s64int)fs->m_fatType << " filesystem.\n" << "root_dir_sectors:" << fs->m_rootDirSectors << " fat_size:" << fs->m_fatSize << " total_sectors:" << fs->m_totalSectors << " data_sectors:" << dataSectors << " count_of_clusters:" << fs->m_countOfClusters << - " sizeof(fat_dir_entry_t):" << sizeof(fat_dir_entry_t) << " first_data_sector:" << fs->m_firstDataSector; + " sizeof(fat_dir_entry_t):" << sizeof(fat_dir_entry_t) << " first_data_sector:" << fs->m_firstDataSector << + " cluster_size:" << fs->m_clusterSize; return 0; } @@ -122,7 +123,30 @@ bool FATFS::setParent(FSNode* node, FSNode* parent) { } u32int FATFS::read(FileNode* file, u64int position, u32int max_length, u8int *data) { - return 0; + u32int len = max_length; + if (position >= file->getLength()) return 0; + if (position + len > file->getLength()) len = len - position; + u32int firstCluster = position / m_clusterSize, clusterOffset = position % m_clusterSize; + u32int clusters = (len + clusterOffset) / m_clusterSize + 1, lastClusBytesToRead = (len + clusterOffset) % m_clusterSize; + u32int clust = FIRSTCLUS(file); + //Find first cluster + for (u32int i = 0; i < firstCluster and clust != 0; i++) clust = nextCluster(clust); + if (clust == 0) return 0; + //Read first cluster + u8int* temp = (u8int*)Mem::alloc(m_clusterSize); + readCluster(clust, temp); + memcpy(data, temp + clusterOffset, (m_clusterSize - clusterOffset)); + //Read next clusters + u32int pos = (m_clusterSize - clusterOffset); + for (u32int i = 1; i < clusters; i++) { + clust = nextCluster(clust); + if (clust == 0) break; + readCluster(clust, temp); + memcpy(data + pos, temp, (i == clusters - 1 ? lastClusBytesToRead : m_clusterSize)); + pos += m_clusterSize; + } + Mem::free(temp); + return len; } bool FATFS::write(FileNode* file, u64int position, u32int length, u8int* data) { -- cgit v1.2.3 From 0f536540de15202d44cd9b1d708ee04edccb8c66 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Tue, 24 Nov 2009 13:00:34 +0100 Subject: Multiple things : - Partially fixed FATFS::read - Corrected some unicode encoding/decoding related stuff - Implemented LFN entries parsing --- Source/Kernel/FileSystems/FAT/FATFS.class.cpp | 36 +++++++++++----- Source/Library/Common/ByteArray.class.cpp | 4 +- Source/Library/Common/String.class.cpp | 4 +- Source/Library/Common/WChar.class.cpp | 59 ++++++++++++++++++++++----- Source/Library/Common/WChar.class.h | 30 +++++++++----- 5 files changed, 98 insertions(+), 35 deletions(-) (limited to 'Source') diff --git a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp index 00107e5..67b4013 100644 --- a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp +++ b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp @@ -3,6 +3,7 @@ #include "FATFileNode.class.h" #include "FATDirectoryNode.class.h" #include +#include #define FIRSTCLUS(node) ((u32int&)(node->type() == NT_DIRECTORY ? \ ((FATDirectoryNode*)(node))->m_firstCluster : \ @@ -125,7 +126,7 @@ bool FATFS::setParent(FSNode* node, FSNode* parent) { u32int FATFS::read(FileNode* file, u64int position, u32int max_length, u8int *data) { u32int len = max_length; if (position >= file->getLength()) return 0; - if (position + len > file->getLength()) len = len - position; + if (position + len > file->getLength()) len = file->getLength() - position; u32int firstCluster = position / m_clusterSize, clusterOffset = position % m_clusterSize; u32int clusters = (len + clusterOffset) / m_clusterSize + 1, lastClusBytesToRead = (len + clusterOffset) % m_clusterSize; u32int clust = FIRSTCLUS(file); @@ -174,21 +175,34 @@ bool FATFS::loadContents(DirectoryNode* dir) { e.c = (u8int*)Mem::alloc(m_clusterSize); } + ByteArray lfnBuffer; while (cluster != 0) { if (cluster != 2 or m_fatType == 32) readCluster(cluster, e.c); for (u32int i = 0; i < entries; i++) { - if (e.e[i].name[0] == 0 or e.e[i].name[0] == 0xE5) continue; //Nothing intresting here. - if (e.e[i].attributes == FA_LFN) continue; //Long file name entry, nothing intresting + if (e.e[i].attributes == FA_LFN && e.c[i*32] != 0xE5) { //Long file name entry + u8int num = e.c[i*32] & 0x3; + if (lfnBuffer.size() < num * 26) lfnBuffer.resize(num * 26); + num--; + memcpy(lfnBuffer + (num * 26), e.c + (i*32 + 1), 10); + memcpy(lfnBuffer + (num * 26 + 10), e.c + (i*32 + 14), 12); + memcpy(lfnBuffer + (num * 26 + 22), e.c + (i*32 + 28), 4); + } if (e.e[i].attributes & FA_VOLUMEID) continue; + if (e.e[i].name[0] == 0 or e.e[i].name[0] == 0xE5) continue; //Nothing intresting here. String name; - for (int j = 0; j < 8; j++) { - if (e.e[i].name[j] == ' ') break; - name += WChar(e.e[i].name[j]); - } - for (int j = 0; j < 3; j++) { - if (e.e[i].extension[j] == ' ') break; - if (j == 0) name += "."; - name += WChar(e.e[i].extension[j]); + if (lfnBuffer.empty()) { + for (int j = 0; j < 8; j++) { + if (e.e[i].name[j] == ' ') break; + name += WChar(e.e[i].name[j]); + } + for (int j = 0; j < 3; j++) { + if (e.e[i].extension[j] == ' ') break; + if (j == 0) name += "."; + name += WChar(e.e[i].extension[j]); + } + } else { + name = lfnBuffer.toString(UE_UTF16_LE); + lfnBuffer.clear(); } u32int first_clus = (e.e[i].first_clust_high << 16) + e.e[i].first_clust_low; FSNode* n; diff --git a/Source/Library/Common/ByteArray.class.cpp b/Source/Library/Common/ByteArray.class.cpp index 2a42702..95326f7 100644 --- a/Source/Library/Common/ByteArray.class.cpp +++ b/Source/Library/Common/ByteArray.class.cpp @@ -50,9 +50,9 @@ void ByteArray::resize(u32int size) { } String ByteArray::toString (u8int encoding) { - char* c = new char[m_length + 1]; + char* c = new char[m_length + 4]; memcpy((u8int*)c, m_string, m_length); - c[m_length] = 0; //Add NULL terminator + for (int i = 0; i < 4; i++) c[m_length + i] = 0; //Add NULL terminator String r(c, encoding); delete c; return r; diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp index 63ff837..a824eac 100644 --- a/Source/Library/Common/String.class.cpp +++ b/Source/Library/Common/String.class.cpp @@ -84,8 +84,8 @@ void String::affect (const char* string, u8int encoding) { return; } m_string = new WChar[m_length + 1]; - int i = 0, l = strlen(string), c = 0; - while (i < l) { + u32int i = 0, c = 0; + while (c < m_length) { i += m_string[c].affect(string + i, encoding); c++; } diff --git a/Source/Library/Common/WChar.class.cpp b/Source/Library/Common/WChar.class.cpp index f5bd5bc..312a5db 100644 --- a/Source/Library/Common/WChar.class.cpp +++ b/Source/Library/Common/WChar.class.cpp @@ -29,8 +29,10 @@ WChar::WChar(char 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); + if (encoding == UE_UTF16_LE) affectUtf16le(c); + if (encoding == UE_UTF16_BE) affectUtf16be(c); + if (encoding == UE_UTF32_LE) affectUtf32le(c); + if (encoding == UE_UTF32_BE) affectUtf32be(c); } u32int WChar::ucharLen(const char* c, u8int encoding) { @@ -40,18 +42,21 @@ u32int WChar::ucharLen(const char* c, u8int encoding) { else if ((c[0] & 0xF0) == 0xE0) return 3; else if ((c[0] & 0xF8) == 0xF0) return 4; else return 1; - } else if (encoding == UE_UTF16) { + } else if (encoding == UE_UTF16_BE) { if ((c[0] & 0xFC) == 0xD8 and (c[2] & 0xFC) == 0xDC) return 4; else return 2; - } else if (encoding == UE_UTF32) { + } else if (encoding == UE_UTF16_LE) { + if ((c[1] & 0xFC) == 0xD8 and (c[3] & 0xFC) == 0xDC) return 4; + else return 2; + } else if (encoding == UE_UTF32_LE or encoding == UE_UTF16_BE) { return 4; } return 1; } u32int WChar::utfLen(const char* c, u8int encoding) { - int i = 0, l = strlen(c), co = 0; - while (i < l) { + int i = 0, co = 0; + while (WChar(c + i, encoding) != 0) { i += ucharLen(c + i, encoding); co++; } @@ -90,7 +95,7 @@ u32int WChar::affectUtf8(const char* c) { //Returns the number of bytes for the return 1; } -u32int WChar::affectUtf16(const char* c) { +u32int WChar::affectUtf16be(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); @@ -108,13 +113,38 @@ u32int WChar::affectUtf16(const char* c) { } } -u32int WChar::affectUtf32(const char* c) { +u32int WChar::affectUtf16le(const char* c) { + if ((c[1] & 0xFC) == 0xD8 and // 11111100b, 11011000b + (c[3] & 0xFC) == 0xDC) { // 11111100b, 11011100b + u32int w = ((c[1] & 0x03) << 2) | ((c[0] & 0xC0) >> 6); + u32int x = (c[0] & 0x3F); + u32int y = ((c[3] & 0x03) << 8) | (c[3]); + 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[1] << 8) | (c[0]); + if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed + if (value >= 0xFFFE and value <= 0xFFFF) value = 0; + return 2; + } +} + +u32int WChar::affectUtf32be(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; } +u32int WChar::affectUtf32le(const char* c) { + value = (c[3] << 24) | (c[2] << 16) | (c[1] << 8) | c[0]; + 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++) { @@ -144,9 +174,9 @@ uchar_repr_t WChar::toUtf8() { return r; } -//TODO : code WChar::toUtf16 +//TODO : code WChar::toUtf16(be|le) -uchar_repr_t WChar::toUtf32() { +uchar_repr_t WChar::toUtf32be() { uchar_repr_t r; r.c[0] = (value >> 24) & 0xFF; r.c[1] = (value >> 16) & 0xFF; @@ -154,3 +184,12 @@ uchar_repr_t WChar::toUtf32() { r.c[3] = value & 0xFF; return r; } + +uchar_repr_t WChar::toUtf32le() { + uchar_repr_t r; + r.c[3] = (value >> 24) & 0xFF; + r.c[2] = (value >> 16) & 0xFF; + r.c[1] = (value >> 8) & 0xFF; + r.c[0] = value & 0xFF; + return r; +} diff --git a/Source/Library/Common/WChar.class.h b/Source/Library/Common/WChar.class.h index 5d6d26b..afaeb44 100644 --- a/Source/Library/Common/WChar.class.h +++ b/Source/Library/Common/WChar.class.h @@ -9,8 +9,10 @@ enum { UE_UTF8, - UE_UTF16, - UE_UTF32, + UE_UTF16_LE, + UE_UTF16_BE, + UE_UTF32_LE, + UE_UTF32_BE, }; union uchar_repr_t { @@ -31,13 +33,17 @@ struct WChar { void affectAscii(char c); u32int affectUtf8(const char* c); - u32int affectUtf16(const char* c); - u32int affectUtf32(const char* c); + u32int affectUtf16le(const char* c); + u32int affectUtf16be(const char* c); + u32int affectUtf32le(const char* c); + u32int affectUtf32be(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); + if (encoding == UE_UTF16_LE) return affectUtf16le(c); + if (encoding == UE_UTF16_BE) return affectUtf16be(c); + if (encoding == UE_UTF32_LE) return affectUtf32le(c); + if (encoding == UE_UTF32_BE) return affectUtf32be(c); affectAscii(c[0]); //Default case :/ return 1; } @@ -45,13 +51,17 @@ struct WChar { u8int toAscii(); uchar_repr_t toUtf8(); - uchar_repr_t toUtf16(); - uchar_repr_t toUtf32(); + uchar_repr_t toUtf16le(); + uchar_repr_t toUtf16be(); + uchar_repr_t toUtf32le(); + uchar_repr_t toUtf32be(); 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(); + //if (encoding == UE_UTF16_LE) return toUtf16le(); + //if (encoding == UE_UTF16_BE) return toUtf16be(); + if (encoding == UE_UTF32_LE) return toUtf32le(); + if (encoding == UE_UTF32_BE) return toUtf32be(); uchar_repr_t x; x.c[0] = toAscii(); return x; -- cgit v1.2.3 From f3ffe96d679742af95afa29e0cf612c6935eedd0 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Tue, 24 Nov 2009 14:29:29 +0100 Subject: Reading from floppys supposedly fixed in qemu --- Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp | 19 ++++++------------- Source/Kernel/Linker/ElfBinary.class.cpp | 2 +- Source/Kernel/Linker/MelonBinary.class.cpp | 2 +- Source/Kernel/Shell/KernelShell-sys.class.cpp | 19 +++++++++++++++++++ Source/Kernel/Shell/KernelShell.class.cpp | 1 + Source/Kernel/Shell/KernelShell.class.h | 1 + 6 files changed, 29 insertions(+), 15 deletions(-) (limited to 'Source') diff --git a/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp b/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp index 7edf24a..9335cb7 100644 --- a/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp +++ b/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp @@ -2,6 +2,7 @@ #include "FloppyController.class.h" #include #include +#include #include using namespace Sys; @@ -145,7 +146,7 @@ bool FloppyDrive::seek(u32int cyli, s32int head) { int st0, cyl = -1; - for (u32int i = 0; i < 10; i++) { + for (u32int i = 0; i < 5; i++) { asm volatile ("cli"); m_fdc->writeCmd(FC_SEEK); m_fdc->writeCmd(head << 2); @@ -158,12 +159,7 @@ bool FloppyDrive::seek(u32int cyli, s32int head) { if (st0 & 0xC0) { //Error continue; } - if (cyl == 0xFF or cyl == 0x00) { //0xFF for bochs, 0x00 for qemu :D - setMotorState(false); - m_fdc->setNoActiveDrive(); - return true; - } - if (cyl == (int)cyli) { + if (cyl == 0xFF or cyl == 0x00 or cyl == 0x01 or cyl == (int)cyli) { //0xFF for bochs, 0x00 for qemu :D setMotorState(false); m_fdc->setNoActiveDrive(); return true; @@ -296,16 +292,13 @@ bool FloppyDrive::readBlocks(u64int start, u32int count, u8int *data) { u32int startblock = start; if (count == 1) { u32int cylinder = (startblock / (m_sectors * 2)), offset = (startblock % (m_sectors * 2)) * 512; - if (m_buffCyl == cylinder && m_buffTime >= Time::uptime() - 4) { - memcpy(data, (const u8int*)(&m_buffer[offset]), 512); - return true; - } else { + if (m_buffCyl != cylinder or m_buffTime < Time::uptime() - 4) { if (!doTrack(cylinder, FD_READ)) return false; m_buffCyl = cylinder; m_buffTime = Time::uptime(); - memcpy(data, (const u8int*)(&m_buffer[offset]), 512); - return true; } + memcpy(data, (const u8int*)(&m_buffer[offset]), 512); + return true; } else { m_buffCyl = 0xFFFF; //Invalid cylinder m_buffTime = 0; diff --git a/Source/Kernel/Linker/ElfBinary.class.cpp b/Source/Kernel/Linker/ElfBinary.class.cpp index 27e5474..0518c38 100644 --- a/Source/Kernel/Linker/ElfBinary.class.cpp +++ b/Source/Kernel/Linker/ElfBinary.class.cpp @@ -9,7 +9,7 @@ ElfBinary::~ElfBinary() { Binary* ElfBinary::load(File& file) { elf_ehdr_t hdr; - file.read (&hdr); + if (!file.read (&hdr)) return 0; //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; diff --git a/Source/Kernel/Linker/MelonBinary.class.cpp b/Source/Kernel/Linker/MelonBinary.class.cpp index 0737b71..8a85977 100644 --- a/Source/Kernel/Linker/MelonBinary.class.cpp +++ b/Source/Kernel/Linker/MelonBinary.class.cpp @@ -2,7 +2,7 @@ Binary* MelonBinary::load(File& file) { u32int magic; - file.read(&magic); + if (!file.read(&magic)) return 0; if (magic == 0xFEEDBEEF) { MelonBinary* r = new MelonBinary; file.read(&r->m_size); diff --git a/Source/Kernel/Shell/KernelShell-sys.class.cpp b/Source/Kernel/Shell/KernelShell-sys.class.cpp index 6243b0f..b039c4d 100644 --- a/Source/Kernel/Shell/KernelShell-sys.class.cpp +++ b/Source/Kernel/Shell/KernelShell-sys.class.cpp @@ -58,3 +58,22 @@ void KernelShell::part(Vector& args) { } } } + +void KernelShell::readblock(Vector& args) { + if (args.size() == 3) { + Vector devcs = Dev::findDevices("block"); + u32int id = args[1].toInt(), block = args[2].toInt(); + if (id < devcs.size()) { + BlockDevice* bdev = (BlockDevice*)devcs[id]; + *m_vt << "Block " << block << " from device " << bdev->getName() << " (" << bdev->getClass() << ")\n"; + u8int* buff = (u8int*)Mem::alloc(bdev->blockSize()); + bdev->readBlocks(block, 1, buff); + m_vt->hexDump(buff, 32); + Mem::free(buff); + } else { + *m_vt << "Block device #" << id << " does not exist.\n"; + } + } else { + *m_vt << "Usage: readblock \n"; + } +} diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index 7f57f8b..9f9858b 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -61,6 +61,7 @@ u32int KernelShell::run() { {"free", &KernelShell::free}, {"uptime", &KernelShell::uptime}, {"part", &KernelShell::part}, + {"readblock", &KernelShell::readblock}, {0, 0} }; diff --git a/Source/Kernel/Shell/KernelShell.class.h b/Source/Kernel/Shell/KernelShell.class.h index e7549c2..4fa9c66 100644 --- a/Source/Kernel/Shell/KernelShell.class.h +++ b/Source/Kernel/Shell/KernelShell.class.h @@ -34,6 +34,7 @@ class KernelShell { void free(Vector& args); void uptime(Vector& args); void part(Vector& args); + void readblock(Vector& args); void setup(DirectoryNode* cwd, VirtualTerminal *vt); -- cgit v1.2.3 From f367fe4e5a7712bafc121ce5c228f15e90fc5c93 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Wed, 25 Nov 2009 17:07:31 +0100 Subject: Fixed FATFS::read - Also added a HDD image, will be used later - Also modified a bit the fdc driver - Also added a hexdump function to kernel shell for dumping file contents --- .../Devices/Floppy/FloppyController.class.cpp | 14 ++++++++--- .../Kernel/Devices/Floppy/FloppyController.class.h | 6 +++++ Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp | 28 +++++++++++----------- Source/Kernel/FileSystems/FAT/FATFS.class.cpp | 4 ++-- Source/Kernel/Shell/KernelShell-fs.class.cpp | 18 ++++++++++++++ Source/Kernel/Shell/KernelShell.class.cpp | 1 + Source/Kernel/Shell/KernelShell.class.h | 1 + 7 files changed, 53 insertions(+), 19 deletions(-) (limited to 'Source') diff --git a/Source/Kernel/Devices/Floppy/FloppyController.class.cpp b/Source/Kernel/Devices/Floppy/FloppyController.class.cpp index 146ce28..db148d0 100644 --- a/Source/Kernel/Devices/Floppy/FloppyController.class.cpp +++ b/Source/Kernel/Devices/Floppy/FloppyController.class.cpp @@ -96,6 +96,7 @@ FloppyController::FloppyController(u32int base, u8int irq) : m_driveMutex(false) m_drives[0] = NULL; m_drives[1] = NULL; m_first = false; + Dev::requestIRQ(this, m_irq); } void FloppyController::detect() { //TODO : do this better @@ -144,15 +145,14 @@ void FloppyController::setDOR() { dor |= 0x10; if (m_drives[1] != NULL and m_drives[1]->m_motorState != 0) dor |= 0x20; - asm volatile ("cli"); + resetIrq(); outb(m_base + FR_DOR, dor); if (m_first) { //First time we set the DOR, controller initialized - Task::currThread()->waitIRQ(m_irq); + waitIrq(); int st0, cyl; checkInterrupt(&st0, &cyl); m_first = false; } - asm volatile ("sti"); //PANIC("test"); } @@ -203,3 +203,11 @@ bool FloppyController::reset() { } return true; } + +void FloppyController::handleIRQ(registers_t regs, int irq) { + m_irqHappened = true; +} + +void FloppyController::waitIrq() { + while (!m_irqHappened) Task::currThread()->sleep(10); +} diff --git a/Source/Kernel/Devices/Floppy/FloppyController.class.h b/Source/Kernel/Devices/Floppy/FloppyController.class.h index a27d853..f0a7c10 100644 --- a/Source/Kernel/Devices/Floppy/FloppyController.class.h +++ b/Source/Kernel/Devices/Floppy/FloppyController.class.h @@ -60,6 +60,8 @@ class FloppyController : public Device { bool m_first; + bool m_irqHappened; + FloppyDrive* m_drives[2]; void checkInterrupt(int *st0, int *cyl); @@ -69,6 +71,10 @@ class FloppyController : public Device { bool writeCmd(u8int cmd); //Sends command to controller u8int readData(); //Reads a byte from controller bool reset(); + + void handleIRQ(registers_t regs, int irq); + void resetIrq() { m_irqHappened = false; } + void waitIrq(); public: static void detect(); diff --git a/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp b/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp index 9335cb7..23d007c 100644 --- a/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp +++ b/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp @@ -95,13 +95,12 @@ bool FloppyDrive::calibrate() { if (!setMotorState(true)) return false; for (int i = 0; i < 10; i++) { - asm volatile("cli"); + m_fdc->resetIrq(); m_fdc->writeCmd(FC_RECALIBRATE); m_fdc->writeCmd(m_driveNumber); - Task::currThread()->waitIRQ(m_fdc->m_irq); + m_fdc->waitIrq(); m_fdc->checkInterrupt(&st0, &cyl); - asm volatile("sti"); if (st0 & 0xC0) { continue; @@ -112,6 +111,7 @@ bool FloppyDrive::calibrate() { } } setMotorState(false); + *kvt << getName() << ": calibrate fail\n"; return false; } @@ -146,27 +146,29 @@ bool FloppyDrive::seek(u32int cyli, s32int head) { int st0, cyl = -1; - for (u32int i = 0; i < 5; i++) { - asm volatile ("cli"); + for (u32int i = 0; i < 10; i++) { + m_fdc->resetIrq(); m_fdc->writeCmd(FC_SEEK); m_fdc->writeCmd(head << 2); m_fdc->writeCmd(cyl); - Task::currThread()->waitIRQ(m_fdc->m_irq); + m_fdc->waitIrq(); m_fdc->checkInterrupt(&st0, &cyl); - asm volatile("sti"); if (st0 & 0xC0) { //Error + Task::currThread()->sleep(10); continue; } - if (cyl == 0xFF or cyl == 0x00 or cyl == 0x01 or cyl == (int)cyli) { //0xFF for bochs, 0x00 for qemu :D + if (cyl == 0xFF or cyl == 0x00 or cyl == (int)cyli) { //0xFF for bochs, 0x00 for qemu :D setMotorState(false); m_fdc->setNoActiveDrive(); return true; } + Task::currThread()->sleep(10); } setMotorState(false); m_fdc->setNoActiveDrive(); + *kvt << getName() << ": seek fail\n"; return false; } @@ -199,7 +201,7 @@ bool FloppyDrive::doTrack(u32int cyl, u8int dir) { Task::currThread()->sleep(100); - asm volatile("cli"); + m_fdc->resetIrq(); m_fdc->writeCmd(cmd); m_fdc->writeCmd(m_driveNumber); //Drive number & first head << 2 m_fdc->writeCmd(cyl); //Cylinder @@ -210,7 +212,7 @@ bool FloppyDrive::doTrack(u32int cyl, u8int dir) { m_fdc->writeCmd(0x1B); m_fdc->writeCmd(0xFF); - Task::currThread()->waitIRQ(m_fdc->m_irq); + m_fdc->waitIrq(); u8int st0, st1, st2, rcy, rhe, rse, bps; st0 = m_fdc->readData(); @@ -220,7 +222,6 @@ bool FloppyDrive::doTrack(u32int cyl, u8int dir) { rhe = m_fdc->readData(); rse = m_fdc->readData(); bps = m_fdc->readData(); - asm volatile("sti"); int error = 0; @@ -270,12 +271,11 @@ bool FloppyDrive::doTrack(u32int cyl, u8int dir) { bool FloppyDrive::readOnly() { m_fdc->setActiveDrive(m_driveNumber); - asm volatile("cli"); + m_fdc->resetIrq(); m_fdc->writeCmd(FC_SENSE_DRIVE_STATUS); m_fdc->writeCmd(m_driveNumber); - Task::currThread()->waitIRQ(m_fdc->m_irq); + m_fdc->waitIrq(); u8int st3 = m_fdc->readData(); - asm volatile("sti"); bool ret = (st3 & 0x80 ? true : false); diff --git a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp index 67b4013..4c662de 100644 --- a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp +++ b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp @@ -136,8 +136,8 @@ u32int FATFS::read(FileNode* file, u64int position, u32int max_length, u8int *da //Read first cluster u8int* temp = (u8int*)Mem::alloc(m_clusterSize); readCluster(clust, temp); - memcpy(data, temp + clusterOffset, (m_clusterSize - clusterOffset)); - //Read next clusters + memcpy(data, temp + clusterOffset, (len > m_clusterSize - clusterOffset ? m_clusterSize - clusterOffset : len)); + //Read next cluster u32int pos = (m_clusterSize - clusterOffset); for (u32int i = 1; i < clusters; i++) { clust = nextCluster(clust); diff --git a/Source/Kernel/Shell/KernelShell-fs.class.cpp b/Source/Kernel/Shell/KernelShell-fs.class.cpp index fa2078d..c389d45 100644 --- a/Source/Kernel/Shell/KernelShell-fs.class.cpp +++ b/Source/Kernel/Shell/KernelShell-fs.class.cpp @@ -125,3 +125,21 @@ void KernelShell::run(Vector& args) { } } } + +void KernelShell::hexdump(Vector& args) { + if (args.size() == 1) { + *m_vt << "No file to hexdump.\n"; + } else { + for (u32int i = 1; i < args.size(); i++) { + File f(args[i], FM_READ, m_cwd); + if (f.valid()) { + u8int *buff = (u8int*)Mem::alloc(f.length()); + f.read(f.length(), buff); + m_vt->hexDump(buff, f.length()); + Mem::free(buff); + } else { + *m_vt << "Error reading from file " << args[i] << "\n"; + } + } + } +} diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index 9f9858b..f35b4dc 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -62,6 +62,7 @@ u32int KernelShell::run() { {"uptime", &KernelShell::uptime}, {"part", &KernelShell::part}, {"readblock", &KernelShell::readblock}, + {"hexdump", &KernelShell::hexdump}, {0, 0} }; diff --git a/Source/Kernel/Shell/KernelShell.class.h b/Source/Kernel/Shell/KernelShell.class.h index 4fa9c66..d3fd5e1 100644 --- a/Source/Kernel/Shell/KernelShell.class.h +++ b/Source/Kernel/Shell/KernelShell.class.h @@ -27,6 +27,7 @@ class KernelShell { void rm(Vector& args); void wf(Vector& args); void run(Vector& args); + void hexdump(Vector& args); //in KernelShell-sys void devices(Vector& args); -- cgit v1.2.3 From a40fe1166ab1db972a8ca0380d603c4d90eede62 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Wed, 25 Nov 2009 18:42:44 +0100 Subject: Re-organized file system stuff. --- Source/Applications/Demos/GOL.cpp | 5 ++- Source/Kernel/Core/Log.ns.cpp | 5 +++ Source/Kernel/Core/kmain.wtf.cpp | 58 +++++++++++++++++++++++++++-- Source/Kernel/UserManager/Usr.ns.cpp | 26 +++++++------ Source/Kernel/VFS/File.class.cpp | 3 +- Source/Kernel/VFS/Part.ns.cpp | 27 ++++++++++++++ Source/Kernel/VFS/Part.ns.h | 3 ++ Source/Library/Common/BasicString.class.cpp | 1 + Source/Library/Common/BasicString.class.h | 2 +- Source/Library/Common/String.class.cpp | 1 + Source/Library/Common/String.class.h | 2 +- 11 files changed, 113 insertions(+), 20 deletions(-) (limited to 'Source') diff --git a/Source/Applications/Demos/GOL.cpp b/Source/Applications/Demos/GOL.cpp index 32eb30a..298c73a 100644 --- a/Source/Applications/Demos/GOL.cpp +++ b/Source/Applications/Demos/GOL.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include int main(Vector args) { @@ -22,7 +23,7 @@ int main(Vector args) { } } - char *tmp = new char[w * h + 1]; + ByteArray tmp((w + 1) * (h + 1)); bool run = true; while (run) { @@ -37,7 +38,7 @@ int main(Vector args) { } } outvt.moveCursor(0, 0); - outvt << String(tmp, w*h) << "Press Ctrl+h for help"; + outvt << tmp.toString() << "Press Ctrl+h for help"; //Compute next generation for (int y = 0; y < h; y++) { diff --git a/Source/Kernel/Core/Log.ns.cpp b/Source/Kernel/Core/Log.ns.cpp index 1727024..c8ccd80 100644 --- a/Source/Kernel/Core/Log.ns.cpp +++ b/Source/Kernel/Core/Log.ns.cpp @@ -1,4 +1,5 @@ #include "Log.ns.h" +#include #include namespace Log { @@ -11,6 +12,10 @@ void init(u8int loglevel) { if (VFS::find("/System/Logs") == 0) VFS::createDirectory("/System/Logs"); logs[KL_PANIC] = new TextFile("/System/Logs/Panic.log", FM_APPEND); + if (!logs[KL_PANIC]->valid()) { //FS maybee not read/write, mount a ramfs + RamFS::mount(1024*1024, (DirectoryNode*)VFS::find("/System/Logs")); + logs[KL_PANIC] = new TextFile("/System/Logs/Panic.log", FM_APPEND); + } if (KL_CRITICAL <= loglevel) logs[KL_CRITICAL] = new TextFile("/System/Logs/Critical.log", FM_APPEND); if (KL_ERROR <= loglevel) logs[KL_ERROR] = new TextFile("/System/Logs/Error.log", FM_APPEND); if (KL_WARNING <= loglevel) logs[KL_WARNING] = new TextFile("/System/Logs/Warning.log", FM_APPEND); diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index bb77eeb..1d438ed 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -115,6 +115,43 @@ void selectVideoMode(SimpleVT& v) { } } +bool mountFS(multiboot_info_t* mbd, String str) { + module_t *mods = (module_t*)mbd->mods_addr; + Vector fs = str.split(":"); + DirectoryNode* root; + if (fs[0] == "/") { + root = NULL; + } else { + FSNode* n = VFS::find(fs[0]); + if (n == NULL) { + *kvt << "Mountpoint does not exist : " << fs[0] << "\n"; + return false; + } + if (n->type() != NT_DIRECTORY) { + *kvt << "Mountpoint is not a directory : " << fs[0] << "\n"; + return false; + } + root = (DirectoryNode*)n; + } + if (fs[1] == "ramfs") { + if (fs[2].toInt() >= mbd->mods_count) { + *kvt << "Invalid module number for filesystem to mount on " << fs[0] << "\n"; + return false; + } + RamFS::mount((u8int*)mods[fs[2].toInt()].mod_start, 1024 * 1024, root); + } else { + if (fs.size() < 5) fs.push("fat"); + BlockDevice* d = Part::dev(fs[1], fs[2].toInt()); + Partition* p = Part::part(d, fs[3].toInt()); + if (fs[4] == "fat") { + FATFS::mount(p, root); + } else { + PANIC("Unknown filesystem type for root file system."); + } + } + return true; +} + void kmain(multiboot_info_t* mbd, u32int magic) { DEBUG("Entering kmain."); @@ -167,13 +204,17 @@ void kmain(multiboot_info_t* mbd, u32int magic) { //*************************************** PARSE COMMAND LINE Vector opts = kcmdline.split(" "); - String keymap = "fr", init = "/System/Applications/PaperWork.app"; + String keymap = "builtin", init = "/System/Applications/PaperWork.app"; + String root = "ramfs:0"; + Vector mount; bool enableVESA = true; for (u32int i = 0; i < opts.size(); i++) { Vector opt = opts[i].split(":"); if (opt[0] == "vesa" && opt[1] != "enabled") enableVESA = false; if (opt[0] == "keymap") keymap = opt[1]; if (opt[0] == "init") init = opt[1]; + if (opt[0] == "root") root = opts[i].substr(5); + if (opt[0] == "mount") mount.push(opts[i].substr(6)); } //*************************************** DEVICE SETUP @@ -183,14 +224,23 @@ void kmain(multiboot_info_t* mbd, u32int magic) { if (enableVESA) Dev::registerDevice(new VESADisplay()); FloppyController::detect(); - //*************************************** MOUNT ROOT FILESYSTEM + //*************************************** MOUNT FILESYSTEMS - RamFS::mount((u8int*)mods[0].mod_start, 1024 * 1024, NULL); + { // mount root filesystem + if (!mountFS(mbd, String("/:") += root)) PANIC("Cannot mount root filesystem."); + } DirectoryNode* cwd; cwd = VFS::getRootNode(); Task::currProcess()->setCwd(cwd); - FATFS::mount(Part::partitions[0], (DirectoryNode*)VFS::createDirectory("/Mount")); + // mount other filesystems + for (u32int i = 0; i < mount.size(); i++) { + mountFS(mbd, mount[i]); + } + + //FATFS::mount(Part::partitions[0], (DirectoryNode*)VFS::createDirectory("/Mount")); + + //*************************************** LOAD SYSTEM STUFF if (keymap != "builtin") { if (!Kbd::loadKeymap(keymap)) *kvt << "\nWARNING : Could not load keymap " << keymap << ", using built-in keymap instead."; diff --git a/Source/Kernel/UserManager/Usr.ns.cpp b/Source/Kernel/UserManager/Usr.ns.cpp index ecf9bae..66e159e 100644 --- a/Source/Kernel/UserManager/Usr.ns.cpp +++ b/Source/Kernel/UserManager/Usr.ns.cpp @@ -26,11 +26,13 @@ void load() { if (VFS::find("/System/Configuration/Groups")) VFS::find("/System/Configuration/Groups")->setPermissions(0600); if (VFS::find("/System/Configuration/Users")) VFS::find("/System/Configuration/Users")->setPermissions(0600); TextFile groups("/System/Configuration/Groups", FM_READ); - while (!groups.eof()) { - String s = groups.readLine(); - Vector data = s.split(":"); - if (data.size() == 2 and !(s[0] == WChar("#"))) { - m_groups = m_groups->cons(Group(data[1], data[0].toInt())); + if (groups.valid()) { + while (!groups.eof()) { + String s = groups.readLine(); + Vector data = s.split(":"); + if (data.size() == 2 and !(s[0] == WChar("#"))) { + m_groups = m_groups->cons(Group(data[1], data[0].toInt())); + } } } if (m_groups == 0) { @@ -39,12 +41,14 @@ void load() { } TextFile users("/System/Configuration/Users", FM_READ); - while (!users.eof()) { - String s = users.readLine(); - if (s == "" or s[0] == WChar("#")) continue; - Vector data = s.split(":"); - if (data.size() == 6) { - m_users = m_users->cons(User(data[1], data[4], data[5], group(data[2].toInt()), data[3], data[0].toInt())); + if (users.valid()) { + while (!users.eof()) { + String s = users.readLine(); + if (s == "" or s[0] == WChar("#")) continue; + Vector data = s.split(":"); + if (data.size() == 6) { + m_users = m_users->cons(User(data[1], data[4], data[5], group(data[2].toInt()), data[3], data[0].toInt())); + } } } if (m_users == 0) { diff --git a/Source/Kernel/VFS/File.class.cpp b/Source/Kernel/VFS/File.class.cpp index c5ddcd6..84561a5 100644 --- a/Source/Kernel/VFS/File.class.cpp +++ b/Source/Kernel/VFS/File.class.cpp @@ -33,7 +33,7 @@ bool File::open(String filename, u8int mode, FSNode* start, bool vrfyperm) { if (node == NULL){ if (mode == FM_READ) return false; node = VFS::createFile(filename, start, vrfyperm); - if (node == 0) return false; + if (node == NULL) return false; } if (node->type() != NT_FILE) return false; @@ -137,6 +137,7 @@ bool File::seek(u64int count, u8int mode) { } bool File::eof() { + if (!m_valid) return false; return m_position == m_file->getLength(); } diff --git a/Source/Kernel/VFS/Part.ns.cpp b/Source/Kernel/VFS/Part.ns.cpp index 6408dbd..7184f90 100644 --- a/Source/Kernel/VFS/Part.ns.cpp +++ b/Source/Kernel/VFS/Part.ns.cpp @@ -56,4 +56,31 @@ u32int getDeviceID(BlockDevice* dev) { return (u32int) - 1; } +BlockDevice* dev(String _class, u32int idx) { + for (u32int i = 0; i < devices.size(); i++) { + String devclass = devices[i]->getClass(); + if (devclass == _class or (devclass.size() > _class.size() and devclass.substr(0, _class.size()) == _class)) { + if (idx == 0) { + return devices[i]; + } else { + idx--; + } + } + } + return NULL; +} + +Partition* part(BlockDevice* dev, u32int idx) { + for (u32int i = 0; i < partitions.size(); i++) { + if (partitions[i]->getDevice() == dev) { + if (idx == 0) { + return partitions[i]; + } else { + idx--; + } + } + } + return NULL; +} + } diff --git a/Source/Kernel/VFS/Part.ns.h b/Source/Kernel/VFS/Part.ns.h index 40a0fb2..4373a2d 100644 --- a/Source/Kernel/VFS/Part.ns.h +++ b/Source/Kernel/VFS/Part.ns.h @@ -13,6 +13,9 @@ namespace Part { void unregisterDevice(BlockDevice* dev); u32int getDeviceID(BlockDevice* dev); + + BlockDevice* dev(String _class, u32int idx); + Partition* part(BlockDevice* dev, u32int idx); } #endif diff --git a/Source/Library/Common/BasicString.class.cpp b/Source/Library/Common/BasicString.class.cpp index f3a6164..58fa926 100644 --- a/Source/Library/Common/BasicString.class.cpp +++ b/Source/Library/Common/BasicString.class.cpp @@ -175,6 +175,7 @@ Vector< BasicString > BasicString::split(T sep) const { template BasicString BasicString::substr(s32int start, u32int size) { if (start < 0) start = m_length - start; + if (size == 0) size = m_length - start; BasicString ret; ret.m_string = new T[size + 1]; ret.m_length = size; diff --git a/Source/Library/Common/BasicString.class.h b/Source/Library/Common/BasicString.class.h index 21041e8..be74cf3 100644 --- a/Source/Library/Common/BasicString.class.h +++ b/Source/Library/Common/BasicString.class.h @@ -46,7 +46,7 @@ class BasicString { bool contains(const T& chr) const; Vector< BasicString > split(T sep) const; - BasicString substr(s32int start, u32int size); + BasicString substr(s32int start, u32int size = 0); }; #include "BasicString.class.cpp" diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp index a824eac..da2b93e 100644 --- a/Source/Library/Common/String.class.cpp +++ b/Source/Library/Common/String.class.cpp @@ -193,6 +193,7 @@ Vector String::split(WChar c) const { String String::substr(s32int start, u32int size) { if (start < 0) start = m_length - start; + if (size == 0) size = m_length - start; String ret; ret.m_string = new WChar[size + 1]; ret.m_length = size; diff --git a/Source/Library/Common/String.class.h b/Source/Library/Common/String.class.h index 0d48ce6..473624b 100644 --- a/Source/Library/Common/String.class.h +++ b/Source/Library/Common/String.class.h @@ -43,7 +43,7 @@ class String : public BasicString { Vector split(WChar c) const; - String substr(s32int start, u32int size); + String substr(s32int start, u32int size = 0); }; #endif -- cgit v1.2.3 From 56ace5efd6ccc02004ddafb1e564a3f9d5d538d2 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Fri, 27 Nov 2009 20:43:25 +0100 Subject: Added some screenshots, re-organized some stuff. --- Source/Applications/PaperWork/main.cpp | 7 +- Source/Kernel/Core/kmain.wtf.cpp | 43 +------------ Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp | 2 - Source/Kernel/FileSystems/FAT/FATFS.class.cpp | 26 +++++--- Source/Kernel/FileSystems/FAT/FATFS.class.h | 6 +- Source/Kernel/FileSystems/RamFS/RamFS.class.h | 2 + Source/Kernel/Shell/KernelShell-sys.class.cpp | 22 +++++++ Source/Kernel/Shell/KernelShell.class.cpp | 32 ++------- Source/Kernel/Shell/KernelShell.class.h | 1 + Source/Kernel/VFS/DirectoryNode.class.cpp | 2 +- Source/Kernel/VFS/FileSystem.proto.h | 2 + Source/Kernel/VFS/Part.ns.cpp | 5 ++ Source/Kernel/VFS/Part.ns.h | 2 + Source/Kernel/VFS/VFS.ns.cpp | 75 ++++++++++++++++++++++ Source/Kernel/VFS/VFS.ns.h | 6 +- 15 files changed, 150 insertions(+), 83 deletions(-) (limited to 'Source') diff --git a/Source/Applications/PaperWork/main.cpp b/Source/Applications/PaperWork/main.cpp index 1a4c1c7..2fb40df 100644 --- a/Source/Applications/PaperWork/main.cpp +++ b/Source/Applications/PaperWork/main.cpp @@ -1,6 +1,8 @@ #include #include +#define DEFAULT_SHELL "/Applications/Shell/Shell.app" + int main(Vector args) { String act = "init"; if (args.size() == 2) { @@ -36,7 +38,10 @@ int main(Vector args) { outvt << "Authentication failed.\n\n"; continue; } - Process p = Process::run("/Applications/Shell/Shell.app"); + outvt << "What shell to run [" << DEFAULT_SHELL << "]? "; + String sh = invt.readLine(); + if (sh == "") sh = DEFAULT_SHELL; + Process p = Process::run(sh); if (p.valid()) { p.setInVT(invt); p.setOutVT(outvt); diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 1d438ed..827a834 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -115,43 +115,6 @@ void selectVideoMode(SimpleVT& v) { } } -bool mountFS(multiboot_info_t* mbd, String str) { - module_t *mods = (module_t*)mbd->mods_addr; - Vector fs = str.split(":"); - DirectoryNode* root; - if (fs[0] == "/") { - root = NULL; - } else { - FSNode* n = VFS::find(fs[0]); - if (n == NULL) { - *kvt << "Mountpoint does not exist : " << fs[0] << "\n"; - return false; - } - if (n->type() != NT_DIRECTORY) { - *kvt << "Mountpoint is not a directory : " << fs[0] << "\n"; - return false; - } - root = (DirectoryNode*)n; - } - if (fs[1] == "ramfs") { - if (fs[2].toInt() >= mbd->mods_count) { - *kvt << "Invalid module number for filesystem to mount on " << fs[0] << "\n"; - return false; - } - RamFS::mount((u8int*)mods[fs[2].toInt()].mod_start, 1024 * 1024, root); - } else { - if (fs.size() < 5) fs.push("fat"); - BlockDevice* d = Part::dev(fs[1], fs[2].toInt()); - Partition* p = Part::part(d, fs[3].toInt()); - if (fs[4] == "fat") { - FATFS::mount(p, root); - } else { - PANIC("Unknown filesystem type for root file system."); - } - } - return true; -} - void kmain(multiboot_info_t* mbd, u32int magic) { DEBUG("Entering kmain."); @@ -182,7 +145,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { //Create a VT for logging what kernel does kvt = new ScrollableVT(25, 80, 20, KVT_FGCOLOR, KVT_BGCOLOR); kvt->map(0, 0); - *kvt << "Melon is loading..."; + *kvt << "Melon is loading...\n"; IDT::init(); //Setup interrupts @@ -227,7 +190,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { //*************************************** MOUNT FILESYSTEMS { // mount root filesystem - if (!mountFS(mbd, String("/:") += root)) PANIC("Cannot mount root filesystem."); + if (!VFS::mount(String("/:") += root, kvt, mbd)) PANIC("Cannot mount root filesystem."); } DirectoryNode* cwd; cwd = VFS::getRootNode(); @@ -235,7 +198,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { // mount other filesystems for (u32int i = 0; i < mount.size(); i++) { - mountFS(mbd, mount[i]); + VFS::mount(mount[i], kvt, mbd); } //FATFS::mount(Part::partitions[0], (DirectoryNode*)VFS::createDirectory("/Mount")); diff --git a/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp b/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp index 23d007c..4036927 100644 --- a/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp +++ b/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp @@ -156,7 +156,6 @@ bool FloppyDrive::seek(u32int cyli, s32int head) { m_fdc->checkInterrupt(&st0, &cyl); if (st0 & 0xC0) { //Error - Task::currThread()->sleep(10); continue; } if (cyl == 0xFF or cyl == 0x00 or cyl == (int)cyli) { //0xFF for bochs, 0x00 for qemu :D @@ -164,7 +163,6 @@ bool FloppyDrive::seek(u32int cyli, s32int head) { m_fdc->setNoActiveDrive(); return true; } - Task::currThread()->sleep(10); } setMotorState(false); m_fdc->setNoActiveDrive(); diff --git a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp index 4c662de..e4cb40c 100644 --- a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp +++ b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp @@ -12,14 +12,15 @@ ((FATDirectoryNode*)(node))->m_firstDirEntryID : \ ((FATFileNode*)(node))->m_firstDirEntryID)) -FATFS* FATFS::mount(Partition* p, DirectoryNode* mountpoint) { +FileSystem* FATFS::mount(Partition* p, DirectoryNode* mountpoint, bool readwrite) { + if (readwrite) return 0; if (mountpoint != 0 and !mountpoint->mountpointable()) return 0; // *** READ BOOT SECTOR *** union { fat_BS_t s; u8int c[512]; } bs; - p->readBlocks(0, 1, bs.c); + if (!p->readBlocks(0, 1, bs.c)) return 0; // *** CHECK FILESYSTEM TYPE *** if (bs.s.extBS_16.boot_signature != 0x28 and bs.s.extBS_16.boot_signature != 0x29 and bs.s.extBS_32.boot_signature != 0x28 and bs.s.extBS_32.boot_signature != 0x29) return 0; @@ -46,14 +47,19 @@ FATFS* FATFS::mount(Partition* p, DirectoryNode* mountpoint) { fs->m_rootNode = new FATDirectoryNode("/", fs, mountpoint); FIRSTCLUS(fs->m_rootNode) = 2; if (fs->m_fatType == 32) FIRSTCLUS(fs->m_rootNode) = bs.s.extBS_32.root_cluster; + if (!fs->m_rootNode->loadContent()) { + *kvt << "Could not read FAT filesystem root directory.\n"; + delete fs; + return 0; + } if (mountpoint != 0) mountpoint->mount(fs->m_rootNode); VFS::registerFilesystem(fs); - *kvt << "\nDetected a FAT" << (s64int)fs->m_fatType << " filesystem.\n" << + *kvt << "Detected a FAT" << (s64int)fs->m_fatType << " filesystem.\n" << "root_dir_sectors:" << fs->m_rootDirSectors << " fat_size:" << fs->m_fatSize << " total_sectors:" << fs->m_totalSectors << " data_sectors:" << dataSectors << " count_of_clusters:" << fs->m_countOfClusters << " sizeof(fat_dir_entry_t):" << sizeof(fat_dir_entry_t) << " first_data_sector:" << fs->m_firstDataSector << - " cluster_size:" << fs->m_clusterSize; - return 0; + " cluster_size:" << fs->m_clusterSize << "\n"; + return fs; } u32int FATFS::nextCluster(u32int cluster) { @@ -87,10 +93,10 @@ u32int FATFS::nextCluster(u32int cluster) { return val; } -void FATFS::readCluster(u32int cluster, u8int* data) { +bool FATFS::readCluster(u32int cluster, u8int* data) { u32int firstSector = ((cluster - 2) * m_bs.sectors_per_cluster) + m_firstDataSector; if (cluster > 2 and m_fatType != 32) firstSector += m_rootDirSectors; - m_part->readBlocks(firstSector, m_bs.sectors_per_cluster, data); + return m_part->readBlocks(firstSector, m_bs.sectors_per_cluster, data); } bool FATFS::unmount() { @@ -170,14 +176,16 @@ bool FATFS::loadContents(DirectoryNode* dir) { u32int entries = m_clusterSize / sizeof(fat_dir_entry_t); if (cluster == 2 and m_fatType != 32) { //This is the value we use for the root directory e.c = (u8int*)Mem::alloc(m_rootDirSectors * m_part->getBlockSize()); - m_part->readBlocks(m_firstDataSector, m_rootDirSectors, e.c); + if (!m_part->readBlocks(m_firstDataSector, m_rootDirSectors, e.c)) return false; } else { e.c = (u8int*)Mem::alloc(m_clusterSize); } ByteArray lfnBuffer; while (cluster != 0) { - if (cluster != 2 or m_fatType == 32) readCluster(cluster, e.c); + if (cluster != 2 or m_fatType == 32) { + if (!readCluster(cluster, e.c)) return false; + } for (u32int i = 0; i < entries; i++) { if (e.e[i].attributes == FA_LFN && e.c[i*32] != 0xE5) { //Long file name entry u8int num = e.c[i*32] & 0x3; diff --git a/Source/Kernel/FileSystems/FAT/FATFS.class.h b/Source/Kernel/FileSystems/FAT/FATFS.class.h index 50ff479..251b2a8 100644 --- a/Source/Kernel/FileSystems/FAT/FATFS.class.h +++ b/Source/Kernel/FileSystems/FAT/FATFS.class.h @@ -103,13 +103,15 @@ class FATFS : public FileSystem { Partition* m_part; u32int nextCluster(u32int cluster); //Get the next cluster number in the chain (0 = EOF) - void readCluster(u32int cluster, u8int* data); //Read the content of a cluster to a buffer + bool readCluster(u32int cluster, u8int* data); //Read the content of a cluster to a buffer public: - static FATFS* mount(Partition* p, DirectoryNode* mountpoint); + static FileSystem* mount(Partition* p, DirectoryNode* mountpoint, bool readwrite = false); bool unmount(); + String getDevDescription() { return Part::partIdentifier(m_part); } + bool setName(FSNode* node, String name); bool setPermissions(FSNode* node, u32int permissions); bool setUid(FSNode* node, u32int uid); diff --git a/Source/Kernel/FileSystems/RamFS/RamFS.class.h b/Source/Kernel/FileSystems/RamFS/RamFS.class.h index 5ce85f1..042baa9 100644 --- a/Source/Kernel/FileSystems/RamFS/RamFS.class.h +++ b/Source/Kernel/FileSystems/RamFS/RamFS.class.h @@ -35,6 +35,8 @@ class RamFS : public FileSystem { bool setGid(FSNode* node, u32int gid); bool setParent(FSNode* node, FSNode* parent); + String getDevDescription() { return "ramfs"; } + 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); diff --git a/Source/Kernel/Shell/KernelShell-sys.class.cpp b/Source/Kernel/Shell/KernelShell-sys.class.cpp index b039c4d..06af11d 100644 --- a/Source/Kernel/Shell/KernelShell-sys.class.cpp +++ b/Source/Kernel/Shell/KernelShell-sys.class.cpp @@ -4,6 +4,8 @@ #include #include #include +#include +#include void KernelShell::devices(Vector& args) { Vector dev = Dev::findDevices(); @@ -59,6 +61,26 @@ void KernelShell::part(Vector& args) { } } +void KernelShell::mount(Vector& args) { + if (args.size() == 1) { + for (u32int i = 0; i < VFS::filesystems.size(); i++) { + *m_vt << VFS::filesystems[i]->getDevDescription() << " on " << VFS::path(VFS::filesystems[i]->getRootNode()) << "\n"; + } + } else if (args.size() == 2) { + if (args[1] == "help") { + *m_vt << "Usage: mount [help|]\n" << + "Options formats :\n" << + " - :ramfs\n" << + " - :[]::[:[:[ro|rw]]]\n" << + "You can have a list of available block devices and partitions by typing 'part'.\n"; + } else { + if (VFS::mount(args[1], m_vt)) *m_vt << "Ok, filesystem mounted.\n"; + } + } else { + *m_vt << "Usage: mount [ \n"; + } +} + void KernelShell::readblock(Vector& args) { if (args.size() == 3) { Vector devcs = Dev::findDevices("block"); diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index f35b4dc..71a717a 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -3,9 +3,8 @@ #include #include #include -#include -#include #include +#include u32int KernelShell::m_instances = 0; @@ -62,6 +61,7 @@ u32int KernelShell::run() { {"uptime", &KernelShell::uptime}, {"part", &KernelShell::part}, {"readblock", &KernelShell::readblock}, + {"mount", &KernelShell::mount}, {"hexdump", &KernelShell::hexdump}, {0, 0} @@ -84,6 +84,9 @@ u32int KernelShell::run() { *m_vt << " - free shows memory usage (frames and kheap)\n"; *m_vt << " - uptime shows seconds since boot\n"; *m_vt << " - part shows all detected block devs and partitions\n"; + *m_vt << " - mount shows mounted devices or mounts a ramfs\n"; + *m_vt << " - readblock reads a block from a block device and dumps it\n"; + *m_vt << " - hexdump shows a hexadecimal dump of a file\n"; *m_vt << " - Standard UNIX commands : ls cd cat pwd rm mkdir wf\n"; *m_vt << " - Scroll up with shift+pgup !\n"; } else if (tokens[0] == "reboot") { @@ -95,31 +98,6 @@ u32int KernelShell::run() { } else if (tokens[0] == "exit") { if (tokens.size() == 1) return 0; return tokens[1].toInt(); - } else if (tokens[0] == "mount") { - if (tokens.size() == 1) { - for (u32int i = 0; i < VFS::filesystems.size(); i++) { - *m_vt << VFS::path(VFS::filesystems[i]->getRootNode()) << "\n"; - } - } else if (tokens.size() == 3) { - if (tokens[1] == "ramfs") { - FSNode* n = VFS::find(tokens[2], m_cwd); - if (n == 0) { - *m_vt << "No such directory.\n"; - } else if (n->type() != NT_DIRECTORY) { - *m_vt << "Not a directory.\n"; - } else { - if (RamFS::mount(100000, (DirectoryNode*)n) != 0) { - *m_vt << "Ok...\n"; - } else { - *m_vt << "Error !\n"; - } - } - } else { - *m_vt << "Not supported yet.\n"; - } - } else { - *m_vt << "Usage: mount [ \n"; - } } else if (tokens[0] == "unmount") { if (tokens.size() == 2) { FSNode* n = VFS::find(tokens[1], m_cwd); diff --git a/Source/Kernel/Shell/KernelShell.class.h b/Source/Kernel/Shell/KernelShell.class.h index d3fd5e1..9655def 100644 --- a/Source/Kernel/Shell/KernelShell.class.h +++ b/Source/Kernel/Shell/KernelShell.class.h @@ -36,6 +36,7 @@ class KernelShell { void uptime(Vector& args); void part(Vector& args); void readblock(Vector& args); + void mount(Vector& args); void setup(DirectoryNode* cwd, VirtualTerminal *vt); diff --git a/Source/Kernel/VFS/DirectoryNode.class.cpp b/Source/Kernel/VFS/DirectoryNode.class.cpp index 7da6fe6..55365f0 100644 --- a/Source/Kernel/VFS/DirectoryNode.class.cpp +++ b/Source/Kernel/VFS/DirectoryNode.class.cpp @@ -12,7 +12,7 @@ DirectoryNode::~DirectoryNode() { delete m_children[i]; } } - if (m_name == "/") ((DirectoryNode*)(m_parent))->unmount(); + if (m_name == "/" && m_parent != NULL) ((DirectoryNode*)(m_parent))->unmount(); } u32int DirectoryNode::getIdxChildSC(u32int idx) { diff --git a/Source/Kernel/VFS/FileSystem.proto.h b/Source/Kernel/VFS/FileSystem.proto.h index 93b37f8..9216219 100644 --- a/Source/Kernel/VFS/FileSystem.proto.h +++ b/Source/Kernel/VFS/FileSystem.proto.h @@ -26,6 +26,8 @@ class FileSystem { bool isWritable() { return m_isWritable; } DirectoryNode* getRootNode() { return m_rootNode; } + virtual String getDevDescription() = 0; + //Must be implemented by the filesystem virtual bool setName(FSNode* node, String name) = 0; virtual bool setPermissions(FSNode* node, u32int permissions) = 0; diff --git a/Source/Kernel/VFS/Part.ns.cpp b/Source/Kernel/VFS/Part.ns.cpp index 7184f90..1bd6a8e 100644 --- a/Source/Kernel/VFS/Part.ns.cpp +++ b/Source/Kernel/VFS/Part.ns.cpp @@ -57,6 +57,7 @@ u32int getDeviceID(BlockDevice* dev) { } BlockDevice* dev(String _class, u32int idx) { + if (_class.empty()) _class = "block"; for (u32int i = 0; i < devices.size(); i++) { String devclass = devices[i]->getClass(); if (devclass == _class or (devclass.size() > _class.size() and devclass.substr(0, _class.size()) == _class)) { @@ -83,4 +84,8 @@ Partition* part(BlockDevice* dev, u32int idx) { return NULL; } +String partIdentifier(Partition* p) { + return String("d") += String::number(getDeviceID(p->getDevice())) += String("p") += String::number(p->getPartNumber()); +} + } diff --git a/Source/Kernel/VFS/Part.ns.h b/Source/Kernel/VFS/Part.ns.h index 4373a2d..992f6f3 100644 --- a/Source/Kernel/VFS/Part.ns.h +++ b/Source/Kernel/VFS/Part.ns.h @@ -16,6 +16,8 @@ namespace Part { BlockDevice* dev(String _class, u32int idx); Partition* part(BlockDevice* dev, u32int idx); + + String partIdentifier(Partition* p); //Simply to help recognize the partition } #endif diff --git a/Source/Kernel/VFS/VFS.ns.cpp b/Source/Kernel/VFS/VFS.ns.cpp index 5ebb697..6a5fe4e 100644 --- a/Source/Kernel/VFS/VFS.ns.cpp +++ b/Source/Kernel/VFS/VFS.ns.cpp @@ -1,6 +1,19 @@ #include "VFS.ns.h" #include #include +#include + +#include +#include +#include + +struct local_fs_t { + const char* name; + mount_callback_t cb; +} fileSystems[] = { + {"fat", FATFS::mount}, + {0, 0} +}; FileSystem::~FileSystem() { delete m_rootNode; } @@ -37,6 +50,68 @@ bool unmount(FileSystem* fs) { return true; } +bool mount(String str, VirtualTerminal* vt, multiboot_info_t *mbd) { + Vector fs = str.split(":"); + DirectoryNode* root; + if (fs[0] == "/") { + root = NULL; + } else { + FSNode* n = VFS::find(fs[0]); + if (n == NULL) { + *vt << "Mountpoint does not exist : " << fs[0] << "\n"; + return false; + } + if (n->type() != NT_DIRECTORY) { + *vt << "Mountpoint is not a directory : " << fs[0] << "\n"; + return false; + } + root = (DirectoryNode*)n; + } + if (fs[1] == "ramfs") { + if (fs.size() > 2) { + if (mbd != 0) { + module_t *mods = (module_t*)mbd->mods_addr; + if (fs[2].toInt() >= mbd->mods_count) { + *vt << "Invalid module number for filesystem to mount on " << fs[0] << "\n"; + return false; + } + RamFS::mount((u8int*)mods[fs[2].toInt()].mod_start, 1024 * 1024, root); + return true; + } else { + *vt << "Cannot mount kernel modules outside of kernel command line.\n"; + return false; + } + } else { + RamFS::mount(1024 * 1024, root); + return true; + } + } else { + if (fs.size() < 4) { + *vt << "Syntax: :[]::[:[:[ro|rw]]]\n"; + return false; + } + if (fs[1] == "") fs[1] = "block"; + if (fs.size() < 5) fs.push(""); + if (fs.size() < 6) fs.push("ro"); //By default, mount file systems read-only + BlockDevice* d = Part::dev(fs[1], fs[2].toInt()); + Partition* p = Part::part(d, fs[3].toInt()); + for (u32int i = 0; fileSystems[i].cb != 0; i++) { + if (fs[4] == fileSystems[i].name or fs[4] == "") { + if (fileSystems[i].cb(p, root, (fs[5] == "rw")) != NULL) { + return true; + } else if (fs[4] != "") { + *vt << "Could not mount filesystem on " << fs[0] << "\n"; + if (root == NULL) PANIC("Error while mounting root filesystem."); + return false; + } + } + } + *vt << "Unknown filesystem type for filesystem to mount on " << fs[0] << "\n"; + if (root == NULL) PANIC("Unknown filesystem type for root file system."); + return false; + } +} + FSNode* find(const String& path, FSNode* start) { if (start == 0) start = rootNode; diff --git a/Source/Kernel/VFS/VFS.ns.h b/Source/Kernel/VFS/VFS.ns.h index 21a1e77..eede728 100644 --- a/Source/Kernel/VFS/VFS.ns.h +++ b/Source/Kernel/VFS/VFS.ns.h @@ -1,11 +1,13 @@ #ifndef DEF_VFS_NS_H #define DEF_VFS_NS_H +#include + #include #include #include -typedef FileSystem* (* mount_callback_t)(Partition* partition); +typedef FileSystem* (* mount_callback_t)(Partition* partition, DirectoryNode* mountpoint, bool readwrite); namespace VFS { extern Vector filesystems; @@ -18,6 +20,8 @@ namespace VFS { void unregisterFilesystem(FileSystem* fs); bool unmount(FileSystem* fs); + bool mount(String str, VirtualTerminal* logvt, multiboot_info_t* mbd = 0); + FSNode* find(const String& path, FSNode* start = 0); FSNode* createFile(const String& path, FSNode* start = 0, bool vrfyperm = false); FSNode* createDirectory(const String& path, FSNode* start = 0, bool vrfyperm = false); -- cgit v1.2.3 From bcb8807209f4aa7da4d7fec54857599b60c87947 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Fri, 27 Nov 2009 22:17:21 +0100 Subject: Some bugfixes --- Source/Applications/Demos/GOL.cpp | 6 +++++- Source/Kernel/Core/kmain.wtf.cpp | 6 +++--- Source/Library/Common/BasicString.class.cpp | 5 +++-- Source/Library/Common/BasicString.class.h | 2 +- Source/Library/Common/String.class.cpp | 5 +++-- Source/Library/Common/String.class.h | 2 +- 6 files changed, 16 insertions(+), 10 deletions(-) (limited to 'Source') diff --git a/Source/Applications/Demos/GOL.cpp b/Source/Applications/Demos/GOL.cpp index 298c73a..e6da3a6 100644 --- a/Source/Applications/Demos/GOL.cpp +++ b/Source/Applications/Demos/GOL.cpp @@ -83,12 +83,16 @@ int main(Vector args) { u64int y = Rand::rand() * h / Rand::max(); cells[x * h + y] = true; } + } else if (kp.character == WChar("p")) { + outvt << " [PAUSED] press a key to resume"; + invt.getKeypress(); } else if (kp.character == WChar("h")) { outvt << "\n\n** Melon's demo Game Of Life Simulator help :\n"; outvt << " - ctrl+c : quit\n"; outvt << " - ctrl+h : show this\n"; + outvt << " - ctrl+p : pause\n"; outvt << " - ctrl+r : add some random cells\n"; - outvt << " - ctrl+R : add more cells, but not random\n\n"; + outvt << " - ctrl+R : add more cells, still random\n\n"; outvt << "Press any key to return to simultaor..."; invt.getKeypress(); } diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 827a834..a028457 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -86,7 +86,7 @@ u32int logoAnimation(void* p) { void selectVideoMode(SimpleVT& v) { Disp::getModes(); - v << "\n\nPlease select a graphic mode in the list below:\n"; + v << "\nPlease select a graphic mode in the list below:\n"; for (u32int i = 0; i < Disp::modes.size(); i++) { Disp::mode_t& m = Disp::modes[i]; @@ -206,7 +206,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { //*************************************** LOAD SYSTEM STUFF if (keymap != "builtin") { - if (!Kbd::loadKeymap(keymap)) *kvt << "\nWARNING : Could not load keymap " << keymap << ", using built-in keymap instead."; + if (!Kbd::loadKeymap(keymap)) *kvt << "WARNING : Could not load keymap " << keymap << ", using built-in keymap instead."; } Log::init(KL_STATUS); //Setup logging @@ -216,7 +216,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) { Log::log(KL_STATUS, "kmain : User list loaded"); if (init.empty()) { - *kvt << "\n\n"; + *kvt << "\n"; new KernelShell(cwd, kvt); while (KernelShell::getInstances() > 0) { Task::currThread()->sleep(100); diff --git a/Source/Library/Common/BasicString.class.cpp b/Source/Library/Common/BasicString.class.cpp index 58fa926..ddb4e2c 100644 --- a/Source/Library/Common/BasicString.class.cpp +++ b/Source/Library/Common/BasicString.class.cpp @@ -173,9 +173,10 @@ Vector< BasicString > BasicString::split(T sep) const { } template -BasicString BasicString::substr(s32int start, u32int size) { +BasicString BasicString::substr(s32int start, s32int size) { + if (size == 0) return BasicString(); if (start < 0) start = m_length - start; - if (size == 0) size = m_length - start; + if (size == -1) size = m_length - start; BasicString ret; ret.m_string = new T[size + 1]; ret.m_length = size; diff --git a/Source/Library/Common/BasicString.class.h b/Source/Library/Common/BasicString.class.h index be74cf3..03d82c1 100644 --- a/Source/Library/Common/BasicString.class.h +++ b/Source/Library/Common/BasicString.class.h @@ -46,7 +46,7 @@ class BasicString { bool contains(const T& chr) const; Vector< BasicString > split(T sep) const; - BasicString substr(s32int start, u32int size = 0); + BasicString substr(s32int start, s32int size = -1); }; #include "BasicString.class.cpp" diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp index da2b93e..fe851bd 100644 --- a/Source/Library/Common/String.class.cpp +++ b/Source/Library/Common/String.class.cpp @@ -191,9 +191,10 @@ Vector String::split(WChar c) const { return ret; } -String String::substr(s32int start, u32int size) { +String String::substr(s32int start, s32int size) { + if (size == 0) return String(); if (start < 0) start = m_length - start; - if (size == 0) size = m_length - start; + if (size == -1) size = m_length - start; String ret; ret.m_string = new WChar[size + 1]; ret.m_length = size; diff --git a/Source/Library/Common/String.class.h b/Source/Library/Common/String.class.h index 473624b..b623fb2 100644 --- a/Source/Library/Common/String.class.h +++ b/Source/Library/Common/String.class.h @@ -43,7 +43,7 @@ class String : public BasicString { Vector split(WChar c) const; - String substr(s32int start, u32int size = 0); + String substr(s32int start, s32int size = -1); }; #endif -- cgit v1.2.3 From 4d0939e2853ffd9d49b83524923351f9776866d7 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sat, 28 Nov 2009 12:36:01 +0100 Subject: Caching mechanism added and floppy driver fixed on qemu/vbox --- .../Devices/Floppy/FloppyController.class.cpp | 3 +- Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp | 27 ++++--- Source/Kernel/Devices/Floppy/FloppyDrive.class.h | 2 +- Source/Kernel/FileSystems/FAT/FATFS.class.cpp | 10 +-- Source/Kernel/FileSystems/FAT/FATFS.class.h | 8 +- Source/Kernel/VFS/BlockCache.class.cpp | 89 ++++++++++++++++++++++ Source/Kernel/VFS/BlockCache.class.h | 32 ++++++++ Source/Kernel/VFS/Part.ns.cpp | 2 +- Source/Kernel/VFS/Partition.class.cpp | 8 +- Source/Kernel/VFS/Partition.class.h | 2 + Source/Kernel/VFS/VFS.ns.cpp | 1 - 11 files changed, 157 insertions(+), 27 deletions(-) create mode 100644 Source/Kernel/VFS/BlockCache.class.cpp create mode 100644 Source/Kernel/VFS/BlockCache.class.h (limited to 'Source') diff --git a/Source/Kernel/Devices/Floppy/FloppyController.class.cpp b/Source/Kernel/Devices/Floppy/FloppyController.class.cpp index db148d0..7201c5c 100644 --- a/Source/Kernel/Devices/Floppy/FloppyController.class.cpp +++ b/Source/Kernel/Devices/Floppy/FloppyController.class.cpp @@ -153,7 +153,6 @@ void FloppyController::setDOR() { checkInterrupt(&st0, &cyl); m_first = false; } - //PANIC("test"); } void FloppyController::setActiveDrive(u8int drive) { @@ -190,10 +189,10 @@ u8int FloppyController::readData() { bool FloppyController::reset() { outb(m_base + FR_DOR, 0x00); //Disable controller m_first = true; - setNoActiveDrive(); if (m_drives[0] != NULL) m_drives[0]->m_motorState = 0; if (m_drives[1] != NULL) m_drives[1]->m_motorState = 0; + setNoActiveDrive(); for (int i = 0; i < 2; i++) { if (m_drives[i] != NULL) { diff --git a/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp b/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp index 4036927..b7fd69b 100644 --- a/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp +++ b/Source/Kernel/Devices/Floppy/FloppyDrive.class.cpp @@ -92,7 +92,10 @@ bool FloppyDrive::calibrate() { int st0, cyl = -1; - if (!setMotorState(true)) return false; + if (!setMotorState(true)) { + *kvt << getName() << ": calibrate fail\n"; + return false; + } for (int i = 0; i < 10; i++) { m_fdc->resetIrq(); @@ -138,18 +141,17 @@ bool FloppyDrive::killMotor() { return true; } -bool FloppyDrive::seek(u32int cyli, s32int head) { +bool FloppyDrive::seek(u32int cyli, s32int head, bool recursive) { if (cyli >= m_cylinders) return false; - m_fdc->setActiveDrive(m_driveNumber); setMotorState(true); //Turn on motor int st0, cyl = -1; - for (u32int i = 0; i < 10; i++) { + for (u32int i = 0; i < (recursive ? 10 : 5); i++) { m_fdc->resetIrq(); m_fdc->writeCmd(FC_SEEK); - m_fdc->writeCmd(head << 2); + m_fdc->writeCmd(head << 2 | m_driveNumber); m_fdc->writeCmd(cyl); m_fdc->waitIrq(); @@ -160,20 +162,23 @@ bool FloppyDrive::seek(u32int cyli, s32int head) { } if (cyl == 0xFF or cyl == 0x00 or cyl == (int)cyli) { //0xFF for bochs, 0x00 for qemu :D setMotorState(false); - m_fdc->setNoActiveDrive(); return true; } } - setMotorState(false); - m_fdc->setNoActiveDrive(); - *kvt << getName() << ": seek fail\n"; - return false; + if (recursive) { + setMotorState(false); + *kvt << getName() << ": seek fail\n"; + return false; + } else { + calibrate(); + return seek(cyli, head, true); + } } bool FloppyDrive::doTrack(u32int cyl, u8int dir) { + m_fdc->setActiveDrive(m_driveNumber); if (!seek(cyl, 0)) return false; if (!seek(cyl, 1)) return false; - m_fdc->setActiveDrive(m_driveNumber); u8int cmd, flags = 0xC0; switch (dir) { diff --git a/Source/Kernel/Devices/Floppy/FloppyDrive.class.h b/Source/Kernel/Devices/Floppy/FloppyDrive.class.h index 75926ea..73229b1 100644 --- a/Source/Kernel/Devices/Floppy/FloppyDrive.class.h +++ b/Source/Kernel/Devices/Floppy/FloppyDrive.class.h @@ -22,7 +22,7 @@ class FloppyDrive : public BlockDevice { bool calibrate(); bool setMotorState(bool on); bool killMotor(); - bool seek(u32int cyli, s32int head); + bool seek(u32int cyli, s32int head, bool recursive = false); bool doTrack(u32int cyl, u8int dir); public: diff --git a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp index e4cb40c..35c18eb 100644 --- a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp +++ b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp @@ -25,7 +25,7 @@ FileSystem* FATFS::mount(Partition* p, DirectoryNode* mountpoint, bool readwrite if (bs.s.extBS_16.boot_signature != 0x28 and bs.s.extBS_16.boot_signature != 0x29 and bs.s.extBS_32.boot_signature != 0x28 and bs.s.extBS_32.boot_signature != 0x29) return 0; // *** DO SOME CALCULATIONS *** - FATFS* fs = new FATFS(); + FATFS* fs = new FATFS(p); fs->m_fatSize = (bs.s.table_size_16 == 0 ? bs.s.extBS_32.table_size_32 : bs.s.table_size_16); fs->m_totalSectors = (bs.s.total_sectors_16 == 0 ? bs.s.total_sectors_32 : bs.s.total_sectors_16); fs->m_rootDirSectors = ((bs.s.root_entry_count * 32) + (bs.s.bytes_per_sector - 1)) / bs.s.bytes_per_sector; @@ -42,7 +42,6 @@ FileSystem* FATFS::mount(Partition* p, DirectoryNode* mountpoint, bool readwrite } fs->m_readOnly = true; fs->m_bs = bs.s; - fs->m_part = p; // *** CREATE ROOT DIRECTORY NODE *** fs->m_rootNode = new FATDirectoryNode("/", fs, mountpoint); FIRSTCLUS(fs->m_rootNode) = 2; @@ -52,6 +51,7 @@ FileSystem* FATFS::mount(Partition* p, DirectoryNode* mountpoint, bool readwrite delete fs; return 0; } + fs->m_fatCache.init(fs->m_fatType == 12 ? 8 : (fs->m_fatType == 16 ? 20 : 40)); if (mountpoint != 0) mountpoint->mount(fs->m_rootNode); VFS::registerFilesystem(fs); *kvt << "Detected a FAT" << (s64int)fs->m_fatType << " filesystem.\n" << @@ -69,7 +69,7 @@ u32int FATFS::nextCluster(u32int cluster) { u32int fat_offset = cluster + (cluster / 2); u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->getBlockSize()); u32int ent_offset = fat_offset % m_part->getBlockSize(); - m_part->readBlocks(fat_sector, 1, fat_table); + m_fatCache.readBlocks(fat_sector, 1, fat_table); u16int tblval = *(u16int*)&fat_table[ent_offset]; if (cluster & 1) val = tblval >> 4; else val = tblval & 0x0FFF; @@ -78,7 +78,7 @@ u32int FATFS::nextCluster(u32int cluster) { u32int fat_offset = cluster * 2; u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->getBlockSize()); u32int ent_offset = fat_offset % m_part->getBlockSize(); - m_part->readBlocks(fat_sector, 1, fat_table); + m_fatCache.readBlocks(fat_sector, 1, fat_table); u16int tblval = *(u16int*)&fat_table[ent_offset]; val = tblval; if (tblval >= 0xFFF7) val = 0; @@ -86,7 +86,7 @@ u32int FATFS::nextCluster(u32int cluster) { u32int fat_offset = cluster * 4; u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->getBlockSize()); u32int ent_offset = fat_offset % m_part->getBlockSize(); - m_part->readBlocks(fat_sector, 1, fat_table); + m_fatCache.readBlocks(fat_sector, 1, fat_table); val = *(u32int*)&fat_table[ent_offset] & 0x0FFFFFFF; if (val >= 0x0FFFFFF7) val = 0; } diff --git a/Source/Kernel/FileSystems/FAT/FATFS.class.h b/Source/Kernel/FileSystems/FAT/FATFS.class.h index 251b2a8..fbefc02 100644 --- a/Source/Kernel/FileSystems/FAT/FATFS.class.h +++ b/Source/Kernel/FileSystems/FAT/FATFS.class.h @@ -3,6 +3,7 @@ #include #include +#include struct fat_extBS_32_t { //Extended boot sector for FAT32 unsigned int table_size_32; @@ -88,9 +89,6 @@ struct fat_dir_entry_t { class FATFS : public FileSystem { private: - FATFS() {} - ~FATFS() {} - fat_BS_t m_bs; bool m_readOnly; u32int m_fatSize; //Size of one FAT, in sectors @@ -101,10 +99,14 @@ class FATFS : public FileSystem { u32int m_clusterSize; //size of a cluster in bytes u32int m_fatType; //12, 16 or 32 Partition* m_part; + BlockCache m_fatCache; u32int nextCluster(u32int cluster); //Get the next cluster number in the chain (0 = EOF) bool readCluster(u32int cluster, u8int* data); //Read the content of a cluster to a buffer + ~FATFS() {} + FATFS(Partition* p) : m_part(p), m_fatCache(p) {} + public: static FileSystem* mount(Partition* p, DirectoryNode* mountpoint, bool readwrite = false); diff --git a/Source/Kernel/VFS/BlockCache.class.cpp b/Source/Kernel/VFS/BlockCache.class.cpp new file mode 100644 index 0000000..458faf6 --- /dev/null +++ b/Source/Kernel/VFS/BlockCache.class.cpp @@ -0,0 +1,89 @@ +#include + +template +BlockCache::BlockCache(T* dev) { + m_dev = dev; + m_count = 0; +} + +template +BlockCache::~BlockCache() { + sync(); + m_count = 0; + delete m_cache; + delete m_cacheInfo; +} + +template +void BlockCache::sync() { + for (u32int i = 0; i < m_count; i++) { + if (m_cacheInfo[i].dirty) m_dev->writeBlocks(m_cacheInfo[i].id, 1, m_cache + (i * m_dev->getBlockSize())); + } +} + +template +void BlockCache::init(u32int count) { + m_count = count; + m_cacheInfo = new cached_block_t[count]; + for (u32int i = 0; i < m_count; i++) { + m_cacheInfo[i].id = 0; + m_cacheInfo[i].lastuse = 0; + m_cacheInfo[i].dirty = false; + } + m_cache = (u8int*)Mem::alloc(m_count * m_dev->getBlockSize()); +} + +template +bool BlockCache::setCache(u64int block, u8int* data, bool dirty) { + u32int best = 0; + for (u32int i = 0; i < m_count; i++) { + if (m_cacheInfo[i].id == block) { + best = i; + break; + } + if (m_cacheInfo[i].lastuse < m_cacheInfo[best].lastuse) best = i; + } + if (best >= m_count) return false; + if (m_cacheInfo[best].dirty && (m_cacheInfo[best].id != block or !dirty)) + m_dev->writeBlocks(m_cacheInfo[best].id, 1, m_cache + (best * m_dev->getBlockSize())); + m_cacheInfo[best].id = block; + m_cacheInfo[best].lastuse = Time::uptime(); + m_cacheInfo[best].dirty = dirty; + memcpy(m_cache + (best * m_dev->getBlockSize()), data, m_dev->getBlockSize()); + return true; +} + +template +bool BlockCache::getCache(u64int block, u8int* data) { + for (u32int i = 0; i < m_count; i++) { + if (m_cacheInfo[i].id == block && m_cacheInfo[i].lastuse != 0) { + m_cacheInfo[i].lastuse = Time::uptime(); + memcpy(data, m_cache + (i * m_dev->getBlockSize()), m_dev->getBlockSize()); + return true; + } + } + return false; +} + +template +bool BlockCache::readBlocks(u64int startblock, u32int count, u8int* data) { + if (count == 1) { + if (getCache(startblock, data)) return true; + if (!m_dev->readBlocks(startblock, count, data)) return false; + setCache(startblock, data); + return true; + } else { + return m_dev->readBlocks(startblock, count, data); + } +} + +template +bool BlockCache::writeBlocks(u64int startblock, u32int count, u8int* data) { + if (m_dev->readOnly()) return false; + if (count == 1) { + if (!setCache(startblock, data, true)) return m_dev->writeBlocks(startblock, count, data); + return true; + } else { + return m_dev->writeBlocks(startblock, count, data); + } +} diff --git a/Source/Kernel/VFS/BlockCache.class.h b/Source/Kernel/VFS/BlockCache.class.h new file mode 100644 index 0000000..0b26180 --- /dev/null +++ b/Source/Kernel/VFS/BlockCache.class.h @@ -0,0 +1,32 @@ +#ifndef DEF_BLOCKCACHE_CLASS_H +#define DEF_BLOCKCACHE_CLASS_H + +template +class BlockCache { + private: + T* m_dev; + u32int m_count; + struct cached_block_t { + u64int id; + u32int lastuse; + bool dirty; + } *m_cacheInfo; + u8int* m_cache; + + void sync(); + bool setCache(u64int block, u8int* data, bool dirty = false); + bool getCache(u64int block, u8int* data); + + public: + BlockCache(T* dev); + ~BlockCache(); + void init(u32int count); + + bool readBlocks(u64int startblock, u32int count, u8int* data); + bool writeBlocks(u64int startblock, u32int count, u8int* data); + +}; + +#include "BlockCache.class.cpp" + +#endif diff --git a/Source/Kernel/VFS/Part.ns.cpp b/Source/Kernel/VFS/Part.ns.cpp index 1bd6a8e..9ead6b5 100644 --- a/Source/Kernel/VFS/Part.ns.cpp +++ b/Source/Kernel/VFS/Part.ns.cpp @@ -57,7 +57,7 @@ u32int getDeviceID(BlockDevice* dev) { } BlockDevice* dev(String _class, u32int idx) { - if (_class.empty()) _class = "block"; + if (_class.empty()) return devices[idx]; for (u32int i = 0; i < devices.size(); i++) { String devclass = devices[i]->getClass(); if (devclass == _class or (devclass.size() > _class.size() and devclass.substr(0, _class.size()) == _class)) { diff --git a/Source/Kernel/VFS/Partition.class.cpp b/Source/Kernel/VFS/Partition.class.cpp index b62f33c..1476b14 100644 --- a/Source/Kernel/VFS/Partition.class.cpp +++ b/Source/Kernel/VFS/Partition.class.cpp @@ -2,21 +2,23 @@ using namespace CMem; //For memcpy -Partition::Partition(BlockDevice* dev, u8int partnumber, u64int startblock, u64int blockcount) { +Partition::Partition(BlockDevice* dev, u8int partnumber, u64int startblock, u64int blockcount) +: m_cache(dev) { m_device = dev; m_partnumber = partnumber; m_startblock = startblock; m_blockcount = blockcount; + m_cache.init(10 + (m_device->blocks() / 1000 > 100 ? 100 : m_device->blocks() / 1000)); } bool Partition::readBlocks(u64int startblock, u32int count, u8int *data) { if (startblock + count > m_startblock + m_blockcount) return false; - return m_device->readBlocks(startblock - m_startblock, count, data); + return m_cache.readBlocks(startblock - m_startblock, count, data); } bool Partition::writeBlocks(u64int startblock, u32int count, u8int *data) { if (startblock + count > m_startblock + m_blockcount) return false; - return m_device->writeBlocks(startblock - m_startblock, count, data); + return m_cache.writeBlocks(startblock - m_startblock, count, data); } bool Partition::read(u64int start, u32int length, u8int *data) { diff --git a/Source/Kernel/VFS/Partition.class.h b/Source/Kernel/VFS/Partition.class.h index 8df1c4f..f511074 100644 --- a/Source/Kernel/VFS/Partition.class.h +++ b/Source/Kernel/VFS/Partition.class.h @@ -2,10 +2,12 @@ #define DEF_PARTITION_CLASS_H #include +#include class Partition { private: BlockDevice* m_device; + BlockCache m_cache; u64int m_startblock, m_blockcount; u8int m_partnumber; //Partition number in partition table of device diff --git a/Source/Kernel/VFS/VFS.ns.cpp b/Source/Kernel/VFS/VFS.ns.cpp index 6a5fe4e..3b59c5a 100644 --- a/Source/Kernel/VFS/VFS.ns.cpp +++ b/Source/Kernel/VFS/VFS.ns.cpp @@ -90,7 +90,6 @@ bool mount(String str, VirtualTerminal* vt, multiboot_info_t *mbd) { *vt << "Syntax: :[]::[:[:[ro|rw]]]\n"; return false; } - if (fs[1] == "") fs[1] = "block"; if (fs.size() < 5) fs.push(""); if (fs.size() < 6) fs.push("ro"); //By default, mount file systems read-only BlockDevice* d = Part::dev(fs[1], fs[2].toInt()); -- cgit v1.2.3 From a913d4c2cb4daf10c0eac4d548fccb26b2a9f099 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sat, 28 Nov 2009 14:01:27 +0100 Subject: Fixed some stuff --- Source/Kernel/FileSystems/FAT/FATFS.class.cpp | 16 ++++++++-------- Source/Kernel/VFS/BlockCache.class.cpp | 10 +++++----- Source/Kernel/VFS/Partition.class.cpp | 2 +- Source/Kernel/VFS/Partition.class.h | 2 +- 4 files changed, 15 insertions(+), 15 deletions(-) (limited to 'Source') diff --git a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp index 35c18eb..4c20b3f 100644 --- a/Source/Kernel/FileSystems/FAT/FATFS.class.cpp +++ b/Source/Kernel/FileSystems/FAT/FATFS.class.cpp @@ -63,12 +63,12 @@ FileSystem* FATFS::mount(Partition* p, DirectoryNode* mountpoint, bool readwrite } u32int FATFS::nextCluster(u32int cluster) { - u8int fat_table[m_part->getBlockSize()]; + u8int fat_table[m_part->blockSize()]; u32int val; if (m_fatType == 12) { u32int fat_offset = cluster + (cluster / 2); - u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->getBlockSize()); - u32int ent_offset = fat_offset % m_part->getBlockSize(); + u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->blockSize()); + u32int ent_offset = fat_offset % m_part->blockSize(); m_fatCache.readBlocks(fat_sector, 1, fat_table); u16int tblval = *(u16int*)&fat_table[ent_offset]; if (cluster & 1) val = tblval >> 4; @@ -76,16 +76,16 @@ u32int FATFS::nextCluster(u32int cluster) { if (val >= 0xFF7) val = 0; } else if (m_fatType == 16) { u32int fat_offset = cluster * 2; - u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->getBlockSize()); - u32int ent_offset = fat_offset % m_part->getBlockSize(); + u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->blockSize()); + u32int ent_offset = fat_offset % m_part->blockSize(); m_fatCache.readBlocks(fat_sector, 1, fat_table); u16int tblval = *(u16int*)&fat_table[ent_offset]; val = tblval; if (tblval >= 0xFFF7) val = 0; } else if (m_fatType == 32) { u32int fat_offset = cluster * 4; - u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->getBlockSize()); - u32int ent_offset = fat_offset % m_part->getBlockSize(); + u32int fat_sector = m_bs.reserved_sector_count + (fat_offset / m_part->blockSize()); + u32int ent_offset = fat_offset % m_part->blockSize(); m_fatCache.readBlocks(fat_sector, 1, fat_table); val = *(u32int*)&fat_table[ent_offset] & 0x0FFFFFFF; if (val >= 0x0FFFFFF7) val = 0; @@ -175,7 +175,7 @@ bool FATFS::loadContents(DirectoryNode* dir) { u32int entries = m_clusterSize / sizeof(fat_dir_entry_t); if (cluster == 2 and m_fatType != 32) { //This is the value we use for the root directory - e.c = (u8int*)Mem::alloc(m_rootDirSectors * m_part->getBlockSize()); + e.c = (u8int*)Mem::alloc(m_rootDirSectors * m_part->blockSize()); if (!m_part->readBlocks(m_firstDataSector, m_rootDirSectors, e.c)) return false; } else { e.c = (u8int*)Mem::alloc(m_clusterSize); diff --git a/Source/Kernel/VFS/BlockCache.class.cpp b/Source/Kernel/VFS/BlockCache.class.cpp index 458faf6..d505a99 100644 --- a/Source/Kernel/VFS/BlockCache.class.cpp +++ b/Source/Kernel/VFS/BlockCache.class.cpp @@ -17,7 +17,7 @@ BlockCache::~BlockCache() { template void BlockCache::sync() { for (u32int i = 0; i < m_count; i++) { - if (m_cacheInfo[i].dirty) m_dev->writeBlocks(m_cacheInfo[i].id, 1, m_cache + (i * m_dev->getBlockSize())); + if (m_cacheInfo[i].dirty) m_dev->writeBlocks(m_cacheInfo[i].id, 1, m_cache + (i * m_dev->blockSize())); } } @@ -30,7 +30,7 @@ void BlockCache::init(u32int count) { m_cacheInfo[i].lastuse = 0; m_cacheInfo[i].dirty = false; } - m_cache = (u8int*)Mem::alloc(m_count * m_dev->getBlockSize()); + m_cache = (u8int*)Mem::alloc(m_count * m_dev->blockSize()); } template @@ -45,11 +45,11 @@ bool BlockCache::setCache(u64int block, u8int* data, bool dirty) { } if (best >= m_count) return false; if (m_cacheInfo[best].dirty && (m_cacheInfo[best].id != block or !dirty)) - m_dev->writeBlocks(m_cacheInfo[best].id, 1, m_cache + (best * m_dev->getBlockSize())); + m_dev->writeBlocks(m_cacheInfo[best].id, 1, m_cache + (best * m_dev->blockSize())); m_cacheInfo[best].id = block; m_cacheInfo[best].lastuse = Time::uptime(); m_cacheInfo[best].dirty = dirty; - memcpy(m_cache + (best * m_dev->getBlockSize()), data, m_dev->getBlockSize()); + memcpy(m_cache + (best * m_dev->blockSize()), data, m_dev->blockSize()); return true; } @@ -58,7 +58,7 @@ bool BlockCache::getCache(u64int block, u8int* data) { for (u32int i = 0; i < m_count; i++) { if (m_cacheInfo[i].id == block && m_cacheInfo[i].lastuse != 0) { m_cacheInfo[i].lastuse = Time::uptime(); - memcpy(data, m_cache + (i * m_dev->getBlockSize()), m_dev->getBlockSize()); + memcpy(data, m_cache + (i * m_dev->blockSize()), m_dev->blockSize()); return true; } } diff --git a/Source/Kernel/VFS/Partition.class.cpp b/Source/Kernel/VFS/Partition.class.cpp index 1476b14..8d7de9b 100644 --- a/Source/Kernel/VFS/Partition.class.cpp +++ b/Source/Kernel/VFS/Partition.class.cpp @@ -67,4 +67,4 @@ BlockDevice* Partition::getDevice() { return m_device; } u64int Partition::getStartBlock() { return m_startblock; } u64int Partition::getBlockCount() { return m_blockcount; } u8int Partition::getPartNumber() { return m_partnumber; } -u32int Partition::getBlockSize() { return m_device->blockSize(); } +u32int Partition::blockSize() { return m_device->blockSize(); } diff --git a/Source/Kernel/VFS/Partition.class.h b/Source/Kernel/VFS/Partition.class.h index f511074..eb0aafd 100644 --- a/Source/Kernel/VFS/Partition.class.h +++ b/Source/Kernel/VFS/Partition.class.h @@ -26,7 +26,7 @@ class Partition { u64int getStartBlock(); u64int getBlockCount(); u8int getPartNumber(); - u32int getBlockSize(); + u32int blockSize(); inline u64int blocks() { return getBlockCount(); } }; -- cgit v1.2.3