summaryrefslogtreecommitdiff
path: root/Source/Kernel
diff options
context:
space:
mode:
authorAlexis211 <alexis211@gmail.com>2009-10-18 10:34:11 +0200
committerAlexis211 <alexis211@gmail.com>2009-10-18 10:34:11 +0200
commit22c06556ccbd07f4ef7da39a62d10e03fbee3fe0 (patch)
tree8b45002ef347b625c9134091a7dfad9ed16c5274 /Source/Kernel
parent7dc8c19f7d6220c9e3dac43796faf77c4f11974f (diff)
downloadMelon-22c06556ccbd07f4ef7da39a62d10e03fbee3fe0.tar.gz
Melon-22c06556ccbd07f4ef7da39a62d10e03fbee3fe0.zip
Loading binaries now is done through a much more unified interface.
Diffstat (limited to 'Source/Kernel')
-rw-r--r--Source/Kernel/Linker/Binary.proto.cpp19
-rw-r--r--Source/Kernel/Linker/Binary.proto.h16
-rw-r--r--Source/Kernel/Linker/MelonBinary.class.cpp30
-rw-r--r--Source/Kernel/Linker/MelonBinary.class.h21
-rw-r--r--Source/Kernel/Makefile2
-rw-r--r--Source/Kernel/MemoryManager/Mem.ns.cpp2
-rw-r--r--Source/Kernel/MemoryManager/PhysMem.ns.cpp2
-rw-r--r--Source/Kernel/Shell/KernelShell-fs.class.cpp27
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.cpp4
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp24
-rw-r--r--Source/Kernel/TaskManager/Process.class.h6
-rw-r--r--Source/Kernel/TaskManager/Thread.class.cpp1
12 files changed, 130 insertions, 24 deletions
diff --git a/Source/Kernel/Linker/Binary.proto.cpp b/Source/Kernel/Linker/Binary.proto.cpp
new file mode 100644
index 0000000..6053f22
--- /dev/null
+++ b/Source/Kernel/Linker/Binary.proto.cpp
@@ -0,0 +1,19 @@
+#include "Binary.proto.h"
+
+#include <Linker/MelonBinary.class.h>
+
+Binary* (*loaders[])(File& file) = {
+ &MelonBinary::load,
+
+0 };
+
+Binary* Binary::load(File& file) {
+ Binary* r = 0;
+ u32int i = 0;
+ while (loaders[i] != 0) {
+ r = loaders[i](file); //Call loader
+ if (r != 0) break;
+ i++;
+ }
+ return r;
+}
diff --git a/Source/Kernel/Linker/Binary.proto.h b/Source/Kernel/Linker/Binary.proto.h
new file mode 100644
index 0000000..d0bd039
--- /dev/null
+++ b/Source/Kernel/Linker/Binary.proto.h
@@ -0,0 +1,16 @@
+#ifndef DEF_BINARY_PROTO_H
+#define DEF_BINARY_PROTO_H
+
+#include <VFS/File.class.h>
+#include <TaskManager/Process.class.h>
+#include <TaskManager/Thread.class.h>
+
+class Binary {
+ public:
+ static Binary* load(File& file);
+ virtual ~Binary() {}
+
+ virtual thread_entry_t toProcess(Process* p) = 0;
+};
+
+#endif
diff --git a/Source/Kernel/Linker/MelonBinary.class.cpp b/Source/Kernel/Linker/MelonBinary.class.cpp
new file mode 100644
index 0000000..d6074de
--- /dev/null
+++ b/Source/Kernel/Linker/MelonBinary.class.cpp
@@ -0,0 +1,30 @@
+#include "MelonBinary.class.h"
+
+Binary* MelonBinary::load(File& file) {
+ u32int magic;
+ file.read<u32int>(&magic);
+ if (magic == 0xFEEDBEEF) {
+ MelonBinary* r = new MelonBinary;
+ file.read<u32int>(&r->m_size);
+ file.read<u32int>(&r->m_org);
+ r->m_data = (u8int*)Mem::kalloc(r->m_size);
+ file.read(r->m_size, r->m_data);
+ return r;
+ } else {
+ return 0;
+ }
+}
+
+MelonBinary::~MelonBinary() {
+ delete m_data;
+}
+
+thread_entry_t MelonBinary::toProcess(Process* p) {
+ if (p == 0) return 0;
+ for (u32int i = m_org; i < m_org + m_size; i += 0x1000) {
+ p->getPagedir()->allocFrame(i, true, true);
+ }
+ p->getPagedir()->switchTo();
+ memcpy((u8int*)m_org, m_data, m_size);
+ return (thread_entry_t)m_org;
+}
diff --git a/Source/Kernel/Linker/MelonBinary.class.h b/Source/Kernel/Linker/MelonBinary.class.h
new file mode 100644
index 0000000..4300c7e
--- /dev/null
+++ b/Source/Kernel/Linker/MelonBinary.class.h
@@ -0,0 +1,21 @@
+#ifndef DEF_MELONBINARY_CLASS_H
+#define DEF_MELONBINARY_CLASS_H
+
+#include <Linker/Binary.proto.h>
+
+class MelonBinary : public Binary {
+ private:
+ u32int m_size;
+ u32int m_org;
+ u8int* m_data;
+
+ MelonBinary() {}
+
+ public:
+ virtual ~MelonBinary();
+ static Binary* load(File& file);
+
+ thread_entry_t toProcess(Process* p);
+};
+
+#endif
diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile
index 118ea29..521e32a 100644
--- a/Source/Kernel/Makefile
+++ b/Source/Kernel/Makefile
@@ -43,6 +43,8 @@ Objects = Core/loader.wtf.o \
Shell/KernelShell.class.o \
Shell/KernelShell-fs.class.o \
Shell/KernelShell-sys.class.o \
+ Linker/Binary.proto.o \
+ Linker/MelonBinary.class.o \
Library/Bitset.class.o \
Library/String.class.o \
Library/ByteArray.class.o \
diff --git a/Source/Kernel/MemoryManager/Mem.ns.cpp b/Source/Kernel/MemoryManager/Mem.ns.cpp
index b2f2d59..0698a12 100644
--- a/Source/Kernel/MemoryManager/Mem.ns.cpp
+++ b/Source/Kernel/MemoryManager/Mem.ns.cpp
@@ -19,7 +19,7 @@ void *kallocInternal(u32int sz, bool align) {
u32int temp = placementAddress;
placementAddress += sz;
for (u32int i = temp; i < placementAddress; i += 0x1000) {
- if (pagingEnabled) kernelPageDirectory->allocFrame(i, true, false);
+ if (pagingEnabled) kernelPageDirectory->allocFrame(i, false, false);
}
return (void*)temp;
}
diff --git a/Source/Kernel/MemoryManager/PhysMem.ns.cpp b/Source/Kernel/MemoryManager/PhysMem.ns.cpp
index eb6fbf1..9e4b36a 100644
--- a/Source/Kernel/MemoryManager/PhysMem.ns.cpp
+++ b/Source/Kernel/MemoryManager/PhysMem.ns.cpp
@@ -19,7 +19,7 @@ void initPaging(u32int mem_size) {
u32int i = 0xC0000000;
while (i < Mem::placementAddress) {
page_t *p2 = kernelPageDirectory->getPage(i, true);
- allocFrame(p2, true, false);
+ allocFrame(p2, false, false);
i += 0x1000;
}
//Also map thoses pages at begning of virtual memory
diff --git a/Source/Kernel/Shell/KernelShell-fs.class.cpp b/Source/Kernel/Shell/KernelShell-fs.class.cpp
index b34fa7f..fe1ecbf 100644
--- a/Source/Kernel/Shell/KernelShell-fs.class.cpp
+++ b/Source/Kernel/Shell/KernelShell-fs.class.cpp
@@ -109,27 +109,14 @@ void KernelShell::run(Vector<String>& args) {
if (args.size() == 1) {
*m_vt << "No app to run !\n";
} else {
- File f(args[1], FM_READ, m_cwd);
- if (f.valid()) {
- u32int magic = 0;
- f.read<u32int>(&magic);
- if (magic == 0xFEEDBEEF) {
- u32int size;
- f.read<u32int>(&size);
- Process* p;
- p = new Process(args[1], 0);
- p->setVirtualTerminal(m_vt);
- u8int *ptr = (u8int*)p->heap().alloc(size);
- f.read(size, ptr);
- new Thread(p, (thread_entry_t)ptr, 0);
- kernelPageDirectory->switchTo();
- while (p->getState() != P_FINISHED) Task::currThread()->sleep(10);
- delete p;
- } else {
- *m_vt << "Bad magic number : " << (u32int)magic << "\n";
- }
+ Process* p = Process::run(args[1], m_cwd, 0);
+ if (p == 0) {
+ *m_vt << "Error while launching process.\n";
} else {
- *m_vt << "Unable to read from file.\n";
+ p->setVirtualTerminal(m_vt);
+ p->start();
+ while (p->getState() != P_FINISHED) Task::currThread()->sleep(10);
+ delete p;
}
}
}
diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp
index 0744e56..46e6ee2 100644
--- a/Source/Kernel/SyscallManager/IDT.ns.cpp
+++ b/Source/Kernel/SyscallManager/IDT.ns.cpp
@@ -79,7 +79,11 @@ extern "C" void interrupt_handler(registers_t regs) {
Task::currProcess()->getVirtualTerminal()->put(WChar(regs.ebx));
} else if (regs.eax == 0xFFFFFF02) {
Task::currThread()->sleep(regs.ebx);
+ } else if (regs.eax == 0xFFFFFF03) {
+ Task::currProcess()->getVirtualTerminal()->writeHex(regs.ebx);
}
+ //Some syscalls have maybee modified current page directory, set it back to one for current process
+ Task::currProcess()->getPagedir()->switchTo();
}
if (regs.int_no == 66) { //This syscall signals to kernel that thread ended.
Task::currentThreadExits(regs.eax); //DO NOT COUNT ON COMMING BACK FROM HERE
diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp
index 9fdad96..bad4e52 100644
--- a/Source/Kernel/TaskManager/Process.class.cpp
+++ b/Source/Kernel/TaskManager/Process.class.cpp
@@ -2,6 +2,7 @@
#include <TaskManager/Task.ns.h>
#include <MemoryManager/PhysMem.ns.h>
#include <VFS/File.class.h>
+#include <Linker/Binary.proto.h>
namespace Mem {
extern Heap kheap;
@@ -35,11 +36,28 @@ Process* Process::createKernel(String cmdline, VirtualTerminal *vt) {
return p;
}
+Process* Process::run(String filename, FSNode* cwd, u32int uid) {
+ File file(filename, FM_READ, cwd);
+ if (!file.valid()) return 0;
+ Binary* b = Binary::load(file);
+ if (b == 0) return 0;
+ Process* p = new Process(filename, uid);
+ thread_entry_t e = b->toProcess(p);
+ delete b;
+ if (e != 0) {
+ new Thread(p, e, 0);
+ return p;
+ } else {
+ delete p;
+ return 0;
+ }
+}
+
Process::Process(String cmdline, u32int uid) {
m_pid = Task::nextPid();
m_cmdline = cmdline;
m_retval = 0;
- m_state = P_RUNNING;
+ m_state = P_STARTING;
m_uid = uid;
m_vt = Task::currProcess()->getVirtualTerminal();
m_fileDescriptors = 0;
@@ -57,6 +75,10 @@ Process::~Process() {
delete m_userHeap;
}
+void Process::start() {
+ if (m_state == P_STARTING) m_state = P_RUNNING;
+}
+
void Process::exit() {
for (u32int i = 0; i < m_threads.size(); i++) {
delete m_threads[i];
diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h
index 73421a9..7cd78fc 100644
--- a/Source/Kernel/TaskManager/Process.class.h
+++ b/Source/Kernel/TaskManager/Process.class.h
@@ -7,10 +7,12 @@
#include <MemoryManager/PageDirectory.class.h>
#include <MemoryManager/Heap.class.h>
#include <VTManager/VirtualTerminal.proto.h>
+#include <VFS/File.class.h>
#define P_ZOMBIE 0
#define P_RUNNING 1
-#define P_FINISHED 2
+#define P_STARTING 2
+#define P_FINISHED 3
#define E_PAGEFAULT 0x0FFFFF00
#define E_ABORTED 0x0FFFFF01
@@ -45,11 +47,13 @@ class Process {
public:
static Process* createKernel(String cmdline, VirtualTerminal *vt); //Also creates a Thread for what's curently happening
+ static Process* run(String filename, FSNode* cwd, u32int uid);
Process(String cmdline, u32int uid);
~Process();
Heap& heap() { return *m_userHeap; }
+ void start(); //Starts thread execution - sets m_state to P_RUNNING if == P_STARTING
void exit(); //Exits properly process by killing all threads and deleting file descriptors
void registerThread(Thread* t); //Called when a thread starts
void threadFinishes(Thread* thread, u32int retval); //Called when a thread finishes
diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp
index 8b4845e..9a2df3f 100644
--- a/Source/Kernel/TaskManager/Thread.class.cpp
+++ b/Source/Kernel/TaskManager/Thread.class.cpp
@@ -191,6 +191,7 @@ void Thread::waitIRQ(u8int irq) {
}
bool Thread::runnable() {
+ if (m_process->getState() != P_RUNNING) return false;
if (m_state == T_RUNNING) return true;
if (m_state == T_SLEEPING and Time::time() >= waitfor.m_time) {
m_state = T_RUNNING;