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/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 +- 14 files changed, 144 insertions(+), 82 deletions(-) (limited to 'Source/Kernel') 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