summaryrefslogtreecommitdiff
path: root/Source/Kernel
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-10-02 22:51:28 +0200
committerAlexis211 <alexis211@gmail.com>2009-10-02 22:51:28 +0200
commit92abedffec913fe7337117403c5e07185356c81b (patch)
tree1527937c1a1a7ab8168891f6465e198b88bbfea2 /Source/Kernel
parent021831ab981b9df22cd1ac5e5ac51f0f84ef49a7 (diff)
downloadMelon-92abedffec913fe7337117403c5e07185356c81b.tar.gz
Melon-92abedffec913fe7337117403c5e07185356c81b.zip
The kernel shell is now in an independent class, KernelShell::
Diffstat (limited to 'Source/Kernel')
-rw-r--r--Source/Kernel/Config.h12
-rw-r--r--Source/Kernel/Core/kmain.wtf.cpp173
-rw-r--r--Source/Kernel/Devices/Floppy/FloppyController.class.cpp4
-rw-r--r--Source/Kernel/Devices/Floppy/FloppyDrive.class.h2
-rw-r--r--Source/Kernel/Makefile3
-rwxr-xr-xSource/Kernel/Melon.kebin159686 -> 165137 bytes
-rw-r--r--Source/Kernel/Shell/KernelShell-fs.class.cpp104
-rw-r--r--Source/Kernel/Shell/KernelShell-sys.class.cpp60
-rw-r--r--Source/Kernel/Shell/KernelShell.class.cpp98
-rw-r--r--Source/Kernel/Shell/KernelShell.class.h43
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.cpp2
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp1
-rw-r--r--Source/Kernel/TaskManager/Task.ns.cpp4
-rw-r--r--Source/Kernel/TaskManager/Thread.class.cpp18
-rw-r--r--Source/Kernel/TaskManager/Thread.class.h8
15 files changed, 351 insertions, 181 deletions
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 <VFS/DirectoryNode.class.h>
#include <VFS/TextFile.class.h>
#include <Core/Log.ns.h>
+#include <Shell/KernelShell.class.h>
#include <Ressources/Graphics/logo.text.cxd>
@@ -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<String> 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<Device*> 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<Device*> 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
--- a/Source/Kernel/Melon.ke
+++ b/Source/Kernel/Melon.ke
Binary files 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 <VFS/VFS.ns.h>
+#include <VFS/File.class.h>
+
+void KernelShell::ls(Vector<String>& 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<String>& 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<String>& args) {
+ *m_vt << "Current location : " << VFS::path(m_cwd) << "\n";
+}
+
+void KernelShell::cat(Vector<String>& 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<String>& 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<String>& 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<String>& 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 <DeviceManager/Dev.ns.h>
+#include <DeviceManager/Time.ns.h>
+#include <MemoryManager/Mem.ns.h>
+#include <MemoryManager/PhysMem.ns.h>
+#include <VFS/Part.ns.h>
+
+void KernelShell::devices(Vector<String>& args) {
+ Vector<Device*> 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<String>& 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<String>& 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<String>& args) {
+ *m_vt << " - Uptime : " << (s32int)(Time::uptime()) << "s.\n";
+}
+
+void KernelShell::part(Vector<String>& 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 <VTManager/ScrollableVT.class.h>
+#include <DeviceManager/Kbd.ns.h>
+
+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<String>&);
+ } 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<String> 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 <VTManager/VirtualTerminal.proto.h>
+#include <VFS/DirectoryNode.class.h>
+#include <TaskManager/Thread.class.h>
+#include <Library/Vector.class.h>
+
+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<String>& args);
+ void cd(Vector<String>& args);
+ void pwd(Vector<String>& args);
+ void cat(Vector<String>& args);
+ void mkdir(Vector<String>& args);
+ void rm(Vector<String>& args);
+ void wf(Vector<String>& args);
+
+ //in KernelShell-sys
+ void devices(Vector<String>& args);
+ void loadkeys(Vector<String>& args);
+ void free(Vector<String>& args);
+ void uptime(Vector<String>& args);
+ void part(Vector<String>& 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 <MemoryManager/PageAlloc.ns.h>
#include <DeviceManager/Time.ns.h>
-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);