From 92abedffec913fe7337117403c5e07185356c81b Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Fri, 2 Oct 2009 22:51:28 +0200 Subject: The kernel shell is now in an independent class, KernelShell:: --- Source/Kernel/Config.h | 12 +- Source/Kernel/Core/kmain.wtf.cpp | 173 ++------------------- .../Devices/Floppy/FloppyController.class.cpp | 4 +- Source/Kernel/Devices/Floppy/FloppyDrive.class.h | 2 +- Source/Kernel/Makefile | 3 + Source/Kernel/Melon.ke | Bin 159686 -> 165137 bytes Source/Kernel/Shell/KernelShell-fs.class.cpp | 104 +++++++++++++ Source/Kernel/Shell/KernelShell-sys.class.cpp | 60 +++++++ Source/Kernel/Shell/KernelShell.class.cpp | 98 ++++++++++++ Source/Kernel/Shell/KernelShell.class.h | 43 +++++ Source/Kernel/SyscallManager/IDT.ns.cpp | 2 +- Source/Kernel/TaskManager/Process.class.cpp | 1 + Source/Kernel/TaskManager/Task.ns.cpp | 4 +- Source/Kernel/TaskManager/Thread.class.cpp | 18 ++- Source/Kernel/TaskManager/Thread.class.h | 8 +- 15 files changed, 351 insertions(+), 181 deletions(-) create mode 100644 Source/Kernel/Shell/KernelShell-fs.class.cpp create mode 100644 Source/Kernel/Shell/KernelShell-sys.class.cpp create mode 100644 Source/Kernel/Shell/KernelShell.class.cpp create mode 100644 Source/Kernel/Shell/KernelShell.class.h (limited to 'Source') diff --git a/Source/Kernel/Config.h b/Source/Kernel/Config.h index 09c7a14..e5943fb 100644 --- a/Source/Kernel/Config.h +++ b/Source/Kernel/Config.h @@ -9,11 +9,15 @@ //Color scheme #define TXTLOGO_FGCOLOR 9 #define TXTLOGO_BGCOLOR 0 -#define KVT_FGCOLOR 0 -#define KVT_BGCOLOR 7 -#define KVT_OKCOLOR 1 +#define KVT_FGCOLOR 7 +#define KVT_BGCOLOR 0 +#define KVT_OKCOLOR 2 #define KVT_BLECOLOR 4 //BLE = Boot Log Entry -#define KVT_ENTRYCOLOR 6 #define KVT_LIGHTCOLOR 8 +#define SHELL_FGCOLOR 0 +#define SHELL_BGCOLOR 7 +#define SHELL_LIGHTCOLOR 8 +#define SHELL_ENTRYCOLOR 6 + #endif diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 0f22189..924cfc2 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -74,8 +75,8 @@ void kmain(multiboot_info_t* mbd, u32int magic) { melonLogoVT->map(1); //Create a VT for logging what kernel does - SimpleVT *kvt = new ScrollableVT(15, 76, 200, KVT_FGCOLOR, KVT_BGCOLOR); - kvt->map(melonLogoLines + 2); + SimpleVT *kvt = new ScrollableVT(5, 69, 10, KVT_FGCOLOR, KVT_BGCOLOR); + kvt->map(20); INFO(kvt); *kvt << "Lower ram : " << (s32int)mbd->mem_lower << "k, upper : " << (s32int)mbd->mem_upper << "k.\n"; INFO(kvt); *kvt << "Placement address : " << (u32int)Mem::placementAddress << "\n"; @@ -124,165 +125,17 @@ void kmain(multiboot_info_t* mbd, u32int magic) { Log::log(KL_STATUS, "kmain : Floppy drives detected"); asm volatile("sti"); + Log::log(KL_STATUS, "kmain : Interrupts enabled."); - while(1) { - kvt->setColor(KVT_LIGHTCOLOR); - *kvt << "[" << cwd->getName() << "]# "; - kvt->setColor(KVT_ENTRYCOLOR); - Vector tokens = kvt->readLine().split(" "); - kvt->setColor(KVT_FGCOLOR); - if (tokens[0] == "help") { - *kvt << " - Command list for integrated kernel shell:\n"; - *kvt << " - help shows this help screen\n"; - *kvt << " - reboot reboots your computer\n"; - *kvt << " - halt shuts down your computer\n"; - *kvt << " - panic causes a kernel panic\n"; - *kvt << " - devices shows all detected devices on your computer\n"; - *kvt << " - loadkeys loads specified kekymap\n"; - *kvt << " - free shows memory usage (physical frames and kernel heap)\n"; - *kvt << " - uptime shows seconds since boot\n"; - *kvt << " - part shows all detected block devices and partitions\n"; - *kvt << " - Commands you should know how to use : ls, cd, cat, pwd, rm, mkdir, wf\n"; - } else if (tokens[0] == "reboot") { - Sys::reboot(); - } else if (tokens[0] == "halt") { - Sys::halt(); - } else if (tokens[0] == "panic") { - PANIC("This is what happens when you say 'panic'."); - } else if (tokens[0] == "ls") { - DirectoryNode* d = cwd; - if (tokens.size() == 2) { - FSNode* n = VFS::find(tokens[1], cwd); - d = NULL; - if (n == NULL) - *kvt << "No such directory : " << tokens[1] << "\n"; - else if (n->type() != NT_DIRECTORY) - *kvt << "Not a directory : " << tokens[1] << "\n"; - else - d = (DirectoryNode*)n; - } - if (d != NULL) *kvt << "Contents of directory " << VFS::path(d) << " :\n"; - for (u32int i = 0; d != NULL && i < d->getLength(); i++) { - FSNode* n = d->getChild(i); - if (n->type() == NT_FILE) { - FileNode* f = (FileNode*)n; - *kvt << " - FILE\t" << f->getName(); - kvt->setCursorCol(30); - *kvt << (s32int)f->getLength() << " bytes.\n"; - } else if (n->type() == NT_DIRECTORY) { - *kvt << " - DIR\t" << n->getName() << "/"; - kvt->setCursorCol(30); - *kvt << (s32int)n->getLength() << " items.\n"; - } - } - } else if (tokens[0] == "cd") { - if (tokens.size() == 1) { - *kvt << "Error : no argument given.\n"; - } else { - FSNode* n = VFS::find(tokens[1], cwd); - if (n == NULL) - *kvt << "No such directory : " << tokens[1] << "\n"; - else if (n->type() != NT_DIRECTORY) - *kvt << "Not a directory : " << tokens[1] << "\n"; - else - cwd = (DirectoryNode*)n; - } - } else if (tokens[0] == "cat") { - if (tokens.size() == 1) *kvt << "Meow.\n"; - for (u32int i = 1; i < tokens.size(); i++) { - File f(tokens[i], FM_READ, cwd); - if (f.valid()) { - u8int *buff = (u8int*)Mem::kalloc(f.length() + 1); - f.read(f.length(), buff); - buff[f.length()] = 0; - *kvt << String((const char*) buff); - Mem::kfree(buff); - } else { - *kvt << "Error reading from file " << tokens[i] << "\n"; - } - } - } else if (tokens[0] == "pwd") { - *kvt << "Current location : " << VFS::path(cwd) << "\n"; - } else if (tokens[0] == "rm") { - if (tokens.size() == 1) *kvt << "Error : no argument specified.\n"; - for (u32int i = 1; i < tokens.size(); i++) { - if (!VFS::remove(tokens[i], cwd)) { - *kvt << "Error while removing file " << tokens[i] << "\n"; - } - } - } else if (tokens[0] == "mkdir") { - if (tokens.size() > 1) { - for (u32int i = 1; i < tokens.size(); i++) { - if (VFS::createDirectory(tokens[i], cwd) == NULL) - *kvt << "Error while creating directory " << tokens[i] << "\n"; - } - } else { - *kvt << "No argument specified.\n"; - } - } else if (tokens[0] == "wf") { - if (tokens.size() == 1) { - *kvt << "No file to write !\n"; - } else { - File f(tokens[1], FM_TRUNCATE, cwd); - if (f.valid()) { - String t = kvt->readLine(); - while (t != ".") { - t += "\n"; - ByteArray temp(t); - f.write(temp); - t = kvt->readLine(); - } - } else { - *kvt << "Error openning file.\n"; - } - } - } else if (tokens[0] == "devices") { - Vector dev = Dev::findDevices(); - *kvt << " - Detected devices :\n"; - for (u32int i = 0; i < dev.size(); i++) { - *kvt << " - " << dev[i]->getClass(); - kvt->setCursorCol(25); - *kvt << dev[i]->getName() << "\n"; - } - } else if (tokens[0] == "loadkeys") { - if (tokens.size() == 1) { - *kvt << "Error : no argument specified.\n"; - } else { - if (!Kbd::loadKeymap(tokens[1])) { - *kvt << "Error while loading keymap " << tokens[1] << ".\n"; - } - } - } else if (tokens[0] == "free") { - u32int frames = PhysMem::total(), freef = PhysMem::free(); - *kvt << " - Free frames : " << (s32int)freef << " (" << (s32int)(freef * 4 / 1024) << "Mo) of " - << (s32int)frames << " (" << (s32int)(frames * 4 / 1024) << "Mo).\n"; - u32int kh = Mem::kheapSize(), freek = Mem::kheapFree; - *kvt << " - Kernel heap free : " << (s32int)(freek / 1024 / 1024) << "Mo (" << (s32int)(freek / 1024) << - "Ko) of " << (s32int)(kh / 1024 / 1024) << "Mo (" << (s32int)(kh / 1024) << "Ko).\n"; - } else if (tokens[0] == "uptime") { - *kvt << " - Uptime : " << (s32int)(Time::uptime()) << "s.\n"; - } else if (tokens[0] == "part") { - *kvt << " * ID\tClass Name\n"; - for (u32int i = 0; i < Part::devices.size(); i++) { - *kvt << " - " << (s32int)i << "\t"; - if (Part::devices[i] == 0) { - *kvt << "[none]\n"; - } else { - *kvt << Part::devices[i]->getClass(); - kvt->setCursorCol(33); - *kvt << Part::devices[i]->getName() << "\n"; - for (u32int j = 0; j < Part::partitions.size(); j++) { - if (Part::partitions[j]->getDevice() == Part::devices[i]) { - *kvt << "\t - Partition " << (s32int)Part::partitions[j]->getPartNumber() << - ", start at " << (s32int)Part::partitions[j]->getStartBlock() << - ", size " << (s32int)Part::partitions[j]->getBlockCount() << "\n"; - } - } - } - } - } else if (tokens.size() > 1 or tokens[0] != "") { - *kvt << " - Unrecognized command: " << tokens[0] << "\n"; - } + new KernelShell(cwd); //No need to save that in a var, it is automatically destroyed anyways + Log::log(KL_STATUS, "kmain : Kernel shell launched"); + + while (KernelShell::getInstances() > 0) { + Task::currentThread->sleep(10); } + + Log::log(KL_STATUS, "kmain : All kernel shells finished. Halting."); + Sys::halt(); + PANIC("END OF KMAIN"); } diff --git a/Source/Kernel/Devices/Floppy/FloppyController.class.cpp b/Source/Kernel/Devices/Floppy/FloppyController.class.cpp index 3e97e25..fa7a56a 100644 --- a/Source/Kernel/Devices/Floppy/FloppyController.class.cpp +++ b/Source/Kernel/Devices/Floppy/FloppyController.class.cpp @@ -73,7 +73,7 @@ void FloppyController::dmaRelease() { //********************************************************* // FOR THE CONTROLLER //********************************************************* -u32int floppyMotorTimer() { //This will be an independant thread +u32int floppyMotorTimer(void* plop) { //This will be an independant thread while(1) { Task::currentThread->sleep(1000); //Check only every second Vector floppys = Dev::findDevices("block.floppy"); @@ -118,7 +118,7 @@ void FloppyController::detect() { //TODO : do this better Part::registerDevice((BlockDevice*)fdds[i]); } - new Thread(floppyMotorTimer, true); + new Thread(floppyMotorTimer, 0, true); } String FloppyController::getClass() { diff --git a/Source/Kernel/Devices/Floppy/FloppyDrive.class.h b/Source/Kernel/Devices/Floppy/FloppyDrive.class.h index 3ff832b..75926ea 100644 --- a/Source/Kernel/Devices/Floppy/FloppyDrive.class.h +++ b/Source/Kernel/Devices/Floppy/FloppyDrive.class.h @@ -7,7 +7,7 @@ class FloppyDrive : public BlockDevice { friend class FloppyController; - friend u32int floppyMotorTimer(); + friend u32int floppyMotorTimer(void*); private: FloppyDrive(FloppyController *fdc, u8int number, u8int type); //Private constructor, called by FloppyController() diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index c870a26..fd5263b 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -38,6 +38,9 @@ Objects = Core/loader.wtf.o \ VTManager/FileVT.class.o \ VTManager/VirtualTerminal-kbd.proto.o \ VTManager/VT.ns.o \ + Shell/KernelShell.class.o \ + Shell/KernelShell-fs.class.o \ + Shell/KernelShell-sys.class.o \ Library/Bitset.class.o \ Library/String.class.o \ Library/ByteArray.class.o \ diff --git a/Source/Kernel/Melon.ke b/Source/Kernel/Melon.ke index 3cd9a6c..2f43146 100755 Binary files a/Source/Kernel/Melon.ke and b/Source/Kernel/Melon.ke differ diff --git a/Source/Kernel/Shell/KernelShell-fs.class.cpp b/Source/Kernel/Shell/KernelShell-fs.class.cpp new file mode 100644 index 0000000..3ac7b20 --- /dev/null +++ b/Source/Kernel/Shell/KernelShell-fs.class.cpp @@ -0,0 +1,104 @@ +#include "KernelShell.class.h" +#include +#include + +void KernelShell::ls(Vector& args) { + DirectoryNode* d = m_cwd; + if (args.size() == 2) { + FSNode* n = VFS::find(args[1], m_cwd); + d = NULL; + if (n == NULL) + *m_vt << "No such directory : " << args[1] << "\n"; + else if (n->type() != NT_DIRECTORY) + *m_vt << "Not a directory : " << args[1] << "\n"; + else + d = (DirectoryNode*)n; + } + if (d != NULL) *m_vt << "Contents of directory " << VFS::path(d) << " :\n"; + for (u32int i = 0; d != NULL && i < d->getLength(); i++) { + FSNode* n = d->getChild(i); + if (n->type() == NT_FILE) { + FileNode* f = (FileNode*)n; + *m_vt << " - FILE\t" << f->getName(); + m_vt->setCursorCol(30); + *m_vt << (s32int)f->getLength() << " bytes.\n"; + } else if (n->type() == NT_DIRECTORY) { + *m_vt << " - DIR\t" << n->getName() << "/"; + m_vt->setCursorCol(30); + *m_vt << (s32int)n->getLength() << " items.\n"; + } + } +} + +void KernelShell::cd(Vector& args) { + if (args.size() == 1) { + *m_vt << "Error : no argument given.\n"; + } else { + FSNode* n = VFS::find(args[1], m_cwd); + if (n == NULL) + *m_vt << "No such directory : " << args[1] << "\n"; + else if (n->type() != NT_DIRECTORY) + *m_vt << "Not a directory : " << args[1] << "\n"; + else + m_cwd = (DirectoryNode*)n; + } +} + +void KernelShell::pwd(Vector& args) { + *m_vt << "Current location : " << VFS::path(m_cwd) << "\n"; +} + +void KernelShell::cat(Vector& args) { + if (args.size() == 1) *m_vt << "Meow.\n"; + for (u32int i = 1; i < args.size(); i++) { + File f(args[i], FM_READ, m_cwd); + if (f.valid()) { + u8int *buff = (u8int*)Mem::kalloc(f.length() + 1); + f.read(f.length(), buff); + buff[f.length()] = 0; + *m_vt << String((const char*) buff); + Mem::kfree(buff); + } else { + *m_vt << "Error reading from file " << args[i] << "\n"; + } + } +} + +void KernelShell::mkdir(Vector& args) { + if (args.size() > 1) { + for (u32int i = 1; i < args.size(); i++) { + if (VFS::createDirectory(args[i], m_cwd) == NULL) + *m_vt << "Error while creating directory " << args[i] << "\n"; + } + } else { + *m_vt << "No argument specified.\n"; + } +} + +void KernelShell::rm(Vector& args) { + if (args.size() == 1) *m_vt << "Error : no argument specified.\n"; + for (u32int i = 1; i < args.size(); i++) { + if (!VFS::remove(args[i], m_cwd)) { + *m_vt << "Error while removing file " << args[i] << "\n"; + } + } +} + +void KernelShell::wf(Vector& args) { + if (args.size() == 1) { + *m_vt << "No file to write !\n"; + } else { + File f(args[1], FM_TRUNCATE, m_cwd); + if (f.valid()) { + String t = m_vt->readLine(); + while (t != ".") { + t += "\n"; + ByteArray temp(t); + f.write(temp); + t = m_vt->readLine(); + } + } else { + *m_vt << "Error openning file.\n"; + } + } +} diff --git a/Source/Kernel/Shell/KernelShell-sys.class.cpp b/Source/Kernel/Shell/KernelShell-sys.class.cpp new file mode 100644 index 0000000..17ff19c --- /dev/null +++ b/Source/Kernel/Shell/KernelShell-sys.class.cpp @@ -0,0 +1,60 @@ +#include "KernelShell.class.h" +#include +#include +#include +#include +#include + +void KernelShell::devices(Vector& args) { + Vector dev = Dev::findDevices(); + *m_vt << " - Detected devices :\n"; + for (u32int i = 0; i < dev.size(); i++) { + *m_vt << " - " << dev[i]->getClass(); + m_vt->setCursorCol(25); + *m_vt << dev[i]->getName() << "\n"; + } +} + +void KernelShell::loadkeys(Vector& args) { + if (args.size() == 1) { + *m_vt << "Error : no argument specified.\n"; + } else { + if (!Kbd::loadKeymap(args[1])) { + *m_vt << "Error while loading keymap " << args[1] << ".\n"; + } + } +} + +void KernelShell::free(Vector& args) { + u32int frames = PhysMem::total(), freef = PhysMem::free(); + *m_vt << " - Free frames : " << (s32int)freef << " (" << (s32int)(freef * 4 / 1024) << "Mo) of " + << (s32int)frames << " (" << (s32int)(frames * 4 / 1024) << "Mo).\n"; + u32int kh = Mem::kheapSize(), freek = Mem::kheapFree; + *m_vt << " - Kernel heap free : " << (s32int)(freek / 1024 / 1024) << "Mo (" << (s32int)(freek / 1024) << + "Ko) of " << (s32int)(kh / 1024 / 1024) << "Mo (" << (s32int)(kh / 1024) << "Ko).\n"; +} + +void KernelShell::uptime(Vector& args) { + *m_vt << " - Uptime : " << (s32int)(Time::uptime()) << "s.\n"; +} + +void KernelShell::part(Vector& args) { + *m_vt << " * ID\tClass Name\n"; + for (u32int i = 0; i < Part::devices.size(); i++) { + *m_vt << " - " << (s32int)i << "\t"; + if (Part::devices[i] == 0) { + *m_vt << "[none]\n"; + } else { + *m_vt << Part::devices[i]->getClass(); + m_vt->setCursorCol(33); + *m_vt << Part::devices[i]->getName() << "\n"; + for (u32int j = 0; j < Part::partitions.size(); j++) { + if (Part::partitions[j]->getDevice() == Part::devices[i]) { + *m_vt << "\t - Partition " << (s32int)Part::partitions[j]->getPartNumber() << + ", start at " << (s32int)Part::partitions[j]->getStartBlock() << + ", size " << (s32int)Part::partitions[j]->getBlockCount() << "\n"; + } + } + } + } +} diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp new file mode 100644 index 0000000..5d78953 --- /dev/null +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -0,0 +1,98 @@ +#include "KernelShell.class.h" +#include +#include + +u32int KernelShell::m_instances = 0; + +#define COMMAND(name, wat) {(void*)name, (void*)(&KernelShell::wat)}, + +u32int shellRun(void* ks) { + KernelShell* sh = (KernelShell*)ks; + u32int ret = sh->run(); + delete sh; + return ret; +} + +KernelShell::KernelShell(DirectoryNode* cwd) { + m_vt = new ScrollableVT(10, 76, 200, SHELL_FGCOLOR, SHELL_BGCOLOR); + ((ScrollableVT*)m_vt)->map(9); + Kbd::setFocus(m_vt); + m_cwd = cwd; + *m_vt << "Welcome to Melon's kernel shell !\n"; + m_thread = new Thread(shellRun, (void*)this, true); + m_instances++; +} + +KernelShell::~KernelShell() { + delete m_vt; + m_instances--; +} + +u32int KernelShell::run() { + + struct { + const char* name; + void (KernelShell::*cmd)(Vector&); + } commands[]= { + {"ls", &KernelShell::ls}, + {"cd", &KernelShell::cd}, + {"pwd", &KernelShell::pwd}, + {"cat", &KernelShell::cat}, + {"mkdir", &KernelShell::mkdir}, + {"rm", &KernelShell::rm}, + {"wf", &KernelShell::wf}, + + {"devices", &KernelShell::devices}, + {"loadkeys", &KernelShell::loadkeys}, + {"free", &KernelShell::free}, + {"uptime", &KernelShell::uptime}, + {"part", &KernelShell::part}, + + {0, 0} + }; + + while (1) { + m_vt->setColor(SHELL_LIGHTCOLOR); + *m_vt << "[" << m_cwd->getName() << "]# "; + m_vt->setColor(SHELL_ENTRYCOLOR); + Vector tokens = m_vt->readLine().split(" "); + m_vt->setColor(SHELL_FGCOLOR); + if (tokens[0] == "help") { + *m_vt << " - Command list for integrated kernel shell:\n"; + *m_vt << " - help shows this help screen\n"; + *m_vt << " - reboot reboots your computer\n"; + *m_vt << " - halt shuts down your computer\n"; + *m_vt << " - panic causes a kernel panic\n"; + *m_vt << " - devices shows all detected devices on your computer\n"; + *m_vt << " - loadkeys loads specified kekymap\n"; + *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 << " - Standard UNIX commands : ls cd cat pwd rm mkdir wf\n"; + *m_vt << " - Scroll up with shift+pgup !\n"; + } else if (tokens[0] == "reboot") { + Sys::reboot(); + } else if (tokens[0] == "halt") { + Sys::halt(); + } else if (tokens[0] == "panic") { + PANIC("This is what happens when you say 'panic'."); + } else if (tokens[0] != "" or tokens.size() != 1) { + u32int i = 0; + bool found = false; + while (commands[i].name != 0) { + if (tokens[0] == (const char*)commands[i].name) { + found = true; + if (commands[i].name != 0) { + (this->*(commands[i].cmd))(tokens); //Call command + } else { + *m_vt << "This command isn't enabled... yet !\n"; + } + break; + } + i++; + } + if (!found) *m_vt << "Unknown command : " << tokens[0] << "\n"; + } + } + return 1337; +} diff --git a/Source/Kernel/Shell/KernelShell.class.h b/Source/Kernel/Shell/KernelShell.class.h new file mode 100644 index 0000000..182aa66 --- /dev/null +++ b/Source/Kernel/Shell/KernelShell.class.h @@ -0,0 +1,43 @@ +#ifndef DEF_KERNELSHELL_CLASS_H +#define DEF_KERNELSHELL_CLASS_H + +#include +#include +#include +#include + +class KernelShell { + friend u32int shellRun(void* ks); + + private: + VirtualTerminal *m_vt; + DirectoryNode *m_cwd; + Thread* m_thread; + static u32int m_instances; + + ~KernelShell(); + u32int run(); + + //in KernelShell-fs + void ls(Vector& args); + void cd(Vector& args); + void pwd(Vector& args); + void cat(Vector& args); + void mkdir(Vector& args); + void rm(Vector& args); + void wf(Vector& args); + + //in KernelShell-sys + void devices(Vector& args); + void loadkeys(Vector& args); + void free(Vector& args); + void uptime(Vector& args); + void part(Vector& args); + + public: + KernelShell(DirectoryNode* cwd); + + static u32int getInstances() { return m_instances; } +}; + +#endif diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index 4f41fb2..dc40747 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -76,7 +76,7 @@ extern "C" void interrupt_handler(registers_t regs) { if (regs.int_no == 66) { //This syscall signals to kernel that thread ended. Task::currentThread->finish(regs.eax); } - if (doSwitch) Task::doSwitch(); + if (doSwitch) Task::doSwitch(); //DO NEVER COUNT ON COMMING BACK FROM HERE } namespace IDT { diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index ec1fcc9..5a707cd 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -74,6 +74,7 @@ void Process::registerThread(Thread* t) { } void Process::threadFinishes(Thread* thread, u32int retval) { + delete thread; // If it is the main thread of the process, or if it pagefaulted if (thread == m_threads[0] or retval == E_PAGEFAULT) { exit(); diff --git a/Source/Kernel/TaskManager/Task.ns.cpp b/Source/Kernel/TaskManager/Task.ns.cpp index 3ee21de..b430f24 100644 --- a/Source/Kernel/TaskManager/Task.ns.cpp +++ b/Source/Kernel/TaskManager/Task.ns.cpp @@ -3,7 +3,7 @@ //From Task.wtf.asm extern "C" u32int read_eip(); -extern "C" u32int idle_task(); +extern "C" u32int idle_task(void*); namespace Task { @@ -22,7 +22,7 @@ void initialize(String cmdline, VirtualTerminal *vt) { threads.clear(); processes.clear(); currentProcess = Process::createKernel(cmdline, vt); - idleThread = new Thread(idle_task, true); + idleThread = new Thread(idle_task, 0, true); currentThread = threads[0]; currentThreadId = 0; asm volatile ("sti"); diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index de92f0c..43884d7 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -3,33 +3,33 @@ #include #include -void runThread(Thread* thread, u32int (*entry_point)()) { +void runThread(Thread* thread, void* data, thread_entry_t entry_point) { asm volatile("sti"); - u32int ret = entry_point(); //Run ! + u32int ret = entry_point(data); //Run ! asm volatile("mov %0, %%eax; int $66;" : : "r"(ret)); //Syscall for thread ending } Thread::Thread() { //Private constructor, does nothing } -Thread::Thread(u32int (*entry_point)(), bool iskernel) { +Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) { if (iskernel) { m_isKernel = true; u32int tmp; m_kernelStackFrame = (u32int)PageAlloc::alloc(&tmp); m_process = Task::getKernelProcess(); - setup(entry_point, m_kernelStackFrame + 0x1000); //A kernel stack always is 1 frame, meaning 0x1000 bytes + setup(entry_point, data, m_kernelStackFrame + 0x1000); //A kernel stack always is 1 frame, meaning 0x1000 bytes } else { m_isKernel = false; m_process = Task::currentProcess; - setup(entry_point, m_process->stackAlloc() + STACKSIZE); + setup(entry_point, data, m_process->stackAlloc() + STACKSIZE); } } -Thread::Thread(Process* process, u32int (*entry_point)()) { +Thread::Thread(Process* process, thread_entry_t entry_point, void* data) { m_isKernel = false; m_process = process; - setup(entry_point, m_process->stackAlloc() + STACKSIZE); + setup(entry_point, data, m_process->stackAlloc() + STACKSIZE); } Thread::~Thread() { @@ -40,12 +40,14 @@ Thread::~Thread() { //Don't unregister thread in process, it has probably already been done } -void Thread::setup(u32int (*entry_point)(), u32int esp) { +void Thread::setup(thread_entry_t entry_point, void* data, u32int esp) { //Pass function parameters for runThread() u32int *stack = (u32int*)esp; stack--; *stack = (u32int)entry_point; //Push entry point (function parameter) stack--; + *stack = (u32int)data; //Push data + stack--; *stack = (u32int)this; //Push object pointer stack--; *stack = 0; //Null return address diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h index 7d7917b..dffc84a 100644 --- a/Source/Kernel/TaskManager/Thread.class.h +++ b/Source/Kernel/TaskManager/Thread.class.h @@ -9,6 +9,8 @@ #define T_SLEEPING 2 #define T_IRQWAIT 3 //This can only happen if process->uid == 0 (root) +typedef u32int(*thread_entry_t)(void*); + class Thread { friend class Process; //This might be useful @@ -27,11 +29,11 @@ class Thread { bool m_isKernel; //Says if stack is in kernel pagedir, and if thread should run in ring 0 u32int m_kernelStackFrame; //Used for allocating and freeing a frame used as a stack - void setup(u32int (*entry_point)(), u32int esp); //Sets up stack, called by both constructors + void setup(thread_entry_t entry_point, void* data, u32int esp); //Sets up stack, called by both constructors public: - Thread(u32int (*entry_point)(), bool iskernel = false); //Assumes process is current process, or is kprocess if isk - Thread(Process* process, u32int (*entry_point)()); + Thread(thread_entry_t entry_point, void* data, bool iskernel = false); //Assumes process is current process, or is kprocess if isk + Thread(Process* process, thread_entry_t entry_point, void* data); ~Thread(); void finish(u32int errcode); //Called by run() when thread returns, and by exception handler. Can also be called by the thread itself void handleException(registers_t regs, int no); -- cgit v1.2.3