From 22c06556ccbd07f4ef7da39a62d10e03fbee3fe0 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 10:34:11 +0200 Subject: Loading binaries now is done through a much more unified interface. --- Init.rfs | Bin 4081 -> 0 bytes Source/Applications/ASMApps/syscalls.asm | 11 ++++++++++ Source/Applications/ASMApps/test | Bin 62 -> 92 bytes Source/Applications/ASMApps/test.asm | 16 +++++++++++--- Source/Kernel/Linker/Binary.proto.cpp | 19 +++++++++++++++++ Source/Kernel/Linker/Binary.proto.h | 16 ++++++++++++++ Source/Kernel/Linker/MelonBinary.class.cpp | 30 +++++++++++++++++++++++++++ Source/Kernel/Linker/MelonBinary.class.h | 21 +++++++++++++++++++ Source/Kernel/Makefile | 2 ++ Source/Kernel/MemoryManager/Mem.ns.cpp | 2 +- Source/Kernel/MemoryManager/PhysMem.ns.cpp | 2 +- Source/Kernel/Shell/KernelShell-fs.class.cpp | 27 +++++++----------------- Source/Kernel/SyscallManager/IDT.ns.cpp | 4 ++++ Source/Kernel/TaskManager/Process.class.cpp | 24 ++++++++++++++++++++- Source/Kernel/TaskManager/Process.class.h | 6 +++++- Source/Kernel/TaskManager/Thread.class.cpp | 1 + 16 files changed, 154 insertions(+), 27 deletions(-) delete mode 100644 Init.rfs create mode 100644 Source/Kernel/Linker/Binary.proto.cpp create mode 100644 Source/Kernel/Linker/Binary.proto.h create mode 100644 Source/Kernel/Linker/MelonBinary.class.cpp create mode 100644 Source/Kernel/Linker/MelonBinary.class.h diff --git a/Init.rfs b/Init.rfs deleted file mode 100644 index b10aa86..0000000 Binary files a/Init.rfs and /dev/null differ diff --git a/Source/Applications/ASMApps/syscalls.asm b/Source/Applications/ASMApps/syscalls.asm index cdd5cc6..1a634d7 100644 --- a/Source/Applications/ASMApps/syscalls.asm +++ b/Source/Applications/ASMApps/syscalls.asm @@ -1,7 +1,18 @@ [bits 32] +%ifidn __OUTPUT_FORMAT__, bin + +%define MEM_ORIGIN 0x10000000 + dd 0xFEEDBEEF ; magic number ^^ dd end - start +dd MEM_ORIGIN + +; the ($-$$) permits not taking into account the header above +[org MEM_ORIGIN - ($-$$)] + +%endif %define SC_PUTCH 0xFFFFFF01 %define SC_SLEEP 0xFFFFFF02 +%define SC_WHEX 0xFFFFFF03 diff --git a/Source/Applications/ASMApps/test b/Source/Applications/ASMApps/test index 397abf1..781a4b6 100644 Binary files a/Source/Applications/ASMApps/test and b/Source/Applications/ASMApps/test differ diff --git a/Source/Applications/ASMApps/test.asm b/Source/Applications/ASMApps/test.asm index 80965b4..a79d4a3 100644 --- a/Source/Applications/ASMApps/test.asm +++ b/Source/Applications/ASMApps/test.asm @@ -1,7 +1,13 @@ %include "syscalls.asm" -start: - mov ecx, ' ' +start: ; label used for calculating app size + mov ecx, [data] + mov ebx, ecx + mov eax, SC_WHEX + int 64 + mov eax, SC_PUTCH + mov ebx, 10 + int 64 loop: inc ecx mov eax, SC_PUTCH ;temporarily defined for writing one char to screen @@ -17,4 +23,8 @@ start: mov ebx, 10 ;newline int 64 int 66 ;finish task -end: + +data: +dd 0x00000020 + +end: ; label used for calculating app size 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 + +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 +#include +#include + +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(&magic); + if (magic == 0xFEEDBEEF) { + MelonBinary* r = new MelonBinary; + file.read(&r->m_size); + file.read(&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 + +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& 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(&magic); - if (magic == 0xFEEDBEEF) { - u32int size; - f.read(&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 #include #include +#include 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 #include #include +#include #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; -- cgit v1.2.3