summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--Init.rfsbin3984 -> 0 bytes
-rw-r--r--Makefile9
-rw-r--r--Media/Screenshots/2009-10-17-225953_728x426_scrot.pngbin0 -> 17989 bytes
-rw-r--r--Media/Screenshots/2009-10-17-230014_728x426_scrot.pngbin0 -> 19788 bytes
-rw-r--r--Source/Applications/SampleApps/Makefile37
-rw-r--r--Source/Applications/SampleApps/asmdemo.asm30
-rw-r--r--Source/Applications/SampleApps/cxxdemo.cpp19
-rw-r--r--Source/Applications/SampleApps/lib-melonasm.asm24
-rw-r--r--Source/Applications/Shell/Makefile31
-rw-r--r--Source/Applications/Shell/main.cpp13
-rw-r--r--Source/Kernel/Core/Sys.ns.cpp11
-rw-r--r--Source/Kernel/Core/cppsupport.wtf.cpp2
-rw-r--r--Source/Kernel/Core/kmain.wtf.cpp8
-rw-r--r--Source/Kernel/DeviceManager/Dev.ns.h2
-rw-r--r--Source/Kernel/DeviceManager/Disp.ns.h2
-rw-r--r--Source/Kernel/DeviceManager/Kbd.ns.cpp2
-rw-r--r--Source/Kernel/DeviceManager/Kbd.ns.h4
-rw-r--r--Source/Kernel/Devices/Device.proto.h2
-rw-r--r--Source/Kernel/Devices/Display/Display.proto.h4
-rw-r--r--Source/Kernel/Devices/Floppy/FloppyController.class.h2
-rw-r--r--Source/Kernel/FileSystems/RamFS/RamFS.class.cpp8
-rw-r--r--Source/Kernel/Linker/Binary.proto.cpp21
-rw-r--r--Source/Kernel/Linker/Binary.proto.h16
-rw-r--r--Source/Kernel/Linker/ElfBinary.class.cpp55
-rw-r--r--Source/Kernel/Linker/ElfBinary.class.h68
-rw-r--r--Source/Kernel/Linker/MelonBinary.class.cpp30
-rw-r--r--Source/Kernel/Linker/MelonBinary.class.h21
-rw-r--r--Source/Kernel/Makefile28
-rw-r--r--Source/Kernel/MemoryManager/GDT.ns.cpp22
-rw-r--r--Source/Kernel/MemoryManager/GDT.ns.h34
-rw-r--r--Source/Kernel/MemoryManager/GDT.wtf.asm6
-rw-r--r--Source/Kernel/MemoryManager/Mem.ns.cpp15
-rw-r--r--Source/Kernel/MemoryManager/Mem.ns.h6
-rw-r--r--Source/Kernel/MemoryManager/PageAlloc.ns.cpp4
-rw-r--r--Source/Kernel/MemoryManager/PageAlloc.ns.h2
-rw-r--r--Source/Kernel/MemoryManager/PageDirectory.class.h2
-rw-r--r--Source/Kernel/MemoryManager/PhysMem.ns.cpp7
-rw-r--r--Source/Kernel/Ressources/Keymaps/Keymap.h2
-rwxr-xr-xSource/Kernel/Ressources/Keymaps/MakeMKM.sh4
-rw-r--r--Source/Kernel/Shell/KernelShell-fs.class.cpp22
-rw-r--r--Source/Kernel/Shell/KernelShell.class.cpp7
-rw-r--r--Source/Kernel/Shell/KernelShell.class.h3
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.cpp22
-rw-r--r--Source/Kernel/SyscallManager/IDT.ns.h2
-rw-r--r--Source/Kernel/SyscallManager/Res.ns.cpp75
-rw-r--r--Source/Kernel/SyscallManager/Res.ns.h15
-rw-r--r--Source/Kernel/SyscallManager/Ressource.class.cpp41
-rw-r--r--Source/Kernel/SyscallManager/Ressource.class.h56
-rw-r--r--Source/Kernel/TaskManager/Process.class.cpp68
-rw-r--r--Source/Kernel/TaskManager/Process.class.h30
-rw-r--r--Source/Kernel/TaskManager/Task.ns.cpp8
-rw-r--r--Source/Kernel/TaskManager/Task.ns.h2
-rw-r--r--Source/Kernel/TaskManager/Task.wtf.asm9
-rw-r--r--Source/Kernel/TaskManager/Thread.class.cpp109
-rw-r--r--Source/Kernel/TaskManager/Thread.class.h14
-rw-r--r--Source/Kernel/VFS/DirectoryNode.class.h2
-rw-r--r--Source/Kernel/VFS/FSNode-sc.proto.cpp34
-rw-r--r--Source/Kernel/VFS/FSNode.proto.h20
-rw-r--r--Source/Kernel/VFS/File.class.h2
-rw-r--r--Source/Kernel/VFS/Part.ns.h2
-rw-r--r--Source/Kernel/VTManager/SimpleVT.class.cpp2
-rw-r--r--Source/Kernel/VTManager/VT.ns.cpp2
-rw-r--r--Source/Kernel/VTManager/VT.ns.h2
-rw-r--r--Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp3
-rw-r--r--Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp46
-rw-r--r--Source/Kernel/VTManager/VirtualTerminal.proto.cpp24
-rw-r--r--Source/Kernel/VTManager/VirtualTerminal.proto.h26
-rw-r--r--Source/Kernel/common.h (renamed from Source/Kernel/Core/common.wtf.h)12
-rw-r--r--Source/Library/Common/BasicString.class.cpp (renamed from Source/Kernel/Library/BasicString.class.cpp)2
-rw-r--r--Source/Library/Common/BasicString.class.h (renamed from Source/Kernel/Library/BasicString.class.h)2
-rw-r--r--Source/Library/Common/Bitset.class.cpp (renamed from Source/Kernel/Library/Bitset.class.cpp)4
-rw-r--r--Source/Library/Common/Bitset.class.h (renamed from Source/Kernel/Library/Bitset.class.h)2
-rw-r--r--Source/Library/Common/ByteArray.class.cpp (renamed from Source/Kernel/Library/ByteArray.class.cpp)4
-rw-r--r--Source/Library/Common/ByteArray.class.h (renamed from Source/Kernel/Library/ByteArray.class.h)5
-rw-r--r--Source/Library/Common/CMem.ns.cpp (renamed from Source/Kernel/Core/CMem.ns.cpp)2
-rw-r--r--Source/Library/Common/CMem.ns.h (renamed from Source/Kernel/Core/CMem.ns.h)0
-rw-r--r--Source/Library/Common/Heap-index.class.cpp (renamed from Source/Kernel/MemoryManager/Heap-index.class.cpp)0
-rw-r--r--Source/Library/Common/Heap.class.cpp (renamed from Source/Kernel/MemoryManager/Heap.class.cpp)29
-rw-r--r--Source/Library/Common/Heap.class.h (renamed from Source/Kernel/MemoryManager/Heap.class.h)19
-rw-r--r--Source/Library/Common/Mutex.class.cpp (renamed from Source/Kernel/TaskManager/Mutex.class.cpp)19
-rw-r--r--Source/Library/Common/Mutex.class.h (renamed from Source/Kernel/TaskManager/Mutex.class.h)2
-rw-r--r--Source/Library/Common/OrderedArray.class.cpp (renamed from Source/Kernel/Library/OrderedArray.class.cpp)0
-rw-r--r--Source/Library/Common/OrderedArray.class.h (renamed from Source/Kernel/Library/OrderedArray.class.h)2
-rw-r--r--Source/Library/Common/Rand.ns.cpp (renamed from Source/Kernel/Library/Rand.ns.cpp)0
-rw-r--r--Source/Library/Common/Rand.ns.h (renamed from Source/Kernel/Library/Rand.ns.h)2
-rw-r--r--Source/Library/Common/SimpleList.class.h (renamed from Source/Kernel/Library/SimpleList.class.h)6
-rw-r--r--Source/Library/Common/String.class.cpp (renamed from Source/Kernel/Library/String.class.cpp)22
-rw-r--r--Source/Library/Common/String.class.h (renamed from Source/Kernel/Library/String.class.h)10
-rw-r--r--Source/Library/Common/Vector.class.cpp (renamed from Source/Kernel/Library/Vector.class.cpp)16
-rw-r--r--Source/Library/Common/Vector.class.h (renamed from Source/Kernel/Library/Vector.class.h)2
-rw-r--r--Source/Library/Common/WChar.class.cpp (renamed from Source/Kernel/Library/WChar.class.cpp)6
-rw-r--r--Source/Library/Common/WChar.class.h (renamed from Source/Kernel/Library/WChar.class.h)4
-rw-r--r--Source/Library/Common/types.h (renamed from Source/Kernel/Core/types.wtf.h)0
-rw-r--r--Source/Library/Interface/FSNode.iface.h14
-rw-r--r--Source/Library/Interface/Process.iface.h13
-rw-r--r--Source/Library/Interface/Thread.iface.h12
-rw-r--r--Source/Library/Interface/VirtualTerminal.iface.h21
-rw-r--r--Source/Library/Link.ld32
-rw-r--r--Source/Library/Makefile46
-rw-r--r--Source/Library/Userland/Binding/FSNode.class.h23
-rw-r--r--Source/Library/Userland/Binding/Process.class.h22
-rw-r--r--Source/Library/Userland/Binding/Thread.class.h19
-rw-r--r--Source/Library/Userland/Binding/VirtualTerminal.class.h48
-rw-r--r--Source/Library/Userland/Start.cpp36
-rw-r--r--Source/Library/Userland/Syscall/RessourceCaller.class.cpp18
-rw-r--r--Source/Library/Userland/Syscall/RessourceCaller.class.h36
-rw-r--r--Source/Library/Userland/Syscall/Syscall.wtf.cpp21
-rw-r--r--Source/Library/Userland/Syscall/Syscall.wtf.h13
-rw-r--r--Source/Library/Userland/common.h27
-rwxr-xr-xSource/Tools/MakeRamFS/MakeRamFSbin12483 -> 0 bytes
111 files changed, 1613 insertions, 163 deletions
diff --git a/.gitignore b/.gitignore
index e604120..4246a36 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,4 +1,6 @@
*.swp
*.o
+*.uo
+Init.rfs
Source/Kernel/Map.txt
Source/Kernel/Melon.ke
diff --git a/Init.rfs b/Init.rfs
deleted file mode 100644
index d3023af..0000000
--- a/Init.rfs
+++ /dev/null
Binary files differ
diff --git a/Makefile b/Makefile
index 9a7d72a..1237ef8 100644
--- a/Makefile
+++ b/Makefile
@@ -1,12 +1,15 @@
.PHONY: clean, mrproper, Init.rfs
-Projects = Kernel Tools/MakeRamFS
+Projects = Kernel Library Tools/MakeRamFS Applications/Shell Applications/SampleApps
Kernel = Source/Kernel/Melon.ke
RamFS = Init.rfs
RamFSFiles = :/System :/System/Applications :/System/Configuration :/System/Keymaps \
Source/Kernel/Ressources/Keymaps/fr.mkm:/System/Keymaps/fr.mkm \
Source/Kernel/Ressources/Texts/Welcome.txt:/Welcome.txt \
+ Source/Applications/SampleApps/asmdemo:/ad \
+ Source/Applications/SampleApps/cxxdemo:/cd \
+ Source/Applications/Shell/Shell:/shell \
:/Useless \
Source/Kernel/Ressources/Texts/Info.txt:/Useless/Info.txt \
Source/Kernel/Ressources/Graphics/logo.text.cxd:/Useless/Melon-logo
@@ -31,9 +34,9 @@ clean:
make -C Source/$$p clean -s; \
done
-mproper:
+mrproper:
for p in $(Projects); do \
- make -C Source mrproper -s; \
+ make -C Source/$$p mrproper -s; \
done
$(RamFS):
diff --git a/Media/Screenshots/2009-10-17-225953_728x426_scrot.png b/Media/Screenshots/2009-10-17-225953_728x426_scrot.png
new file mode 100644
index 0000000..7c86436
--- /dev/null
+++ b/Media/Screenshots/2009-10-17-225953_728x426_scrot.png
Binary files differ
diff --git a/Media/Screenshots/2009-10-17-230014_728x426_scrot.png b/Media/Screenshots/2009-10-17-230014_728x426_scrot.png
new file mode 100644
index 0000000..be4404c
--- /dev/null
+++ b/Media/Screenshots/2009-10-17-230014_728x426_scrot.png
Binary files differ
diff --git a/Source/Applications/SampleApps/Makefile b/Source/Applications/SampleApps/Makefile
new file mode 100644
index 0000000..a632f87
--- /dev/null
+++ b/Source/Applications/SampleApps/Makefile
@@ -0,0 +1,37 @@
+.PHONY: clean, mrproper
+
+ASM = nasm
+ASMFLAGS = -f elf
+
+CXX = g++
+CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Interface -I ../../Library/Userland -D THIS_IS_MELON_USERLAND
+
+LD = ld
+LDFLAGS = -T ../../Library/Link.ld
+
+Applications = asmdemo cxxdemo
+
+all: $(Applications)
+ echo "* Done with applications : $(Applications)"
+
+rebuild: mrproper all
+
+%: %.cpp
+ echo "* Compiling $<..."
+ $(CXX) $(CXXFLAGS) -c $< -o $@.o
+ echo "* Linking $@.o..."
+ $(LD) $(LDFLAGS) ../../Library/Melon.o $@.o -o $@
+
+%: %.asm
+ echo "* Compiling $<..."
+ $(ASM) $(ASMFLAGS) -o $@.o $<
+ echo "* Linking $@.o..."
+ $(LD) $(LDFLAGS) $@.o -o $@
+
+clean:
+ echo "* Removing object files..."
+ rm -rf *.o
+
+mrproper: clean
+ echo "* Removing applications..."
+ rm -rf $(Applications)
diff --git a/Source/Applications/SampleApps/asmdemo.asm b/Source/Applications/SampleApps/asmdemo.asm
new file mode 100644
index 0000000..3037897
--- /dev/null
+++ b/Source/Applications/SampleApps/asmdemo.asm
@@ -0,0 +1,30 @@
+%include "lib-melonasm.asm"
+
+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
+ mov ebx, ecx
+ int 64
+ mov eax, SC_SLEEP ;temporary syscall for sleeping
+ mov ebx, 30 ;20ms
+ int 64
+ cmp ecx, 127
+ jnz loop
+ mov eax, 0
+ mov eax, SC_PUTCH
+ mov ebx, 10 ;newline
+ int 64
+ int 66 ;finish task
+
+data:
+dd 0x00000020
+
+end: ; label used for calculating app size
diff --git a/Source/Applications/SampleApps/cxxdemo.cpp b/Source/Applications/SampleApps/cxxdemo.cpp
new file mode 100644
index 0000000..01644a8
--- /dev/null
+++ b/Source/Applications/SampleApps/cxxdemo.cpp
@@ -0,0 +1,19 @@
+#include <Syscall/Syscall.wtf.h>
+#include <WChar.class.h>
+#include <Binding/VirtualTerminal.class.h>
+#include <Binding/Thread.class.h>
+
+int main() {
+ VirtualTerminal x = VirtualTerminal::get();
+ String s = x.readLine();
+ x.write(s);
+ Thread t = Thread::get();
+ for (char c = ' '; c <= 'z'; c++) {
+ t.sleep((u32int)c / 4);
+ x.put(c);
+ }
+ x.put("\n");
+ x.write("Salut les gens ! c'est le progrès !!!\nLe boeuf mort est juste là : ");
+ x.writeHex(0xDEADBEEF);
+ x.put("\n");
+}
diff --git a/Source/Applications/SampleApps/lib-melonasm.asm b/Source/Applications/SampleApps/lib-melonasm.asm
new file mode 100644
index 0000000..0845770
--- /dev/null
+++ b/Source/Applications/SampleApps/lib-melonasm.asm
@@ -0,0 +1,24 @@
+[bits 32]
+
+%ifidn __OUTPUT_FORMAT__, bin
+; create a MelonBinary output
+
+%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 - ($-$$)]
+
+%elifidn __OUTPUT_FORMAT__, elf
+; create an elf object
+
+[global start]
+
+%endif
+
+%define SC_PUTCH 0xFFFFFF01
+%define SC_SLEEP 0xFFFFFF02
+%define SC_WHEX 0xFFFFFF03
diff --git a/Source/Applications/Shell/Makefile b/Source/Applications/Shell/Makefile
new file mode 100644
index 0000000..205fc2f
--- /dev/null
+++ b/Source/Applications/Shell/Makefile
@@ -0,0 +1,31 @@
+.PHONY: clean, mrproper
+
+CXX = g++
+CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Interface -I ../../Library/Userland -D THIS_IS_MELON_USERLAND
+
+LD = ld
+LDFLAGS = -T ../../Library/Link.ld
+
+Objects = main.o
+OutFile = Shell
+
+all: $(OutFile)
+ echo "* Done with $(OutFile)."
+
+rebuild: mrproper all
+
+$(OutFile): $(Objects)
+ echo "* Linking $@.o..."
+ $(LD) $(LDFLAGS) ../../Library/Melon.o $^ -o $@
+
+%.o: %.cpp
+ echo "* Compiling $<..."
+ $(CXX) $(CXXFLAGS) -c $< -o $@
+
+clean:
+ echo "* Removing object files..."
+ rm -rf *.o
+
+mrproper: clean
+ echo "* Removing applications..."
+ rm -rf $(OutFile)
diff --git a/Source/Applications/Shell/main.cpp b/Source/Applications/Shell/main.cpp
new file mode 100644
index 0000000..fabf30c
--- /dev/null
+++ b/Source/Applications/Shell/main.cpp
@@ -0,0 +1,13 @@
+#include <Binding/VirtualTerminal.class.h>
+#include <Binding/FSNode.class.h>
+#include <String.class.h>
+
+int main() {
+ VirtualTerminal vt = VirtualTerminal::get();
+ FSNode node = FSNode::getRoot();
+ while (1) {
+ vt << node.getName() << " : ";
+ String s = vt.readLine();
+ }
+ return 0;
+}
diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp
index c0218d8..c99544b 100644
--- a/Source/Kernel/Core/Sys.ns.cpp
+++ b/Source/Kernel/Core/Sys.ns.cpp
@@ -1,5 +1,5 @@
//This automatically includes Sys.ns.h
-#include <Core/common.wtf.h>
+#include <common.h>
#include <Core/Log.ns.h>
#include <VTManager/SimpleVT.class.h>
#include <SyscallManager/IDT.ns.h>
@@ -93,7 +93,14 @@ void panic(char *message, registers_t *regs, char *file, u32int line) {
vt << "eax=" << (u32int)regs->eax << ", ebx=" << (u32int)regs->ebx << ", ecx=" << (u32int)regs->ecx <<
", edx=" << (u32int)regs->edx << "\n";
vt << "int_no=" << (s32int)regs->int_no << ", err_code=" << (u32int)regs->err_code << "\n";
- vt << "eflags=" << (u32int)regs->eflags << ", useresp=" << (u32int)regs->useresp << ", ss=" << (u32int)regs->ss << "\n\n";
+ vt << "eflags=" << (u32int)regs->eflags << ", useresp=" << (u32int)regs->useresp << ", ss=" << (u32int)regs->ss << "\n";
+ if (regs->int_no == 14) {
+ u32int cr2;
+ asm volatile("mov %%cr2, %0" : "=r"(cr2));
+ vt << "cr2=" << (u32int)cr2 << "\n";
+ }
+ vt << "\n";
+
while (1) asm volatile("cli; hlt");
u32int *v = (u32int*)regs->ebp;
diff --git a/Source/Kernel/Core/cppsupport.wtf.cpp b/Source/Kernel/Core/cppsupport.wtf.cpp
index bad28f2..2cefc39 100644
--- a/Source/Kernel/Core/cppsupport.wtf.cpp
+++ b/Source/Kernel/Core/cppsupport.wtf.cpp
@@ -1,5 +1,5 @@
//This file just contains a few methods required for some C++ things to work
-#include <Core/types.wtf.h>
+#include <types.h>
extern "C" void __cxa_pure_virtual() {} //Required when using abstract classes
diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp
index c7b47e1..a8fb002 100644
--- a/Source/Kernel/Core/kmain.wtf.cpp
+++ b/Source/Kernel/Core/kmain.wtf.cpp
@@ -1,6 +1,6 @@
//This file contains the kernel's main procedure
-#include <Core/common.wtf.h>
+#include <common.h>
#include <Core/multiboot.wtf.h>
#include <Devices/Display/VGATextOutput.class.h>
@@ -18,8 +18,8 @@
#include <MemoryManager/GDT.ns.h>
#include <TaskManager/Task.ns.h>
#include <SyscallManager/IDT.ns.h>
-#include <Library/String.class.h>
-#include <Library/ByteArray.class.h>
+#include <String.class.h>
+#include <ByteArray.class.h>
#include <VFS/Part.ns.h>
#include <FileSystems/RamFS/RamFS.class.h>
#include <VFS/FileNode.class.h>
@@ -169,7 +169,7 @@ void kmain(multiboot_info_t* mbd, u32int magic) {
new KernelShell(cwd); //No need to save that in a var, it is automatically destroyed anyways
Log::log(KL_STATUS, "kmain : Kernel shell launched");
- kvt->unmap();
+ //kvt->unmap();
while (KernelShell::getInstances() > 0) {
Task::currThread()->sleep(100);
diff --git a/Source/Kernel/DeviceManager/Dev.ns.h b/Source/Kernel/DeviceManager/Dev.ns.h
index 7dda56b..aa52e81 100644
--- a/Source/Kernel/DeviceManager/Dev.ns.h
+++ b/Source/Kernel/DeviceManager/Dev.ns.h
@@ -2,7 +2,7 @@
#define DEF_DEV_NS_H
#include <Devices/Device.proto.h>
-#include <Library/Vector.class.h>
+#include <Vector.class.h>
namespace Dev {
void handleIRQ(registers_t regs, int irq);
diff --git a/Source/Kernel/DeviceManager/Disp.ns.h b/Source/Kernel/DeviceManager/Disp.ns.h
index 5a92e69..0eea51d 100644
--- a/Source/Kernel/DeviceManager/Disp.ns.h
+++ b/Source/Kernel/DeviceManager/Disp.ns.h
@@ -2,7 +2,7 @@
#define DEF_DISP_NS_H
#include <Devices/Display/Display.proto.h>
-#include <Library/WChar.class.h>
+#include <WChar.class.h>
namespace Disp {
struct mode_t {
diff --git a/Source/Kernel/DeviceManager/Kbd.ns.cpp b/Source/Kernel/DeviceManager/Kbd.ns.cpp
index 3db0d34..4fbf511 100644
--- a/Source/Kernel/DeviceManager/Kbd.ns.cpp
+++ b/Source/Kernel/DeviceManager/Kbd.ns.cpp
@@ -1,6 +1,6 @@
#include "Kbd.ns.h"
#include <DeviceManager/Dev.ns.h>
-#include <Library/Vector.class.h>
+#include <Vector.class.h>
#include <Devices/Keyboard/Keyboard.proto.h>
#include <VTManager/VirtualTerminal.proto.h>
#include <Ressources/Keymaps/Keymap.h>
diff --git a/Source/Kernel/DeviceManager/Kbd.ns.h b/Source/Kernel/DeviceManager/Kbd.ns.h
index 50cd746..2934474 100644
--- a/Source/Kernel/DeviceManager/Kbd.ns.h
+++ b/Source/Kernel/DeviceManager/Kbd.ns.h
@@ -1,8 +1,8 @@
#ifndef DEF_KBD_NS_H
#define DEF_KBD_NS_H
-#include <Core/common.wtf.h>
-#include <Library/WChar.class.h>
+#include <common.h>
+#include <WChar.class.h>
//Used by variable kbdstatus
#define STATUS_SCRL 0x40
diff --git a/Source/Kernel/Devices/Device.proto.h b/Source/Kernel/Devices/Device.proto.h
index 4f216ec..b0db514 100644
--- a/Source/Kernel/Devices/Device.proto.h
+++ b/Source/Kernel/Devices/Device.proto.h
@@ -1,7 +1,7 @@
#ifndef DEF_DEVICE_PROTO_H
#define DEF_DEVICE_PROTO_H
-#include <Library/String.class.h>
+#include <String.class.h>
#include <SyscallManager/IDT.ns.h>
diff --git a/Source/Kernel/Devices/Display/Display.proto.h b/Source/Kernel/Devices/Display/Display.proto.h
index d4bd8fc..2cec616 100644
--- a/Source/Kernel/Devices/Display/Display.proto.h
+++ b/Source/Kernel/Devices/Display/Display.proto.h
@@ -1,9 +1,9 @@
#ifndef DEF_DISPLAY_PROTO_H
#define DEF_DISPLAY_PROTO_H
-#include <Core/common.wtf.h>
+#include <common.h>
#include <Devices/Device.proto.h>
-#include <Library/WChar.class.h>
+#include <WChar.class.h>
class Display : public Device {
public:
diff --git a/Source/Kernel/Devices/Floppy/FloppyController.class.h b/Source/Kernel/Devices/Floppy/FloppyController.class.h
index 2d0104b..a27d853 100644
--- a/Source/Kernel/Devices/Floppy/FloppyController.class.h
+++ b/Source/Kernel/Devices/Floppy/FloppyController.class.h
@@ -2,7 +2,7 @@
#define DEF_FLOPPYCONTROLLER_CLASS_H
#include <Devices/Device.proto.h>
-#include <TaskManager/Mutex.class.h>
+#include <Mutex.class.h>
#define FLOPPY_DMALEN 0x4800 //This is one cylinder
diff --git a/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp b/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp
index a224bf8..5997841 100644
--- a/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp
+++ b/Source/Kernel/FileSystems/RamFS/RamFS.class.cpp
@@ -112,11 +112,11 @@ bool RamFS::write(FileNode* file, u64int position, u32int length, u8int *data) {
m_usedSize -= node->getLength();
m_usedSize += end;
- u8int* data = (u8int*)Mem::kalloc(end);
+ u8int* data = (u8int*)Mem::alloc(end);
if (data == 0) return false; //Invalid pointer
if (node->m_data != 0) {
memcpy(data, node->m_data, node->getLength());
- Mem::kfree(node->m_data);
+ Mem::free(node->m_data);
}
node->m_data = data;
node->setLength(end);
@@ -129,7 +129,7 @@ bool RamFS::truncate(FileNode* file) {
if (!m_isWritable) return false;
RamFileNode *node = (RamFileNode*) file;
- Mem::kfree(node->m_data);
+ Mem::free(node->m_data);
node->setLength(0);
node->m_data = 0;
@@ -163,7 +163,7 @@ DirectoryNode* RamFS::createDirectory(DirectoryNode* parent, String name) {
bool RamFS::remove(DirectoryNode* parent, FSNode* node) {
if (node->type() == NT_FILE) {
u8int *d = ((RamFileNode*)node)->m_data;
- if (d != 0) Mem::kfree(d);
+ if (d != 0) Mem::free(d);
}
return true;
}
diff --git a/Source/Kernel/Linker/Binary.proto.cpp b/Source/Kernel/Linker/Binary.proto.cpp
new file mode 100644
index 0000000..c0345da
--- /dev/null
+++ b/Source/Kernel/Linker/Binary.proto.cpp
@@ -0,0 +1,21 @@
+#include "Binary.proto.h"
+
+#include <Linker/MelonBinary.class.h>
+#include <Linker/ElfBinary.class.h>
+
+Binary* (*loaders[])(File& file) = {
+ &MelonBinary::load,
+ &ElfBinary::load,
+0 };
+
+Binary* Binary::load(File& file) {
+ Binary* r = 0;
+ u32int i = 0;
+ while (loaders[i] != 0) {
+ file.seek(0, SM_BEGINNING);
+ 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/ElfBinary.class.cpp b/Source/Kernel/Linker/ElfBinary.class.cpp
new file mode 100644
index 0000000..27e5474
--- /dev/null
+++ b/Source/Kernel/Linker/ElfBinary.class.cpp
@@ -0,0 +1,55 @@
+#include "ElfBinary.class.h"
+#include <TaskManager/Task.ns.h>
+
+ElfBinary::~ElfBinary() {
+ for (SimpleList<phdr_t> *iter = m_phdr; iter != 0; iter = iter->next()) {
+ delete iter->v().data;
+ }
+}
+
+Binary* ElfBinary::load(File& file) {
+ elf_ehdr_t hdr;
+ file.read<elf_ehdr_t> (&hdr);
+ //Verify we have an elf file
+ if (hdr.e_ident[0] != 0x7F or hdr.e_ident[1] != 'E' or hdr.e_ident[2] != 'L' or hdr.e_ident[3] != 'F') return 0;
+
+ //Store elf header into a new ElfBinary
+ ElfBinary* b = new ElfBinary();
+ memcpy((u8int*)&b->m_ehdr, (const u8int*) &hdr, sizeof(elf_ehdr_t));
+ b->m_phdr = 0;
+
+ //Load program headers
+ file.seek(hdr.e_phoff, SM_BEGINNING);
+ for (u32int i = 0; i < hdr.e_phnum; i++) {
+ b->m_phdr = b->m_phdr->cons(phdr_t());
+ file.read<elf_phdr_t>(&b->m_phdr->v().h); //Load current entry from file
+ }
+ //Load data
+ for (SimpleList<phdr_t> *iter = b->m_phdr; iter != 0; iter = iter->next()) {
+ iter->v().data = (u8int*)Mem::alloc(iter->v().h.p_filesz);
+ file.seek(iter->v().h.p_offset, SM_BEGINNING);
+ file.read(iter->v().h.p_filesz, iter->v().data);
+ }
+
+ return b;
+}
+
+thread_entry_t ElfBinary::toProcess(Process* p) {
+ for (SimpleList<phdr_t> *iter = m_phdr; iter != 0; iter = iter->next()) {
+ phdr_t &e = iter->v();
+ if (e.h.p_type == PT_LOAD) {
+ for (u32int i = e.h.p_vaddr; i < e.h.p_vaddr + e.h.p_memsz; i += 0x1000) {
+ p->getPagedir()->allocFrame(i, true, true);
+ }
+ p->getPagedir()->switchTo();
+ memcpy((u8int*)e.h.p_vaddr, (const u8int*)e.data, e.h.p_filesz);
+ if (e.h.p_memsz > e.h.p_filesz) { //set to zero all the remaining space
+ u8int* x = (u8int*)e.h.p_vaddr;
+ for (u32int i = e.h.p_vaddr + e.h.p_filesz; i < e.h.p_filesz; i++) {
+ x[i] = 0;
+ }
+ }
+ }
+ }
+ return (thread_entry_t)m_ehdr.e_entry;
+}
diff --git a/Source/Kernel/Linker/ElfBinary.class.h b/Source/Kernel/Linker/ElfBinary.class.h
new file mode 100644
index 0000000..1fb9929
--- /dev/null
+++ b/Source/Kernel/Linker/ElfBinary.class.h
@@ -0,0 +1,68 @@
+#ifndef DEF_ELFBINARY_CLASS_H
+#define DEF_ELFBINARY_CLASS_H
+
+#include <Linker/Binary.proto.h>
+#include <SimpleList.class.h>
+
+/* p_type */
+#define PT_NULL 0
+#define PT_LOAD 1
+#define PT_DYNAMIC 2
+#define PT_INTERP 3
+#define PT_NOTE 4
+#define PT_SHLIB 5
+#define PT_PHDR 6
+#define PT_LOPROC 0x70000000
+#define PT_HIPROC 0x7fffffff
+
+struct elf_ehdr_t {
+ u8int e_ident[16]; /* ELF identification */
+ u16int e_type; /* 2 (exec file) */
+ u16int e_machine; /* 3 (intel architecture) */
+ u32int e_version; /* 1 */
+ u32int e_entry; /* starting point */
+ u32int e_phoff; /* program header table offset */
+ u32int e_shoff; /* section header table offset */
+ u32int e_flags; /* various flags */
+ u16int e_ehsize; /* ELF header (this) size */
+
+ u16int e_phentsize; /* program header table entry size */
+ u16int e_phnum; /* number of entries */
+
+ u16int e_shentsize; /* section header table entry size */
+ u16int e_shnum; /* number of entries */
+
+ u16int e_shstrndx; /* index of the section name string table */
+};
+
+struct elf_phdr_t {
+ u32int p_type; /* type of segment */
+ u32int p_offset;
+ u32int p_vaddr;
+ u32int p_paddr;
+ u32int p_filesz;
+ u32int p_memsz;
+ u32int p_flags;
+ u32int p_align;
+};
+
+struct phdr_t {
+ elf_phdr_t h;
+ u8int* data;
+};
+
+class ElfBinary : public Binary {
+ private:
+ elf_ehdr_t m_ehdr;
+ SimpleList<phdr_t> *m_phdr;
+
+ ElfBinary() {}
+
+ public:
+ virtual ~ElfBinary();
+ static Binary* load(File& file);
+
+ thread_entry_t toProcess(Process* p);
+};
+
+#endif
diff --git a/Source/Kernel/Linker/MelonBinary.class.cpp b/Source/Kernel/Linker/MelonBinary.class.cpp
new file mode 100644
index 0000000..0737b71
--- /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::alloc(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 56754d0..55c5fb0 100644
--- a/Source/Kernel/Makefile
+++ b/Source/Kernel/Makefile
@@ -5,7 +5,7 @@ CXX = g++
LD = ld
LDFLAGS = -T Link.ld -Map Map.txt --oformat=elf32-i386
CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -fno-builtin -fno-stack-protector -Wall -Wextra -Werror -I .
-CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON -D RANDOM_SEED=1`date +%N`LL
+CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -I ../Library/Common -I ../Library/Interface -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON_KERNEL -D RANDOM_SEED=1`date +%N`LL -g
ASM = nasm
ASMFLAGS = -f elf
@@ -14,11 +14,8 @@ Objects = Core/loader.wtf.o \
Core/kmain.wtf.o \
Core/cppsupport.wtf.o \
Core/Sys.ns.o \
- Core/CMem.ns.o \
Core/Log.ns.o \
MemoryManager/Mem.ns.o \
- MemoryManager/Heap.class.o \
- MemoryManager/Heap-index.class.o \
MemoryManager/PhysMem.ns.o \
MemoryManager/GDT.wtf.o \
MemoryManager/GDT.ns.o \
@@ -32,30 +29,40 @@ Objects = Core/loader.wtf.o \
TaskManager/Thread.class.o \
TaskManager/Task.ns.o \
TaskManager/Task.wtf.o \
- TaskManager/Mutex.class.o \
VTManager/VirtualTerminal.proto.o \
VTManager/SimpleVT.class.o \
VTManager/ScrollableVT.class.o \
VTManager/PipeVT.class.o \
VTManager/FileVT.class.o \
VTManager/VirtualTerminal-kbd.proto.o \
+ VTManager/VirtualTerminal-sc.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 \
- Library/WChar.class.o \
- Library/Rand.ns.o \
+ Linker/Binary.proto.o \
+ Linker/MelonBinary.class.o \
+ Linker/ElfBinary.class.o \
+ ../Library/Common/Bitset.class.o \
+ ../Library/Common/String.class.o \
+ ../Library/Common/ByteArray.class.o \
+ ../Library/Common/WChar.class.o \
+ ../Library/Common/Rand.ns.o \
+ ../Library/Common/CMem.ns.o \
+ ../Library/Common/Heap.class.o \
+ ../Library/Common/Heap-index.class.o \
+ ../Library/Common/Mutex.class.o \
VFS/Partition.class.o \
VFS/Part.ns.o \
VFS/VFS.ns.o \
+ VFS/FSNode-sc.proto.o \
VFS/File.class.o \
VFS/TextFile.class.o \
VFS/DirectoryNode.class.o \
FileSystems/RamFS/RamFS.class.o \
SyscallManager/IDT.ns.o \
+ SyscallManager/Ressource.class.o \
+ SyscallManager/Res.ns.o \
SyscallManager/IDT.wtf.o \
Devices/Display/VGATextOutput.class.o \
Devices/Keyboard/PS2Keyboard.class.o \
@@ -89,6 +96,7 @@ clean:
rm -rf *.o
rm -rf */*.o
rm -rf */*/*.o
+ rm -rf ../Library/Common/*.o
mrproper: clean
echo "* Removing executable : $(OutFile)"
diff --git a/Source/Kernel/MemoryManager/GDT.ns.cpp b/Source/Kernel/MemoryManager/GDT.ns.cpp
index 0bb606d..f1f5c94 100644
--- a/Source/Kernel/MemoryManager/GDT.ns.cpp
+++ b/Source/Kernel/MemoryManager/GDT.ns.cpp
@@ -1,6 +1,9 @@
#include "GDT.ns.h"
extern "C" void gdt_flush(u32int);
+extern "C" void tss_flush();
+
+using namespace CMem; //For memset
#define GDT_ENTRIES 6
@@ -8,6 +11,7 @@ namespace GDT {
gdt_entry_t gdt_entries[GDT_ENTRIES];
gdt_ptr_t gdt_ptr;
+tss_entry_t tss_entry;
void setGate(s32int num, u32int base, u32int limit, u8int access, u8int gran) {
gdt_entries[num].base_low = (base & 0xFFFF);
@@ -20,6 +24,22 @@ void setGate(s32int num, u32int base, u32int limit, u8int access, u8int gran) {
gdt_entries[num].access = access;
}
+void writeTSS(s32int num, u16int ss0, u32int esp0) {
+ u32int base = (u32int)&tss_entry;
+ u32int limit = base + sizeof(tss_entry);
+
+ setGate(num, base, limit, 0xE9, 0x00);
+
+ memset((u8int*)&tss_entry, 0, sizeof(tss_entry_t));
+
+ tss_entry.ss0 = ss0;
+ tss_entry.esp0 = esp0;
+
+ tss_entry.cs = 0x0B; //0x0B = Kernel code segment + RPL=3 (meaning it is supposed to be called from user mode)
+ //0x13 = Kernel data segment + RPL=3 (meaning to be called from ring3)
+ tss_entry.ss = tss_entry.ds = tss_entry.es = tss_entry.fs = tss_entry.gs = 0x13;
+}
+
void init() {
gdt_ptr.limit = (sizeof(gdt_entry_t) * GDT_ENTRIES) - 1;
gdt_ptr.base = (u32int)&gdt_entries;
@@ -29,8 +49,10 @@ void init() {
setGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); //Kernel data segment
setGate(3, 0, 0xFFFFFFFF, 0xFA, 0xCF); //User code segment
setGate(4, 0, 0xFFFFFFFF, 0xF2, 0xCF); //User data segment
+ writeTSS(5, 0x10, 0x0);
gdt_flush((u32int)&gdt_ptr);
+ tss_flush();
}
}
diff --git a/Source/Kernel/MemoryManager/GDT.ns.h b/Source/Kernel/MemoryManager/GDT.ns.h
index 7a9f95f..9505433 100644
--- a/Source/Kernel/MemoryManager/GDT.ns.h
+++ b/Source/Kernel/MemoryManager/GDT.ns.h
@@ -1,7 +1,7 @@
#ifndef DEF_GDT_NS_H
#define DEF_GDT_NS_H
-#include <Core/common.wtf.h>
+#include <common.h>
namespace GDT {
struct gdt_entry_t {
@@ -13,12 +13,44 @@ namespace GDT {
u8int base_high;
} __attribute__((packed));
+ // A struct describing a Task State Segment.
+ struct tss_entry_t {
+ u32int prev_tss; // The previous TSS - if we used hardware task switching this would form a linked list.
+ u32int esp0; // The stack pointer to load when we change to kernel mode.
+ u32int ss0; // The stack segment to load when we change to kernel mode.
+ u32int esp1; // Unused...
+ u32int ss1;
+ u32int esp2;
+ u32int ss2;
+ u32int cr3;
+ u32int eip;
+ u32int eflags;
+ u32int eax;
+ u32int ecx;
+ u32int edx;
+ u32int ebx;
+ u32int esp;
+ u32int ebp;
+ u32int esi;
+ u32int edi;
+ u32int es; // The value to load into ES when we change to kernel mode.
+ u32int cs; // The value to load into CS when we change to kernel mode.
+ u32int ss; // The value to load into SS when we change to kernel mode.
+ u32int ds; // The value to load into DS when we change to kernel mode.
+ u32int fs; // The value to load into FS when we change to kernel mode.
+ u32int gs; // The value to load into GS when we change to kernel mode.
+ u32int ldt; // Unused...
+ u16int trap;
+ u16int iomap_base;
+ } __attribute__((packed));
+
struct gdt_ptr_t {
u16int limit;
u32int base;
} __attribute__((packed));
void init();
+ extern tss_entry_t tss_entry; //Used for setting kernel stack
}
#endif
diff --git a/Source/Kernel/MemoryManager/GDT.wtf.asm b/Source/Kernel/MemoryManager/GDT.wtf.asm
index eb216ed..beb668d 100644
--- a/Source/Kernel/MemoryManager/GDT.wtf.asm
+++ b/Source/Kernel/MemoryManager/GDT.wtf.asm
@@ -15,3 +15,9 @@ gdt_flush:
.flush:
ret
+
+[GLOBAL tss_flush]
+tss_flush:
+ mov ax, 0x2B ;entry 5 = 0x28, with RPL=3
+ ltr ax
+ ret
diff --git a/Source/Kernel/MemoryManager/Mem.ns.cpp b/Source/Kernel/MemoryManager/Mem.ns.cpp
index b2f2d59..144b9f3 100644
--- a/Source/Kernel/MemoryManager/Mem.ns.cpp
+++ b/Source/Kernel/MemoryManager/Mem.ns.cpp
@@ -1,6 +1,7 @@
-#include <Core/common.wtf.h>
+#include <common.h>
#include <MemoryManager/PhysMem.ns.h>
-#include <MemoryManager/Heap.class.h>
+#include <TaskManager/Task.ns.h>
+#include <Heap.class.h>
namespace Mem {
@@ -19,7 +20,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;
}
@@ -39,17 +40,21 @@ void createHeap() {
kheap.create(heapStart, heapSize, heapIndexSize, kernelPageDirectory, false, false);
}
-void *kalloc(u32int sz, bool align) {
+void *alloc(u32int sz, bool align) {
if (!kheap.usable()) return kallocInternal(sz, align);
if (align) return 0;
return kheap.alloc(sz);
}
-void kfree(void *ptr) {
+void free(void *ptr) {
kheap.free(ptr);
}
+void* mkXchgSpace(u32int sz) {
+ return Task::currThread()->mkXchgSpace(sz);
+}
+
u32int kheapSize() {
return kheap.size();
}
diff --git a/Source/Kernel/MemoryManager/Mem.ns.h b/Source/Kernel/MemoryManager/Mem.ns.h
index 15935c0..b06ab79 100644
--- a/Source/Kernel/MemoryManager/Mem.ns.h
+++ b/Source/Kernel/MemoryManager/Mem.ns.h
@@ -8,8 +8,10 @@ namespace Mem {
extern u32int placementAddress;
void createHeap();
- void *kalloc(u32int sz, bool align = false);
- void kfree(void *ptr);
+ void *alloc(u32int sz, bool align = false);
+ void free(void *ptr);
+
+ void* mkXchgSpace(u32int sz); //This creates a space between userland and kernel land where data can be exchanged
u32int kheapSize(), kheapFree();
}
diff --git a/Source/Kernel/MemoryManager/PageAlloc.ns.cpp b/Source/Kernel/MemoryManager/PageAlloc.ns.cpp
index 34d4f74..d8ede2a 100644
--- a/Source/Kernel/MemoryManager/PageAlloc.ns.cpp
+++ b/Source/Kernel/MemoryManager/PageAlloc.ns.cpp
@@ -14,7 +14,7 @@ bool usable = false, locked = false;
void init() {
freec = CACHED_PAGES;
for (u32int i = 0; i < CACHED_PAGES; i++) {
- freePage[i] = Mem::kalloc(0x1000, true);
+ freePage[i] = Mem::alloc(0x1000, true);
}
usable = true;
}
@@ -26,7 +26,7 @@ void* alloc(u32int* phys) {
locked = true;
void* next = 0;
if (!Mem::pagingEnabled) {
- next = Mem::kalloc(0x1000, true);
+ next = Mem::alloc(0x1000, true);
} else {
u32int i = 0xFFFFF000;
page_t *p;
diff --git a/Source/Kernel/MemoryManager/PageAlloc.ns.h b/Source/Kernel/MemoryManager/PageAlloc.ns.h
index 894defa..d0b376a 100644
--- a/Source/Kernel/MemoryManager/PageAlloc.ns.h
+++ b/Source/Kernel/MemoryManager/PageAlloc.ns.h
@@ -1,7 +1,7 @@
#ifndef DEF_PAGEALLOC_NS_H
#define DEF_PAGEALLOC_NS_H
-#include <Core/common.wtf.h>
+#include <common.h>
namespace PageAlloc {
void init();
diff --git a/Source/Kernel/MemoryManager/PageDirectory.class.h b/Source/Kernel/MemoryManager/PageDirectory.class.h
index e06b546..14b78ca 100644
--- a/Source/Kernel/MemoryManager/PageDirectory.class.h
+++ b/Source/Kernel/MemoryManager/PageDirectory.class.h
@@ -1,7 +1,7 @@
#ifndef DEF_PAGEDIRECTORY_CLASS_H
#define DEF_PAGEDIRECTORY_CLASS_H
-#include <Core/common.wtf.h>
+#include <common.h>
struct page_t {
u32int present : 1;
diff --git a/Source/Kernel/MemoryManager/PhysMem.ns.cpp b/Source/Kernel/MemoryManager/PhysMem.ns.cpp
index 382e8a4..1b40e88 100644
--- a/Source/Kernel/MemoryManager/PhysMem.ns.cpp
+++ b/Source/Kernel/MemoryManager/PhysMem.ns.cpp
@@ -1,5 +1,5 @@
#include "PhysMem.ns.h"
-#include <Library/Bitset.class.h>
+#include <Bitset.class.h>
#include <VTManager/VirtualTerminal.proto.h>
PageDirectory* kernelPageDirectory;
@@ -14,12 +14,12 @@ void initPaging(u32int mem_size) {
frames = new Bitset(nframes);
- kernelPageDirectory = new (Mem::kalloc(sizeof(PageDirectory), true)) PageDirectory();
+ kernelPageDirectory = new (Mem::alloc(sizeof(PageDirectory), true)) PageDirectory();
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
@@ -28,7 +28,6 @@ void initPaging(u32int mem_size) {
kernelPageDirectory->tables[i] = kernelPageDirectory->tables[768 + i];
}
DEBUG_HEX((u32int)kernelPageDirectory->physicalAddr); DEBUG(" is page dir phys addr.");
- //asm volatile("hlt");
kernelPageDirectory->switchTo();
DEBUG("Paging enabled !");
diff --git a/Source/Kernel/Ressources/Keymaps/Keymap.h b/Source/Kernel/Ressources/Keymaps/Keymap.h
index 304e52c..9d1079d 100644
--- a/Source/Kernel/Ressources/Keymaps/Keymap.h
+++ b/Source/Kernel/Ressources/Keymaps/Keymap.h
@@ -1,4 +1,4 @@
-#include <Library/WChar.class.h>
+#include <WChar.class.h>
struct melon_keymap_t {
WChar normal[128];
diff --git a/Source/Kernel/Ressources/Keymaps/MakeMKM.sh b/Source/Kernel/Ressources/Keymaps/MakeMKM.sh
index ac54ce8..056abe2 100755
--- a/Source/Kernel/Ressources/Keymaps/MakeMKM.sh
+++ b/Source/Kernel/Ressources/Keymaps/MakeMKM.sh
@@ -7,11 +7,11 @@
for KM in `ls | grep cxd`; do
echo "#define THIS_IS_NOT_MELON" > kmtemp.cpp
echo "#include <cstring>" >> kmtemp.cpp
- echo "#include <Library/WChar.class.cpp>" >> kmtemp.cpp
+ echo "#include <WChar.class.cpp>" >> kmtemp.cpp
echo "#include \"$KM\"" >> kmtemp.cpp
cat WriteKeymap.cpp >> kmtemp.cpp
- g++ kmtemp.cpp -o kmtemp -I ../..
+ g++ kmtemp.cpp -o kmtemp -I ../../../Library/Common
./kmtemp
done
diff --git a/Source/Kernel/Shell/KernelShell-fs.class.cpp b/Source/Kernel/Shell/KernelShell-fs.class.cpp
index 3ac7b20..cd52810 100644
--- a/Source/Kernel/Shell/KernelShell-fs.class.cpp
+++ b/Source/Kernel/Shell/KernelShell-fs.class.cpp
@@ -1,6 +1,8 @@
#include "KernelShell.class.h"
#include <VFS/VFS.ns.h>
#include <VFS/File.class.h>
+#include <TaskManager/Task.ns.h>
+#include <MemoryManager/PhysMem.ns.h>
void KernelShell::ls(Vector<String>& args) {
DirectoryNode* d = m_cwd;
@@ -53,11 +55,11 @@ void KernelShell::cat(Vector<String>& args) {
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);
+ u8int *buff = (u8int*)Mem::alloc(f.length() + 1);
f.read(f.length(), buff);
buff[f.length()] = 0;
*m_vt << String((const char*) buff);
- Mem::kfree(buff);
+ Mem::free(buff);
} else {
*m_vt << "Error reading from file " << args[i] << "\n";
}
@@ -102,3 +104,19 @@ void KernelShell::wf(Vector<String>& args) {
}
}
}
+
+void KernelShell::run(Vector<String>& args) {
+ if (args.size() == 1) {
+ *m_vt << "No app to run !\n";
+ } else {
+ Process* p = Process::run(args[1], m_cwd, 0);
+ if (p == 0) {
+ *m_vt << "Error while launching process.\n";
+ } else {
+ p->setVirtualTerminal(m_vt);
+ p->start();
+ while (p->getState() != P_FINISHED) Task::currThread()->sleep(10);
+ delete p;
+ }
+ }
+}
diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp
index e2fbb69..d90fc4c 100644
--- a/Source/Kernel/Shell/KernelShell.class.cpp
+++ b/Source/Kernel/Shell/KernelShell.class.cpp
@@ -1,9 +1,10 @@
#include "KernelShell.class.h"
#include <VTManager/ScrollableVT.class.h>
#include <DeviceManager/Kbd.ns.h>
-#include <Library/Rand.ns.h>
-#include <Library/SimpleList.class.h>
+#include <SimpleList.class.h>
+#include <MemoryManager/PhysMem.ns.h>
#include <VFS/VFS.ns.h>
+#include <TaskManager/Task.ns.h>
u32int KernelShell::m_instances = 0;
@@ -18,6 +19,7 @@ u32int shellRun(void* ks) {
void KernelShell::setup(DirectoryNode* cwd, VirtualTerminal *vt) {
m_vt = vt;
+ Task::currProcess()->setVirtualTerminal(vt);
((ScrollableVT*)m_vt)->map(9);
Kbd::setFocus(m_vt);
m_cwd = cwd;
@@ -51,6 +53,7 @@ u32int KernelShell::run() {
{"mkdir", &KernelShell::mkdir},
{"rm", &KernelShell::rm},
{"wf", &KernelShell::wf},
+ {"run", &KernelShell::run},
{"devices", &KernelShell::devices},
{"loadkeys", &KernelShell::loadkeys},
diff --git a/Source/Kernel/Shell/KernelShell.class.h b/Source/Kernel/Shell/KernelShell.class.h
index 39e1ebd..e7549c2 100644
--- a/Source/Kernel/Shell/KernelShell.class.h
+++ b/Source/Kernel/Shell/KernelShell.class.h
@@ -4,7 +4,7 @@
#include <VTManager/VirtualTerminal.proto.h>
#include <VFS/DirectoryNode.class.h>
#include <TaskManager/Thread.class.h>
-#include <Library/Vector.class.h>
+#include <Vector.class.h>
class KernelShell {
friend u32int shellRun(void* ks);
@@ -26,6 +26,7 @@ class KernelShell {
void mkdir(Vector<String>& args);
void rm(Vector<String>& args);
void wf(Vector<String>& args);
+ void run(Vector<String>& args);
//in KernelShell-sys
void devices(Vector<String>& args);
diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp
index fcab741..63b340a 100644
--- a/Source/Kernel/SyscallManager/IDT.ns.cpp
+++ b/Source/Kernel/SyscallManager/IDT.ns.cpp
@@ -2,6 +2,7 @@
#include <VTManager/SimpleVT.class.h>
#include <DeviceManager/Dev.ns.h>
#include <TaskManager/Task.ns.h>
+#include <SyscallManager/Res.ns.h>
using namespace Sys; //For outb
@@ -55,6 +56,7 @@ extern "C" void irq13();
extern "C" void irq14();
extern "C" void irq15();
+extern "C" void int64(); //Main syscall
extern "C" void int65(); //Syscall to request a task switch
extern "C" void int66(); //Syscall to signal that thread ended
@@ -73,6 +75,23 @@ extern "C" void interrupt_handler(registers_t regs) {
Dev::handleIRQ(regs, (regs.int_no - 32));
doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32);
}
+ if (regs.int_no == 64) {
+ u32int res = (regs.eax >> 8);
+ u8int wat = (regs.eax & 0xFF);
+ if (res == 0xFFFFFF) {
+ if (regs.eax == 0xFFFFFF01) {
+ 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);
+ }
+ } else {
+ regs.eax = Res::call(res, wat, regs.ebx, regs.ecx, regs.edx, regs.edi, regs.esi);
+ }
+ //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
}
@@ -89,7 +108,7 @@ void setGate(u8int num, u32int base, u16int sel, u8int flags) {
idt_entries[num].base_hi = (base >> 16) & 0xFFFF;
idt_entries[num].sel = sel;
- idt_entries[num].flags = flags;
+ idt_entries[num].flags = flags | 0x60;
idt_entries[num].always0 = 0;
}
@@ -161,6 +180,7 @@ void init() {
setGate(46, (u32int)irq14, 0x08, 0x8E);
setGate(47, (u32int)irq15, 0x08, 0x8E);
+ setGate(64, (u32int)int64, 0x08, 0x8E);
setGate(65, (u32int)int65, 0x08, 0x8E);
setGate(66, (u32int)int66, 0x08, 0x8E);
diff --git a/Source/Kernel/SyscallManager/IDT.ns.h b/Source/Kernel/SyscallManager/IDT.ns.h
index 52f1ed5..e73a885 100644
--- a/Source/Kernel/SyscallManager/IDT.ns.h
+++ b/Source/Kernel/SyscallManager/IDT.ns.h
@@ -1,7 +1,7 @@
#ifndef DEF_IDT_NS_H
#define DEF_IDT_NS_H
-#include <Core/common.wtf.h>
+#include <common.h>
struct registers_t {
u32int ds; // Data segment selector
diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp
new file mode 100644
index 0000000..048d17a
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Res.ns.cpp
@@ -0,0 +1,75 @@
+#include "Res.ns.h"
+
+#include <VirtualTerminal.iface.h>
+#include <Process.iface.h>
+#include <Thread.iface.h>
+#include <FSNode.iface.h>
+#include <TaskManager/Task.ns.h>
+
+namespace Res {
+
+typedef u32int (*staticcall)(u8int, u32int, u32int, u32int, u32int);
+
+struct static_call_t {
+ u32int id;
+ staticcall call;
+};
+
+static_call_t staticCalls[] = {
+ {VTIF_OBJTYPE, VirtualTerminal::scall},
+ {PRIF_OBJTYPE, Process::scall},
+ {THIF_OBJTYPE, Thread::scall},
+ {FNIF_OBJTYPE, FSNode::scall},
+ {0, 0}
+};
+
+Ressource** ressources = 0;
+u32int size = 0;
+
+void expand() { //Expands size of ressources array of 20 entries
+ size += 20;
+ Ressource** tmp = (Ressource**)Mem::alloc(size * sizeof(Ressource*));
+ for (u32int i = 0; i < size; i++) {
+ if (i < size - 20) tmp[i] = ressources[i];
+ else tmp[i] = 0;
+ }
+ Mem::free(ressources);
+ ressources = tmp;
+}
+
+u32int registerRes(Ressource* r) {
+ if (ressources == 0 or size == 0) {
+ ressources = (Ressource**)Mem::alloc(20 * sizeof(Ressource*));
+ size = 20;
+ for (u32int i = 0; i < 20; i++) ressources[i] = 0;
+ }
+ for (u32int i = 0; i < size; i++) {
+ if (ressources[i] == 0) {
+ ressources[i] = r;
+ return i;
+ }
+ }
+ expand();
+ return registerRes(r);
+}
+
+void unregisterRes(u32int id) {
+ ressources[id] = 0;
+}
+
+u32int call(u32int ressource, u8int wat, u32int a, u32int b, u32int c, u32int d, u32int e) {
+ if (ressource == 0xFFFFFE) { //TODO : return ressource id for some stuff for current process
+ for (u32int i = 0; staticCalls[i].id != 0; i++) {
+ if (staticCalls[i].id == a) return staticCalls[i].call(wat, b, c, d, e);
+ }
+ return 0;
+ } else {
+ if (ressource > size or ressources[ressource] == 0) {
+ return (u32int) - 1;
+ } else {
+ return ressources[ressource]->doCall(wat, a, b, c, d, e);
+ }
+ }
+}
+
+}
diff --git a/Source/Kernel/SyscallManager/Res.ns.h b/Source/Kernel/SyscallManager/Res.ns.h
new file mode 100644
index 0000000..e454693
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Res.ns.h
@@ -0,0 +1,15 @@
+#ifndef DEF_RES_NS_H
+#define DEF_RES_NS_H
+
+#include <SyscallManager/Ressource.class.h>
+
+namespace Res {
+
+u32int registerRes(Ressource* r);
+void unregisterRes(u32int id);
+
+u32int call(u32int ressource, u8int wat, u32int a, u32int b, u32int c, u32int d, u32int e);
+
+}
+
+#endif
diff --git a/Source/Kernel/SyscallManager/Ressource.class.cpp b/Source/Kernel/SyscallManager/Ressource.class.cpp
new file mode 100644
index 0000000..f2aaccb
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Ressource.class.cpp
@@ -0,0 +1,41 @@
+#include "Ressource.class.h"
+#include <SyscallManager/Res.ns.h>
+
+Ressource::Ressource(u8int type, call_t* callTable) {
+ m_id = Res::registerRes(this);
+ m_type = type;
+ m_callTables = 0;
+
+ addCallTable(callTable);
+}
+
+Ressource::~Ressource() {
+ Res::unregisterRes(m_id);
+ delete m_callTables;
+}
+
+void Ressource::addCallTable(call_t* callTable) {
+ if (callTable != 0) m_callTables = m_callTables->cons(callTable);
+}
+
+u32int Ressource::doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e) {
+ if (id == 0) return m_type;
+
+ for (SimpleList<call_t*> *iter = m_callTables; iter != 0; iter = iter->next()) {
+ call_t* ct = iter->v();
+ u32int i = 0;
+ while (ct[i].id != 0) {
+ call_t &ce = ct[i];
+ if (ce.id == id) {
+ if (ce.params == 0) return (this->*(ce.c0))();
+ if (ce.params == 1) return (this->*(ce.c1))(a);
+ if (ce.params == 2) return (this->*(ce.c2))(a, b);
+ if (ce.params == 3) return (this->*(ce.c3))(a, b, c);
+ if (ce.params == 4) return (this->*(ce.c4))(a, b, c, d);
+ if (ce.params == 5) return (this->*(ce.c5))(a, b, c, d, e);
+ }
+ i++;
+ }
+ }
+ return (u32int) - 1;
+}
diff --git a/Source/Kernel/SyscallManager/Ressource.class.h b/Source/Kernel/SyscallManager/Ressource.class.h
new file mode 100644
index 0000000..f58276b
--- /dev/null
+++ b/Source/Kernel/SyscallManager/Ressource.class.h
@@ -0,0 +1,56 @@
+#ifndef DEF_RESSOURCE_CLASS_H
+#define DEF_RESSOURCE_CLASS_H
+
+#include <SimpleList.class.h>
+
+class Ressource;
+
+typedef u32int (Ressource::*call0)();
+typedef u32int (Ressource::*call1)(u32int);
+typedef u32int (Ressource::*call2)(u32int, u32int);
+typedef u32int (Ressource::*call3)(u32int, u32int, u32int);
+typedef u32int (Ressource::*call4)(u32int, u32int, u32int, u32int);
+typedef u32int (Ressource::*call5)(u32int, u32int, u32int, u32int, u32int);
+
+#define CALL0(id, ptr) {0, id, {(call0)ptr}}
+#define CALL1(id, ptr) {1, id, {c1: (call1)ptr}}
+#define CALL2(id, ptr) {2, id, {c2: (call2)ptr}}
+#define CALL3(id, ptr) {3, id, {c3: (call3)ptr}}
+#define CALL4(id, ptr) {4, id, {c4: (call4)ptr}}
+#define CALL5(id, ptr) {5, id, {c5: (call5)ptr}}
+
+struct call_t {
+ u8int params;
+ u8int id;
+ union {
+ call0 c0;
+ call1 c1;
+ call2 c2;
+ call3 c3;
+ call4 c4;
+ call5 c5;
+ };
+};
+
+class Ressource {
+ private:
+ Ressource(const Ressource&);
+ Ressource& operator=(const Ressource&);
+
+ u32int m_id;
+ u32int m_type;
+ SimpleList<call_t*> *m_callTables;
+
+ protected:
+ Ressource(u8int type, call_t* callTable = 0);
+ ~Ressource();
+
+ void addCallTable(call_t* callTable);
+
+ public:
+ u32int doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e);
+ u32int resId() { return m_id; }
+ u32int resType() { return m_type; }
+};
+
+#endif
diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp
index cf8f00a..a2bbfb4 100644
--- a/Source/Kernel/TaskManager/Process.class.cpp
+++ b/Source/Kernel/TaskManager/Process.class.cpp
@@ -2,12 +2,26 @@
#include <TaskManager/Task.ns.h>
#include <MemoryManager/PhysMem.ns.h>
#include <VFS/File.class.h>
+#include <Linker/Binary.proto.h>
+#include <Process.iface.h>
namespace Mem {
extern Heap kheap;
}
-Process::Process() { //Private constructor, does nothing
+call_t Process::m_callTable[] = {
+ CALL0(PRIF_EXIT, &Process::exitSC),
+ CALL1(PRIF_ALLOCPAGE, &Process::allocPageSC),
+ CALL1(PRIF_FREEPAGE, &Process::freePageSC),
+ CALL0(0, 0)
+};
+
+u32int Process::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) {
+ if (wat == PRIF_SGETCPR) return Task::currProcess()->resId();
+ return (u32int) - 1;
+}
+
+Process::Process() : Ressource(PRIF_OBJTYPE, m_callTable) { //Private constructor, does nothing
}
Process* Process::createKernel(String cmdline, VirtualTerminal *vt) {
@@ -35,13 +49,31 @@ Process* Process::createKernel(String cmdline, VirtualTerminal *vt) {
return p;
}
-Process::Process(String cmdline, u32int uid) {
+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) : Ressource(PRIF_OBJTYPE, m_callTable) {
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;
//Create page directory and user heap
m_pagedir = new PageDirectory(kernelPageDirectory);
m_pagedir->switchTo();
@@ -56,6 +88,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];
@@ -65,7 +101,7 @@ void Process::exit() {
iter->v()->close(false);
delete iter->v();
}
- delete m_fileDescriptors; //Will recursively delete whole list
+ if (m_fileDescriptors != 0) delete m_fileDescriptors; //Will recursively delete whole list
m_state = P_FINISHED;
}
@@ -76,7 +112,7 @@ void Process::registerThread(Thread* t) {
void Process::threadFinishes(Thread* thread, u32int retval) {
// If it is the main thread of the process, or if it pagefaulted
- if (thread == m_threads[0] or retval == E_PAGEFAULT) {
+ if (thread == m_threads[0] or retval == E_PAGEFAULT or retval == E_EXIT) {
exit();
} else {
//Simply unregister thread
@@ -110,3 +146,25 @@ VirtualTerminal* Process::getVirtualTerminal() {
void Process::setVirtualTerminal(VirtualTerminal* vt) {
m_vt = vt;
}
+
+u32int Process::exitSC() {
+ if (Task::currProcess() != this) return 1;
+ Task::currentThreadExits(E_EXIT);
+ return 0;
+}
+
+u32int Process::allocPageSC(u32int pos) {
+ if (Task::currProcess() != this) return 1;
+ if ((pos & 0x00000FFF) != 0) pos = (pos & 0xFFFFF000) + 0x1000;
+ if (pos >= 0xC0000000) return 1;
+ m_pagedir->allocFrame(pos, true, true);
+ return 0;
+}
+
+u32int Process::freePageSC(u32int pos) {
+ if (Task::currProcess() != this) return 1;
+ if ((pos & 0x00000FFF) != 0) pos = (pos & 0xFFFFF000) + 0x1000;
+ if (pos >= 0xC0000000) return 1;
+ m_pagedir->freeFrame(pos);
+ return 0;
+}
diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h
index ac9614e..89efd0c 100644
--- a/Source/Kernel/TaskManager/Process.class.h
+++ b/Source/Kernel/TaskManager/Process.class.h
@@ -1,19 +1,23 @@
#ifndef DEF_PROCESS_CLASS_H
#define DEF_PROCESS_CLASS_H
-#include <Library/String.class.h>
-#include <Library/Vector.class.h>
-#include <Library/SimpleList.class.h>
+#include <String.class.h>
+#include <Vector.class.h>
+#include <SimpleList.class.h>
#include <MemoryManager/PageDirectory.class.h>
-#include <MemoryManager/Heap.class.h>
+#include <Heap.class.h>
#include <VTManager/VirtualTerminal.proto.h>
+#include <VFS/File.class.h>
+
+#include <SyscallManager/Ressource.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
+#define E_EXIT 0x0FFFFF01
#define E_UNHANDLED_EXCEPTION 0x0FFFFF02
#define STACKSIZE 4096 //Could change
@@ -24,7 +28,7 @@
class Thread;
class File;
-class Process {
+class Process : public Ressource {
friend class Thread;
private:
@@ -42,14 +46,23 @@ class Process {
Vector<Thread*> m_threads;
SimpleList<File*> *m_fileDescriptors;
+
+ //System calls
+ static call_t m_callTable[];
+ u32int exitSC();
+ u32int allocPageSC(u32int);
public:
+ static u32int scall(u8int, u32int, u32int, u32int, u32int);
+
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
@@ -61,7 +74,8 @@ class Process {
VirtualTerminal* getVirtualTerminal();
void setVirtualTerminal(VirtualTerminal* vt);
-
+ u32int getState() { return m_state; }
+ u32int freePageSC(u32int);
};
#endif
diff --git a/Source/Kernel/TaskManager/Task.ns.cpp b/Source/Kernel/TaskManager/Task.ns.cpp
index a34f14f..aef07f3 100644
--- a/Source/Kernel/TaskManager/Task.ns.cpp
+++ b/Source/Kernel/TaskManager/Task.ns.cpp
@@ -1,5 +1,4 @@
#include "Task.ns.h"
-#include <Library/Vector.class.h>
#include <MemoryManager/PhysMem.ns.h>
#define INVALID_TASK_MAGIC 0xBEEFFEED
@@ -94,8 +93,11 @@ void doSwitch() {
eip = t->getEip();
cr3 = currentProcess->getPagedir()->physicalAddr;
+ asm volatile("cli");
+
+ t->setKernelStack();
+
asm volatile(" \
- cli; \
mov %0, %%ebp; \
mov %1, %%esp; \
mov %2, %%ecx; \
@@ -138,6 +140,7 @@ void currThreadExitProceed(u32int errcode) {
}
void currentThreadExits(u32int errcode) { //Call currThreadExitProceed with a working stack (we use temp_stack)
+ asm volatile("cli");
u32int* stack = &temp_stack[TEMP_STACK_SIZE];
stack--;
*stack = errcode;
@@ -146,7 +149,6 @@ void currentThreadExits(u32int errcode) { //Call currThreadExitProceed with a wo
u32int esp = (u32int)(stack), ebp = (u32int)(stack + 1), eip = (u32int)currThreadExitProceed;
asm volatile(" \
- cli; \
mov %0, %%ebp; \
mov %1, %%esp; \
mov %2, %%ecx; \
diff --git a/Source/Kernel/TaskManager/Task.ns.h b/Source/Kernel/TaskManager/Task.ns.h
index c7c3d23..056e4c0 100644
--- a/Source/Kernel/TaskManager/Task.ns.h
+++ b/Source/Kernel/TaskManager/Task.ns.h
@@ -3,7 +3,7 @@
#include <TaskManager/Thread.class.h>
#include <VTManager/VirtualTerminal.proto.h>
-#include <Library/SimpleList.class.h>
+#include <SimpleList.class.h>
namespace Task {
Thread* currThread();
diff --git a/Source/Kernel/TaskManager/Task.wtf.asm b/Source/Kernel/TaskManager/Task.wtf.asm
index 77db18e..9f27bec 100644
--- a/Source/Kernel/TaskManager/Task.wtf.asm
+++ b/Source/Kernel/TaskManager/Task.wtf.asm
@@ -9,13 +9,6 @@ idle_task:
hlt
jmp idle_task
-[GLOBAL atomic_exchange]
-atomic_exchange:
- mov ecx, [esp+4] ; Get lock address
- mov eax, [esp+8] ; Get new value
- xchg eax, [ecx] ; Old value goes in eax
- ret
-
[GLOBAL copy_page_physical]
copy_page_physical:
push ebx ; According to __cdecl, we must preserve the contents of EBX.
@@ -47,3 +40,5 @@ copy_page_physical:
popf ; Pop EFLAGS back.
pop ebx ; Get the original value of EBX back.
ret
+
+
diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp
index 6d62474..21ef954 100644
--- a/Source/Kernel/TaskManager/Thread.class.cpp
+++ b/Source/Kernel/TaskManager/Thread.class.cpp
@@ -2,17 +2,71 @@
#include <TaskManager/Task.ns.h>
#include <MemoryManager/PageAlloc.ns.h>
#include <DeviceManager/Time.ns.h>
+#include <MemoryManager/GDT.ns.h>
+
+#include <Thread.iface.h>
+
+call_t Thread::m_callTable[] = {
+ CALL1(THIF_SLEEP, &Thread::sleepSC),
+ CALL1(THIF_FINISH, &Thread::finishSC),
+ CALL0(0, 0)
+};
+
+u32int Thread::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) {
+ if (wat == THIF_SGETCTH) return Task::currThread()->resId();
+ return (u32int) - 1;
+}
void runThread(Thread* thread, void* data, thread_entry_t entry_point) {
- asm volatile("sti");
- u32int ret = entry_point(data); //Run !
- asm volatile("mov %0, %%eax; int $66;" : : "r"(ret)); //Syscall for thread ending
+ if (thread->m_isKernel) {
+ asm volatile("sti");
+ u32int ret = entry_point(data); //Run !
+ asm volatile("mov %0, %%eax; int $66;" : : "r"(ret)); //Syscall for thread ending
+ } else {
+ //Setup values on user stack
+ u32int *stack = (u32int*)((u32int)thread->m_userStack.addr + thread->m_userStack.size);
+ stack--;
+ *stack = (u32int)data;
+ stack--;
+ *stack = 0;
+ u32int esp = (u32int)stack, eip = (u32int)entry_point;
+ //Setup a false structure for returning from an interrupt :
+ //- update data segments to 0x23 = user data segment with RPL=3
+ //- mov esp in ebx and eip in ecx
+ //- push value for ss : 0x23 (user data seg rpl3)
+ //- push value for esp
+ //- push flags
+ //- update flags, set IF = 1 (interrupts flag)
+ //- push value for cs : 0x1B = user code segment with RPL=3
+ //- push eip
+ //- return from fake interrupt
+ asm volatile(" \
+ mov $0x23, %%ax; \
+ mov %%ax, %%ds; \
+ mov %%ax, %%es; \
+ mov %%ax, %%fs; \
+ mov %%ax, %%gs; \
+ \
+ mov %0, %%ebx; \
+ mov %1, %%ecx; \
+ pushl $0x23; \
+ pushl %%ebx; \
+ pushf; \
+ pop %%eax; \
+ or $0x200, %%eax; \
+ push %%eax; \
+ pushl $0x1B; \
+ push %%ecx; \
+ iret; \
+ " : : "r"(esp), "r"(eip));
+ }
}
-Thread::Thread() { //Private constructor, does nothing
+Thread::Thread() : Ressource(THIF_OBJTYPE, m_callTable) { //Private constructor, does nothing
+ m_xchgspace = 0;
}
-Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) {
+Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) : Ressource(THIF_OBJTYPE, m_callTable) {
if (iskernel) {
setup(Task::getKernelProcess(), entry_point, data, true);
} else {
@@ -20,22 +74,28 @@ Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) {
}
}
-Thread::Thread(Process* process, thread_entry_t entry_point, void* data) {
+Thread::Thread(Process* process, thread_entry_t entry_point, void* data) : Ressource(THIF_OBJTYPE, m_callTable) {
setup(process, entry_point, data, false);
}
Thread::~Thread() {
Task::unregisterThread(this);
- Mem::kfree(m_kernelStack.addr);
- if (!m_isKernel) m_process->heap().free(m_userStack.addr);
+ Mem::free(m_kernelStack.addr);
+ m_process->getPagedir()->switchTo();
+ if (m_userStack.addr != 0) {
+ m_process->heap().free(m_userStack.addr);
+ }
+ if (m_xchgspace != 0) {
+ m_process->heap().free(m_xchgspace);
+ }
//Don't unregister thread in process, it has probably already been done
}
void Thread::setup(Process* process, thread_entry_t entry_point, void* data, bool isKernel) {
- DEBUG("new Thread :: setup");
+ m_xchgspace = 0;
m_isKernel = isKernel;
m_process = process;
- m_kernelStack.addr = Mem::kalloc(STACKSIZE);
+ m_kernelStack.addr = Mem::alloc(STACKSIZE);
m_kernelStack.size = STACKSIZE;
if (m_isKernel) {
@@ -111,11 +171,11 @@ void Thread::handleException(registers_t regs, int no) {
*(m_process->m_vt) << "At:" << (u32int)faddr;
*(m_process->m_vt) << "\nThread finishing.\n";
- finish(E_PAGEFAULT);
+ Task::currentThreadExits(E_PAGEFAULT); //Calling this will setup a new stack
return;
}
*(m_process->m_vt) << "\nThread finishing.\n";
- finish(E_UNHANDLED_EXCEPTION);
+ Task::currentThreadExits(E_UNHANDLED_EXCEPTION);
}
void Thread::setState(u32int esp, u32int ebp, u32int eip) {
@@ -124,12 +184,22 @@ void Thread::setState(u32int esp, u32int ebp, u32int eip) {
m_eip = eip;
}
+void Thread::setKernelStack() {
+ GDT::tss_entry.esp0 = (u32int)(m_kernelStack.addr) + m_kernelStack.size;
+}
+
u32int Thread::getEsp() { return m_esp; }
u32int Thread::getEbp() { return m_ebp; }
u32int Thread::getEip() { return m_eip; }
Process* Thread::getProcess() { return m_process; }
+void* Thread::mkXchgSpace(u32int sz) {
+ if (m_xchgspace != 0) m_process->heap().free(m_xchgspace);
+ m_xchgspace = m_process->heap().alloc(sz);
+ return m_xchgspace;
+}
+
void Thread::sleep(u32int msecs) {
m_state = T_SLEEPING;
waitfor.m_time = Time::time() + msecs;
@@ -145,6 +215,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;
@@ -152,3 +223,17 @@ bool Thread::runnable() {
}
return false;
}
+
+u32int Thread::sleepSC(u32int msecs) {
+ if (this != Task::currThread()) return 1;
+ sleep(msecs);
+ return 0;
+}
+
+u32int Thread::finishSC(u32int errcode) {
+ if (this != Task::currThread()) return 1;
+ Task::currentThreadExits(errcode);
+ return 0;
+}
+
+
diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h
index 9c8fa26..35a9fd6 100644
--- a/Source/Kernel/TaskManager/Thread.class.h
+++ b/Source/Kernel/TaskManager/Thread.class.h
@@ -11,7 +11,7 @@
typedef u32int(*thread_entry_t)(void*);
-class Thread {
+class Thread : public Ressource {
friend class Process; //This might be useful
friend void runThread(Thread*, void*, thread_entry_t);
@@ -22,6 +22,8 @@ class Thread {
u32int m_esp, m_ebp, m_eip;
u8int m_state; //Is one of T_* defined above
+ void* m_xchgspace;
+
union { //What the thread might be waiting for
u32int m_time;
u8int m_irq; //An IRQ number
@@ -35,7 +37,14 @@ class Thread {
void setup(Process* process, thread_entry_t entry_point, void* data, bool isKernel);
+ //Syscalls
+ static call_t m_callTable[];
+ u32int sleepSC(u32int msecs);
+ u32int finishSC(u32int errcode);
+
public:
+ static u32int scall(u8int, u32int, u32int, u32int, u32int);
+
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();
@@ -43,11 +52,14 @@ class Thread {
void handleException(registers_t regs, int no);
void setState(u32int esp, u32int ebp, u32int eip);
+ void setKernelStack();
u32int getEsp();
u32int getEbp();
u32int getEip();
Process* getProcess();
+ void* mkXchgSpace(u32int sz);
+
void sleep(u32int msecs);
void waitIRQ(u8int irq);
bool runnable(); //Called by scheduler
diff --git a/Source/Kernel/VFS/DirectoryNode.class.h b/Source/Kernel/VFS/DirectoryNode.class.h
index 2130458..346c4ab 100644
--- a/Source/Kernel/VFS/DirectoryNode.class.h
+++ b/Source/Kernel/VFS/DirectoryNode.class.h
@@ -2,7 +2,7 @@
#define DEF_DIRECTORYNODE_CLASS_H
#include <VFS/FileNode.class.h>
-#include <Library/Vector.class.h>
+#include <Vector.class.h>
class DirectoryNode : public FSNode {
protected:
diff --git a/Source/Kernel/VFS/FSNode-sc.proto.cpp b/Source/Kernel/VFS/FSNode-sc.proto.cpp
new file mode 100644
index 0000000..9e485e1
--- /dev/null
+++ b/Source/Kernel/VFS/FSNode-sc.proto.cpp
@@ -0,0 +1,34 @@
+#include "FSNode.proto.h"
+#include <VFS/VFS.ns.h>
+
+call_t FSNode::m_callTable[] = {
+ CALL0(FNIF_GETNAME, &FSNode::getNameSC),
+ CALL0(FNIF_TYPE, &FSNode::typeSC),
+ CALL0(FNIF_GETPARENT, &FSNode::getParentSC),
+ CALL0(FNIF_GETLENGTH, &FSNode::getLengthSC),
+ CALL0(0, 0)
+};
+
+u32int FSNode::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) {
+ if (wat == FNIF_SGETRFN) return VFS::getRootNode()->resId();
+ return (u32int) - 1;
+}
+
+u32int FSNode::getNameSC() {
+ return getName().serialize();
+}
+
+u32int FSNode::typeSC() {
+ return type();
+}
+
+u32int FSNode::getLengthSC() {
+ u64int* a = (u64int*)Mem::mkXchgSpace(sizeof(u64int));
+ *a = getLength();
+ return (u32int)a;
+}
+
+u32int FSNode::getParentSC() {
+ if (m_parent != 0) return m_parent->resId();
+ return (u32int) - 1;
+}
diff --git a/Source/Kernel/VFS/FSNode.proto.h b/Source/Kernel/VFS/FSNode.proto.h
index 8773543..b648141 100644
--- a/Source/Kernel/VFS/FSNode.proto.h
+++ b/Source/Kernel/VFS/FSNode.proto.h
@@ -1,10 +1,13 @@
#ifndef DEF_FSNODE_PROTO_H
#define DEF_FSNODE_PROTO_H
-#include <Core/common.wtf.h>
-#include <Library/String.class.h>
+#include <common.h>
+#include <String.class.h>
class FSNode;
#include <VFS/FileSystem.proto.h>
+#include <SyscallManager/Ressource.class.h>
+
+#include <FSNode.iface.h>
enum {
NT_FILE = 1,
@@ -13,18 +16,27 @@ enum {
NT_MOUNTPOINT = 4
};
-class FSNode {
+class FSNode : public Ressource {
protected:
String m_name;
u64int m_length;
u32int m_permissions, m_uid, m_gid;
FileSystem *m_fs;
FSNode *m_parent;
+
+ //Syscall related
+ static call_t m_callTable[];
+ u32int getNameSC();
+ u32int getLengthSC();
+ u32int typeSC();
+ u32int getParentSC();
public:
+ static u32int scall(u8int, u32int, u32int, u32int, u32int);
+
FSNode(String name, FileSystem* fs, FSNode* parent, u64int length = 0, u32int permissions = 0777,
u32int uid = 0, u32int gid = 0) :
- m_name(name), m_length(length), m_permissions(permissions),
+ Ressource(FNIF_OBJTYPE, m_callTable), m_name(name), m_length(length), m_permissions(permissions),
m_uid(uid), m_gid(gid), m_fs(fs), m_parent(parent) {}
virtual ~FSNode() {}
diff --git a/Source/Kernel/VFS/File.class.h b/Source/Kernel/VFS/File.class.h
index 7831fb5..f5d0c56 100644
--- a/Source/Kernel/VFS/File.class.h
+++ b/Source/Kernel/VFS/File.class.h
@@ -2,7 +2,7 @@
#define DEF_FILE_CLASS_H
#include <VFS/FileNode.class.h>
-#include <Library/ByteArray.class.h>
+#include <ByteArray.class.h>
enum {
FM_READ = 0, //Open for read, put cursor at beginning
diff --git a/Source/Kernel/VFS/Part.ns.h b/Source/Kernel/VFS/Part.ns.h
index 07a45f9..40a0fb2 100644
--- a/Source/Kernel/VFS/Part.ns.h
+++ b/Source/Kernel/VFS/Part.ns.h
@@ -2,7 +2,7 @@
#define DEF_PART_NS_H
#include <Devices/BlockDevice.proto.h>
-#include <Library/Vector.class.h>
+#include <Vector.class.h>
#include <VFS/Partition.class.h>
namespace Part {
diff --git a/Source/Kernel/VTManager/SimpleVT.class.cpp b/Source/Kernel/VTManager/SimpleVT.class.cpp
index 89391b2..d304a5f 100644
--- a/Source/Kernel/VTManager/SimpleVT.class.cpp
+++ b/Source/Kernel/VTManager/SimpleVT.class.cpp
@@ -132,5 +132,5 @@ void SimpleVT::put(WChar c, bool updatecsr) {
void SimpleVT::hexDump(u8int *ptr, u32int sz, bool addnl) {
if (m_cols < 76) return; //Not enough space
- VirtualTerminal::hexDump(ptr, sz, (m_cols == 76));
+ VirtualTerminal::hexDump(ptr, sz, (m_cols > 76));
}
diff --git a/Source/Kernel/VTManager/VT.ns.cpp b/Source/Kernel/VTManager/VT.ns.cpp
index 87586bc..ee7299d 100644
--- a/Source/Kernel/VTManager/VT.ns.cpp
+++ b/Source/Kernel/VTManager/VT.ns.cpp
@@ -1,5 +1,5 @@
#include "VT.ns.h"
-#include <Library/Vector.class.h>
+#include <Vector.class.h>
#include <DeviceManager/Disp.ns.h>
namespace VT {
diff --git a/Source/Kernel/VTManager/VT.ns.h b/Source/Kernel/VTManager/VT.ns.h
index 55556b9..9390636 100644
--- a/Source/Kernel/VTManager/VT.ns.h
+++ b/Source/Kernel/VTManager/VT.ns.h
@@ -1,7 +1,7 @@
#ifndef DEF_VT_NS_H
#define DEF_VT_NS_H
-#include <Core/common.wtf.h>
+#include <common.h>
#include <VTManager/SimpleVT.class.h>
namespace VT {
diff --git a/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp
index 59f66a6..b5ed9c3 100644
--- a/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp
+++ b/Source/Kernel/VTManager/VirtualTerminal-kbd.proto.cpp
@@ -28,8 +28,9 @@ keypress_t VirtualTerminal::getKeypress(bool show, bool block) {
return keypress_t();
}
- while (m_kbdbuff.empty())
+ while (m_kbdbuff.empty()) {
Task::currThread()->sleep(10);
+ }
m_kbdbuffMutex.waitLock();
keypress_t ret = m_kbdbuff[0];
diff --git a/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp
new file mode 100644
index 0000000..0a4e14b
--- /dev/null
+++ b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp
@@ -0,0 +1,46 @@
+#include "VirtualTerminal.proto.h"
+
+u32int VirtualTerminal::writeHexSC(u32int number) {
+ writeHex(number);
+ return 0;
+}
+
+u32int VirtualTerminal::writeDecSC(u32int n_hi, u32int n_lo) {
+ s64int n = ((u64int)n_hi << 32) | n_lo;
+ writeDec(n);
+ return 0;
+}
+
+u32int VirtualTerminal::writeSC(u32int wat) {
+ String *s = (String*)wat;
+ write(*s);
+ return 0;
+}
+
+u32int VirtualTerminal::putSC(u32int code) {
+ put(WChar(code));
+ return 0;
+}
+
+u32int VirtualTerminal::readLineSC() {
+ return readLine().serialize();
+}
+
+u32int VirtualTerminal::setColorSC(u32int x) {
+ setColor((x >> 8) & 0xFF, x & 0xFF);
+ return 0;
+}
+
+u32int VirtualTerminal::setCursorLineSC(u32int l) {
+ setCursorLine(l);
+ return 0;
+}
+
+u32int VirtualTerminal::setCursorColSC(u32int c) {
+ setCursorCol(c);
+ return 0;
+}
+
+u32int VirtualTerminal::isBoxedSC() {
+ return (isBoxed() ? 1 : 0);
+}
diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp
index 7a9ffa8..9b0b862 100644
--- a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp
+++ b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp
@@ -1,8 +1,30 @@
#include "VirtualTerminal.proto.h"
#include <DeviceManager/Disp.ns.h>
#include <VTManager/VT.ns.h>
+#include <TaskManager/Task.ns.h>
-VirtualTerminal::VirtualTerminal() : m_kbdMutex(false), m_kbdbuffMutex(false) {
+#include <VirtualTerminal.iface.h>
+
+call_t VirtualTerminal::m_callTable[] = {
+ CALL1(VTIF_WRITEHEX, &VirtualTerminal::writeHexSC),
+ CALL2(VTIF_WRITEDEC, &VirtualTerminal::writeDecSC),
+ CALL1(VTIF_WRITE, &VirtualTerminal::writeSC),
+ CALL1(VTIF_PUT, &VirtualTerminal::putSC),
+ CALL0(VTIF_READLINE, &VirtualTerminal::readLineSC),
+ CALL1(VTIF_SETCOLOR, &VirtualTerminal::setColorSC),
+ CALL1(VTIF_SETCSRLINE, &VirtualTerminal::setCursorLineSC),
+ CALL1(VTIF_SETCSRCOL, &VirtualTerminal::setCursorColSC),
+ CALL0(VTIF_ISBOXED, &VirtualTerminal::isBoxedSC),
+ CALL0(0, 0)
+};
+
+u32int VirtualTerminal::scall(u8int wat, u32int a, u32int b, u32int c, u32int d) {
+ if (wat == VTIF_SGETPRVT) return Task::currProcess()->getVirtualTerminal()->resId();
+ return (u32int) - 1;
+}
+
+VirtualTerminal::VirtualTerminal() :
+ Ressource(VTIF_OBJTYPE, m_callTable), m_kbdMutex(false), m_kbdbuffMutex(false), m_kbdbuff() {
}
VirtualTerminal::~VirtualTerminal() {
diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.h b/Source/Kernel/VTManager/VirtualTerminal.proto.h
index ea6284f..936e4d4 100644
--- a/Source/Kernel/VTManager/VirtualTerminal.proto.h
+++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h
@@ -1,23 +1,39 @@
#ifndef DEF_VIRTUALTERMINAL_CLASS_H
#define DEF_VIRTUALTERMINAL_CLASS_H
-#include <Core/common.wtf.h>
-#include <Library/String.class.h>
-#include <TaskManager/Mutex.class.h>
+#include <common.h>
+#include <String.class.h>
+#include <Mutex.class.h>
#include <DeviceManager/Kbd.ns.h>
-#include <Library/Vector.class.h>
+#include <Vector.class.h>
+
+#include <SyscallManager/Ressource.class.h>
struct vtchr {
u8int color;
WChar c;
};
-class VirtualTerminal {
+class VirtualTerminal : public Ressource {
protected:
Mutex m_kbdMutex, m_kbdbuffMutex;
Vector<Kbd::keypress_t> m_kbdbuff; //Key press events buffer
+ //SYSCALLS :
+ static call_t m_callTable[];
+ u32int writeHexSC(u32int);
+ u32int writeDecSC(u32int, u32int);
+ u32int writeSC(u32int);
+ u32int putSC(u32int);
+ u32int readLineSC();
+ u32int setColorSC(u32int);
+ u32int setCursorLineSC(u32int);
+ u32int setCursorColSC(u32int);
+ u32int isBoxedSC();
+
public:
+ static u32int scall(u8int, u32int, u32int, u32int, u32int);
+
VirtualTerminal();
virtual ~VirtualTerminal();
diff --git a/Source/Kernel/Core/common.wtf.h b/Source/Kernel/common.h
index 5fb67b4..86d76cd 100644
--- a/Source/Kernel/Core/common.wtf.h
+++ b/Source/Kernel/common.h
@@ -7,9 +7,9 @@
#define NULL 0
-#include <Core/types.wtf.h>
+#include <types.h>
-#include <Core/CMem.ns.h>
+#include <CMem.ns.h>
#include <Core/Sys.ns.h>
#include <MemoryManager/Mem.ns.h>
@@ -20,9 +20,9 @@ inline void* operator new[](u32int, void *p) { return p; }
inline void operator delete(void*, void*) { }
inline void operator delete[](void*, void*) { }
-inline void* operator new(u32int sz) { return Mem::kalloc(sz); }
-inline void* operator new[](u32int sz) { return Mem::kalloc(sz); }
-inline void operator delete(void *ptr) { Mem::kfree(ptr); }
-inline void operator delete[](void *ptr) { Mem::kfree(ptr); }
+inline void* operator new(u32int sz) { return Mem::alloc(sz); }
+inline void* operator new[](u32int sz) { return Mem::alloc(sz); }
+inline void operator delete(void *ptr) { Mem::free(ptr); }
+inline void operator delete[](void *ptr) { Mem::free(ptr); }
#endif
diff --git a/Source/Kernel/Library/BasicString.class.cpp b/Source/Library/Common/BasicString.class.cpp
index ae89fe4..ceab60b 100644
--- a/Source/Kernel/Library/BasicString.class.cpp
+++ b/Source/Library/Common/BasicString.class.cpp
@@ -1,4 +1,4 @@
-#include <Library/Vector.class.h>
+#include <Vector.class.h>
#define FREE if (m_string != 0) delete m_string;
#define ALLOC m_string = new T[m_length];
diff --git a/Source/Kernel/Library/BasicString.class.h b/Source/Library/Common/BasicString.class.h
index 5c69d00..17055e8 100644
--- a/Source/Kernel/Library/BasicString.class.h
+++ b/Source/Library/Common/BasicString.class.h
@@ -1,7 +1,7 @@
#ifndef DEF_BASICSTRING_CLASS_H
#define DEF_BASICSTRING_CLASS_H
-#include <Core/common.wtf.h>
+#include <common.h>
template <typename T> class Vector;
diff --git a/Source/Kernel/Library/Bitset.class.cpp b/Source/Library/Common/Bitset.class.cpp
index ec4e62c..a8d7ec8 100644
--- a/Source/Kernel/Library/Bitset.class.cpp
+++ b/Source/Library/Common/Bitset.class.cpp
@@ -4,7 +4,7 @@ Bitset::Bitset() {
}
Bitset::Bitset(u32int size) {
- init(size, (u32int*)Mem::kalloc(INDEX_FROM_BIT(size)));
+ init(size, (u32int*)Mem::alloc(INDEX_FROM_BIT(size)));
}
Bitset::Bitset(u32int size, u32int *ptr) {
@@ -12,7 +12,7 @@ Bitset::Bitset(u32int size, u32int *ptr) {
}
Bitset::~Bitset() {
- Mem::kfree(m_data);
+ Mem::free(m_data);
}
void Bitset::init(u32int size, u32int *ptr) {
diff --git a/Source/Kernel/Library/Bitset.class.h b/Source/Library/Common/Bitset.class.h
index 75fde24..8a0707d 100644
--- a/Source/Kernel/Library/Bitset.class.h
+++ b/Source/Library/Common/Bitset.class.h
@@ -1,7 +1,7 @@
#ifndef DEF_BITSET_CLASS_H
#define DEF_BITSET_CLASS_H
-#include <Core/common.wtf.h>
+#include <common.h>
#define INDEX_FROM_BIT(a) (a/(8*4))
#define OFFSET_FROM_BIT(a) (a%(8*4))
diff --git a/Source/Kernel/Library/ByteArray.class.cpp b/Source/Library/Common/ByteArray.class.cpp
index 9972493..2a42702 100644
--- a/Source/Kernel/Library/ByteArray.class.cpp
+++ b/Source/Library/Common/ByteArray.class.cpp
@@ -49,10 +49,6 @@ void ByteArray::resize(u32int size) {
m_length = size;
}
-void ByteArray::dump(VirtualTerminal *vt) {
- vt->hexDump(m_string, m_length);
-}
-
String ByteArray::toString (u8int encoding) {
char* c = new char[m_length + 1];
memcpy((u8int*)c, m_string, m_length);
diff --git a/Source/Kernel/Library/ByteArray.class.h b/Source/Library/Common/ByteArray.class.h
index a6d594f..339e0d4 100644
--- a/Source/Kernel/Library/ByteArray.class.h
+++ b/Source/Library/Common/ByteArray.class.h
@@ -1,8 +1,7 @@
#ifndef DEF_BYTEARRAY_CLASS_H
#define DEF_BYTEARRAY_CLASS_H
-#include <Library/String.class.h>
-#include <VTManager/VirtualTerminal.proto.h>
+#include <String.class.h>
class ByteArray : public BasicString<u8int> {
public:
@@ -21,8 +20,6 @@ class ByteArray : public BasicString<u8int> {
void affect(const String& string, u8int encoding = UE_UTF8);
void resize(u32int size);
- void dump(VirtualTerminal *vt);
-
String toString(u8int encoding = UE_UTF8);
operator u8int* () { return m_string; }
};
diff --git a/Source/Kernel/Core/CMem.ns.cpp b/Source/Library/Common/CMem.ns.cpp
index c2129ec..37cdf0c 100644
--- a/Source/Kernel/Core/CMem.ns.cpp
+++ b/Source/Library/Common/CMem.ns.cpp
@@ -1,4 +1,4 @@
-#include <Core/common.wtf.h>
+#include <common.h>
namespace CMem {
diff --git a/Source/Kernel/Core/CMem.ns.h b/Source/Library/Common/CMem.ns.h
index f0c15da..f0c15da 100644
--- a/Source/Kernel/Core/CMem.ns.h
+++ b/Source/Library/Common/CMem.ns.h
diff --git a/Source/Kernel/MemoryManager/Heap-index.class.cpp b/Source/Library/Common/Heap-index.class.cpp
index 3280736..3280736 100644
--- a/Source/Kernel/MemoryManager/Heap-index.class.cpp
+++ b/Source/Library/Common/Heap-index.class.cpp
diff --git a/Source/Kernel/MemoryManager/Heap.class.cpp b/Source/Library/Common/Heap.class.cpp
index 7331cd0..34e4dc4 100644
--- a/Source/Kernel/MemoryManager/Heap.class.cpp
+++ b/Source/Library/Common/Heap.class.cpp
@@ -1,7 +1,19 @@
#include "Heap.class.h"
-#include <MemoryManager/PageDirectory.class.h>
+#ifdef THIS_IS_MELON_KERNEL
+#include <MemoryManager/PageDirectory.class.h>
+#define ALLOC(x) m_pagedir->allocFrame(x, m_user, m_rw)
+#define FREE(x) m_pagedir->freeFrame(x)
+#else
+#define ALLOC(x) m_process.allocPage(x)
+#define FREE(x) m_process.freePage(x)
+#endif
+
+#ifdef THIS_IS_MELON_KERNEL
Heap::Heap() : m_mutex(MUTEX_FALSE) {
+#else
+Heap::Heap() : m_mutex(MUTEX_FALSE), m_process(Process::get()) {
+#endif
m_usable = false;
m_index.data = 0;
m_index.size = 0;
@@ -11,7 +23,11 @@ Heap::~Heap() {
//TODO (optionnal) : free pages.
}
+#ifdef THIS_IS_MELON_KERNEL
void Heap::create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw) {
+#else
+void Heap::create(u32int start, u32int size, u32int idxsize) {
+#endif
if (m_usable) return;
if (start & 0x0FFF) start = (start & 0xFFFFF000) + 0x1000;
@@ -19,14 +35,19 @@ void Heap::create(u32int start, u32int size, u32int idxsize, PageDirectory* page
m_start = start + idxsize; //m_start is start of real data, start is start of index.
m_end = start + size;
+#ifdef THIS_IS_MELON_KERNEL
m_pagedir = pagedir;
m_user = user;
m_rw = rw;
+#endif
//Allocate frames for heap
for (u32int i = start ; i < m_end; i += 0x1000) {
- m_pagedir->allocFrame(i, m_user, m_rw);
+ ALLOC(i);
}
+#ifdef THIS_IS_MELON_KERNEL
+ m_pagedir->switchTo();
+#endif
m_index.data = (heap_header_t **)start; //Set index start. start == start of all heap
m_index.size = 0;
@@ -55,7 +76,7 @@ void Heap::expand(u32int quantity) {
u32int newEnd = m_end + quantity;
for (u32int i = m_end; i < newEnd; i++) {
- m_pagedir->allocFrame(i, m_user, m_rw);
+ ALLOC(i);
}
heap_footer_t *last_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t));
@@ -110,7 +131,7 @@ void Heap::contract() { //Automatically work out how much we can contract
insertIntoIndex(last_header);
for (u32int i = newEnd; i < m_end; i += 0x1000) {
- m_pagedir->freeFrame(i);
+ FREE(i);
}
m_end = newEnd;
diff --git a/Source/Kernel/MemoryManager/Heap.class.h b/Source/Library/Common/Heap.class.h
index 930a589..f5895c7 100644
--- a/Source/Kernel/MemoryManager/Heap.class.h
+++ b/Source/Library/Common/Heap.class.h
@@ -1,8 +1,8 @@
#ifndef DEF_HEAP_CLASS_H
#define DEF_HEAP_CLASS_H
-#include <Core/common.wtf.h>
-#include <TaskManager/Mutex.class.h>
+#include <common.h>
+#include <Mutex.class.h>
//Heap minimum size : 2M
#define HEAP_MIN_SIZE 0x00200000
@@ -25,14 +25,23 @@ struct heap_index_t {
u32int size;
};
+#ifdef THIS_IS_MELON_KERNEL
class PageDirectory;
+#else
+#include <Binding/Process.class.h>
+#endif
class Heap {
private:
- bool m_usable, m_user, m_rw;
u32int m_free, m_start, m_end;
+ bool m_usable;
heap_index_t m_index;
+#ifdef THIS_IS_MELON_KERNEL
+ bool m_user, m_rw;
PageDirectory* m_pagedir;
+#else
+ Process m_process;
+#endif
Mutex m_mutex;
@@ -48,7 +57,11 @@ class Heap {
Heap();
~Heap();
+#ifdef THIS_IS_MELON_KERNEL
void create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw);
+#else
+ void create(u32int start, u32int size, u32int idxsize);
+#endif
void* alloc(u32int sz, bool no_expand = false);
void free(void* ptr);
diff --git a/Source/Kernel/TaskManager/Mutex.class.cpp b/Source/Library/Common/Mutex.class.cpp
index 8ba274f..2e9a63c 100644
--- a/Source/Kernel/TaskManager/Mutex.class.cpp
+++ b/Source/Library/Common/Mutex.class.cpp
@@ -1,7 +1,18 @@
#include "Mutex.class.h"
+
+#ifdef THIS_IS_MELON_KERNEL
#include <TaskManager/Task.ns.h>
+#endif
+
+#ifdef THIS_IS_MELON_USERLAND
+#include <Binding/Thread.class.h>
+#endif
-extern "C" u32int atomic_exchange(u32int* ptr, u32int newval);
+u32int atomic_exchange(u32int* ptr, u32int newval) {
+ u32int r;
+ asm volatile("xchg (%%ecx), %%eax" : "=a"(r) : "c"(ptr), "a"(newval));
+ return r;
+}
Mutex::Mutex(u32int locked) {
m_locked = locked;
@@ -14,8 +25,14 @@ bool Mutex::lock() {
void Mutex::waitLock() {
while (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) {
+#ifdef THIS_IS_MELON_KERNEL
if (Task::currThread() != 0) Task::currThread()->sleep(10); //Wait 10ms
else return;
+#endif
+
+#ifdef THIS_IS_MELON_USERLAND
+ Thread::get().sleep(10);
+#endif
}
}
diff --git a/Source/Kernel/TaskManager/Mutex.class.h b/Source/Library/Common/Mutex.class.h
index 5545559..1e3f63d 100644
--- a/Source/Kernel/TaskManager/Mutex.class.h
+++ b/Source/Library/Common/Mutex.class.h
@@ -1,7 +1,7 @@
#ifndef DEF_MUTEX_CLASS_H
#define DEF_MUTEX_CLASS_H
-#include <Core/common.wtf.h>
+#include <common.h>
#define MUTEX_FALSE 0
#define MUTEX_TRUE 1
diff --git a/Source/Kernel/Library/OrderedArray.class.cpp b/Source/Library/Common/OrderedArray.class.cpp
index 8b8f24f..8b8f24f 100644
--- a/Source/Kernel/Library/OrderedArray.class.cpp
+++ b/Source/Library/Common/OrderedArray.class.cpp
diff --git a/Source/Kernel/Library/OrderedArray.class.h b/Source/Library/Common/OrderedArray.class.h
index 2a5acdd..3091249 100644
--- a/Source/Kernel/Library/OrderedArray.class.h
+++ b/Source/Library/Common/OrderedArray.class.h
@@ -1,7 +1,7 @@
#ifndef DEF_ORDARRAY_CLASS
#define DEF_ORDARRAY_CLASS
-#include <Core/common.wtf.h>
+#include <common.h>
template <typename T>
class OrderedArray {
diff --git a/Source/Kernel/Library/Rand.ns.cpp b/Source/Library/Common/Rand.ns.cpp
index e568678..e568678 100644
--- a/Source/Kernel/Library/Rand.ns.cpp
+++ b/Source/Library/Common/Rand.ns.cpp
diff --git a/Source/Kernel/Library/Rand.ns.h b/Source/Library/Common/Rand.ns.h
index 3598de0..71d4f60 100644
--- a/Source/Kernel/Library/Rand.ns.h
+++ b/Source/Library/Common/Rand.ns.h
@@ -1,7 +1,7 @@
#ifndef DEF_RAND_NS_H
#define DEF_RAND_NS_H
-#include <Core/common.wtf.h>
+#include <common.h>
namespace Rand {
u64int rand();
diff --git a/Source/Kernel/Library/SimpleList.class.h b/Source/Library/Common/SimpleList.class.h
index 64e37aa..7b731db 100644
--- a/Source/Kernel/Library/SimpleList.class.h
+++ b/Source/Library/Common/SimpleList.class.h
@@ -1,6 +1,8 @@
#ifndef DEF_SIMPLELIST_CLASS_H
#define DEF_SIMPLELIST_CLASS_H
+#include <common.h>
+
/* This class implements a singly linked list. It is also used to represent one of its elements. */
template <typename T>
@@ -34,7 +36,7 @@ class SimpleList {
SimpleList<T>* delThis() {
SimpleList<T>* ret = m_next;
- Mem::kfree(this);
+ Mem::free(this);
return ret;
}
@@ -42,7 +44,7 @@ class SimpleList {
if (m_next == 0) return;
SimpleList<T>* temp = m_next;
m_next = m_next->m_next;
- Mem::kfree(temp);
+ Mem::free(temp);
}
SimpleList<T>* removeOnce(const T& value) {
diff --git a/Source/Kernel/Library/String.class.cpp b/Source/Library/Common/String.class.cpp
index 693a11a..ac0eba0 100644
--- a/Source/Kernel/Library/String.class.cpp
+++ b/Source/Library/Common/String.class.cpp
@@ -1,5 +1,5 @@
#include "String.class.h"
-#include <Library/Vector.class.h>
+#include <Vector.class.h>
using namespace CMem; //strlen and memcpy
@@ -49,6 +49,26 @@ String String::number(s32int number) {
return ret;
}
+String String::unserialize(u32int w) {
+ u32int* a = (u32int*)w;
+ String ret;
+ ret.m_length = a[0];
+ ret.m_string = (WChar*)Mem::alloc(a[0] * sizeof(WChar));
+ for (u32int i = 0; i < a[0]; i++) {
+ ret[i] = a[i + 1];
+ }
+ return ret;
+}
+
+u32int String::serialize() const {
+ u32int* x = (u32int*)Mem::mkXchgSpace((m_length + 1) * sizeof(u32int));
+ x[0] = m_length;
+ for (u32int i = 0; i < m_length; i++) {
+ x[i + 1] = m_string[i];
+ }
+ return (u32int)x;
+}
+
String::String(const char* string, u8int encoding) {
m_string = 0;
m_length = 0;
diff --git a/Source/Kernel/Library/String.class.h b/Source/Library/Common/String.class.h
index db274c9..0d48ce6 100644
--- a/Source/Kernel/Library/String.class.h
+++ b/Source/Library/Common/String.class.h
@@ -1,15 +1,17 @@
#ifndef DEF_STRING_CLASS
#define DEF_STRING_CLASS
-#include <Core/common.wtf.h>
-#include <Library/WChar.class.h>
-#include <Library/BasicString.class.h>
+#include <BasicString.class.h>
+#include <WChar.class.h>
class String : public BasicString<WChar> {
public:
static String hex(u32int number);
static String number(s32int number);
+ static String unserialize(u32int w);
+ u32int serialize() const;
+
String(const char* string, u8int encoding = UE_UTF8);
String() : BasicString<WChar>() {}
String(const String &other) : BasicString<WChar> (other) {}
@@ -35,7 +37,7 @@ class String : public BasicString<WChar> {
String operator+ (const String &other) const { return concat(other); }
String operator+ (const char* other) const { return concat(other); }
String operator+ (WChar other) const { return concat(other); }
-
+
s64int toInt() const; //Convert from DEC
u64int toInt16() const; //Convert from HEX
diff --git a/Source/Kernel/Library/Vector.class.cpp b/Source/Library/Common/Vector.class.cpp
index 02ae9be..c546a42 100644
--- a/Source/Kernel/Library/Vector.class.cpp
+++ b/Source/Library/Common/Vector.class.cpp
@@ -4,7 +4,7 @@ using namespace CMem; //strlen and memcpy
for (u32int i = 0; i < m_size; i++) { \
m_data[i].~T(); \
} \
- Mem::kfree(m_data); \
+ Mem::free(m_data); \
}
template <typename T>
@@ -25,7 +25,7 @@ Vector<T>::Vector(u32int size) {
template <typename T>
Vector<T>::Vector(u32int size, const T& value) {
//DEBUG_HEX((u32int)this); DEBUG(" NEW FILLED");
- //m_data = (T*)Mem::kalloc(size * sizeof(T));
+ //m_data = (T*)Mem::alloc(size * sizeof(T));
m_data = new T[size];
m_size = size;
for (u32int i = 0; i < m_size; i++) {
@@ -40,7 +40,7 @@ template <typename T>
Vector<T>::Vector(const Vector<T> &other) {
//DEBUG_HEX((u32int)this); DEBUG(" COPY REF");
m_size = other.m_size;
- m_data = (T*)Mem::kalloc(m_size * sizeof(T));
+ m_data = (T*)Mem::alloc(m_size * sizeof(T));
for (u32int i = 0; i < m_size; i++) {
new(&m_data[i]) T(other.m_data[i]);
}
@@ -51,7 +51,7 @@ Vector<T>& Vector<T>::operator= (const Vector<T> &other) {
//DEBUG_HEX((u32int)this); DEBUG(" COPY EQ");
DELDATA;
m_size = other.m_size;
- m_data = (T*)Mem::kalloc(m_size * sizeof(T));
+ m_data = (T*)Mem::alloc(m_size * sizeof(T));
for (u32int i = 0; i < m_size; i++) {
new(&m_data[i]) T(other.m_data[i]);
}
@@ -72,14 +72,14 @@ T& Vector<T>::operator[] (u32int index) const {
template <typename T>
void Vector<T>::push(const T& element) {
- T* newdata = (T*)Mem::kalloc((m_size + 1) * sizeof(T));
+ T* newdata = (T*)Mem::alloc((m_size + 1) * sizeof(T));
if (m_size != 0 and m_data != 0) {
memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
}
new(&newdata[m_size]) T(element); //Construct by copy
//newdata[m_size] = element;
m_size++;
- Mem::kfree(m_data);
+ Mem::free(m_data);
m_data = newdata;
}
@@ -99,9 +99,9 @@ void Vector<T>::pop() {
m_size--;
//delete(&m_data[m_size], &m_data[m_size]); //implicitly call destructor with placement delete
m_data[m_size].~T(); //Call destructor
- T* newdata = (T*)Mem::kalloc(m_size * sizeof(T));
+ T* newdata = (T*)Mem::alloc(m_size * sizeof(T));
memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T));
- Mem::kfree(m_data);
+ Mem::free(m_data);
m_data = newdata;
}
diff --git a/Source/Kernel/Library/Vector.class.h b/Source/Library/Common/Vector.class.h
index 61c26a4..436e2f9 100644
--- a/Source/Kernel/Library/Vector.class.h
+++ b/Source/Library/Common/Vector.class.h
@@ -1,7 +1,7 @@
#ifndef DEF_VECTOR_CLASS
#define DEF_VECTOR_CLASS
-#include <Core/common.wtf.h>
+#include <common.h>
template <typename T>
class Vector {
diff --git a/Source/Kernel/Library/WChar.class.cpp b/Source/Library/Common/WChar.class.cpp
index ee42849..5485bb8 100644
--- a/Source/Kernel/Library/WChar.class.cpp
+++ b/Source/Library/Common/WChar.class.cpp
@@ -1,6 +1,10 @@
#include "WChar.class.h"
-#ifdef THIS_IS_MELON
+#ifdef THIS_IS_MELON_KERNEL
+using namespace CMem;
+#endif
+
+#ifdef THIS_IS_MELON_USERLAND
using namespace CMem;
#endif
diff --git a/Source/Kernel/Library/WChar.class.h b/Source/Library/Common/WChar.class.h
index e4da603..3eca3d3 100644
--- a/Source/Kernel/Library/WChar.class.h
+++ b/Source/Library/Common/WChar.class.h
@@ -1,10 +1,10 @@
#ifndef DEF_UCHAR_CLASS_H
#define DEF_UCHAR_CLASS_H
-#include <Core/types.wtf.h>
+#include <types.h>
#ifndef THIS_IS_NOT_MELON
-#include <Core/common.wtf.h>
+#include <common.h>
#endif
enum {
diff --git a/Source/Kernel/Core/types.wtf.h b/Source/Library/Common/types.h
index ca6f73d..ca6f73d 100644
--- a/Source/Kernel/Core/types.wtf.h
+++ b/Source/Library/Common/types.h
diff --git a/Source/Library/Interface/FSNode.iface.h b/Source/Library/Interface/FSNode.iface.h
new file mode 100644
index 0000000..482ebd2
--- /dev/null
+++ b/Source/Library/Interface/FSNode.iface.h
@@ -0,0 +1,14 @@
+#ifndef DEF_FSNODE_IFACE_H
+#define DEF_FSNODE_IFACE_H
+
+#define FNIF_OBJTYPE 0x14
+
+//S : static, GET : get, R : root, FN : fsnode
+#define FNIF_SGETRFN 0
+
+#define FNIF_GETNAME 0x10
+#define FNIF_TYPE 0x11
+#define FNIF_GETPARENT 0x12
+#define FNIF_GETLENGTH 0x13
+
+#endif
diff --git a/Source/Library/Interface/Process.iface.h b/Source/Library/Interface/Process.iface.h
new file mode 100644
index 0000000..2126dc6
--- /dev/null
+++ b/Source/Library/Interface/Process.iface.h
@@ -0,0 +1,13 @@
+#ifndef DEF_PROCESS_IFACE_H
+#define DEF_PROCESS_IFACE_H
+
+#define PRIF_OBJTYPE 0x20
+
+//S = static, GET = get, C = current, PR = process
+#define PRIF_SGETCPR 0
+
+#define PRIF_EXIT 0x01
+#define PRIF_ALLOCPAGE 0x02
+#define PRIF_FREEPAGE 0x03
+
+#endif
diff --git a/Source/Library/Interface/Thread.iface.h b/Source/Library/Interface/Thread.iface.h
new file mode 100644
index 0000000..0dac2e1
--- /dev/null
+++ b/Source/Library/Interface/Thread.iface.h
@@ -0,0 +1,12 @@
+#ifndef DEF_THREAD_IFACE_H
+#define DEF_THREAD_IFACE_H
+
+#define THIF_OBJTYPE 0x21
+
+//S = static, GET = get, C = current, TH = thread
+#define THIF_SGETCTH 0
+
+#define THIF_SLEEP 0x01
+#define THIF_FINISH 0x02
+
+#endif
diff --git a/Source/Library/Interface/VirtualTerminal.iface.h b/Source/Library/Interface/VirtualTerminal.iface.h
new file mode 100644
index 0000000..412cf8f
--- /dev/null
+++ b/Source/Library/Interface/VirtualTerminal.iface.h
@@ -0,0 +1,21 @@
+#ifndef DEF_VITRUALTERMINAL_IFACE_H
+#define DEF_VITRUALTERMINAL_IFACE_H
+
+#define VTIF_OBJTYPE 0x10
+
+//S = static, GET = get, PR = process, VT = virtualterminal
+#define VTIF_SGETPRVT 0
+
+#define VTIF_PUT 0x01
+#define VTIF_WRITEHEX 0x02
+#define VTIF_WRITEDEC 0x03
+#define VTIF_WRITE 0x04
+
+#define VTIF_READLINE 0x05
+
+#define VTIF_SETCOLOR 0x10
+#define VTIF_SETCSRLINE 0x11
+#define VTIF_SETCSRCOL 0x12
+#define VTIF_ISBOXED 0x13
+
+#endif
diff --git a/Source/Library/Link.ld b/Source/Library/Link.ld
new file mode 100644
index 0000000..f06f568
--- /dev/null
+++ b/Source/Library/Link.ld
@@ -0,0 +1,32 @@
+ENTRY (start)
+
+SECTIONS{
+ . = 0x10000000;
+
+ .text : {
+ *(.text)
+ }
+
+ .rodata ALIGN (0x1000) :{
+ *(.rodata)
+ }
+
+ .data ALIGN (0x1000) : {
+ start_ctors = .;
+ *(.ctor*)
+ end_ctors = .;
+ start_dtors = .;
+ *(.dtor*)
+ end_dtors = .;
+ *(.data)
+ }
+
+ .bss : {
+ sbss = .;
+ *(COMMON)
+ *(.bss)
+ ebss = .;
+ }
+
+ end = .; _end = .; __end = .;
+}
diff --git a/Source/Library/Makefile b/Source/Library/Makefile
new file mode 100644
index 0000000..a4b9b6a
--- /dev/null
+++ b/Source/Library/Makefile
@@ -0,0 +1,46 @@
+.PHONY: clean, mrproper
+
+CXX = g++
+CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I Common -I Userland -I Interface -D THIS_IS_MELON_USERLAND
+
+ASM = nasm
+ASMFLAGS = -f elf
+
+LDFLAGS = -r
+LD = ld
+
+Library = Melon.o
+Objects = Common/WChar.class.uo \
+ Common/CMem.ns.uo \
+ Common/Mutex.class.uo \
+ Common/Heap.class.uo \
+ Common/Heap-index.class.uo \
+ Common/String.class.uo \
+ Userland/Syscall/Syscall.wtf.uo \
+ Userland/Syscall/RessourceCaller.class.uo \
+ Userland/Start.uo
+
+all: $(Library)
+ echo "* Done with library"
+
+rebuild: mrproper all
+
+$(Library): $(Objects)
+ echo "* Linking melon library $(Library)..."
+ $(LD) $(LDFLAGS) $^ -o $@
+
+%.uo: %.cpp
+ echo "* Compiling $<..."
+ $(CXX) $(CXXFLAGS) -c $< -o $@
+
+%.uo: %.asm
+ echo "* Compiling $<..."
+ $(ASM) $(ASMFLAGS) $< -o $@
+
+clean:
+ echo "* Removing object files..."
+ rm -rf $(Objects)
+
+mrproper: clean
+ echo "* Removing library..."
+ rm -rf $(Library)
diff --git a/Source/Library/Userland/Binding/FSNode.class.h b/Source/Library/Userland/Binding/FSNode.class.h
new file mode 100644
index 0000000..eb25782
--- /dev/null
+++ b/Source/Library/Userland/Binding/FSNode.class.h
@@ -0,0 +1,23 @@
+#include <Syscall/RessourceCaller.class.h>
+#include <FSNode.iface.h>
+
+class FSNode : public RessourceCaller {
+ public:
+ static FSNode getRoot() {
+ return FSNode(RessourceCaller::sCall(FNIF_OBJTYPE, FNIF_SGETRFN));
+ }
+ FSNode(u32int id) : RessourceCaller(id, FNIF_OBJTYPE) {}
+
+ String getName() {
+ return String::unserialize(doCall(FNIF_GETNAME));
+ }
+ u8int type() {
+ return doCall(FNIF_TYPE);
+ }
+ FSNode getParent() {
+ return FSNode(doCall(FNIF_GETPARENT));
+ }
+ u64int getLength() {
+ return *((u64int*)doCall(FNIF_GETLENGTH));
+ }
+};
diff --git a/Source/Library/Userland/Binding/Process.class.h b/Source/Library/Userland/Binding/Process.class.h
new file mode 100644
index 0000000..00afe27
--- /dev/null
+++ b/Source/Library/Userland/Binding/Process.class.h
@@ -0,0 +1,22 @@
+#include <Syscall/RessourceCaller.class.h>
+
+#include <Process.iface.h>
+
+class Process : public RessourceCaller {
+ public:
+ static Process get() {
+ u32int id = RessourceCaller::sCall(PRIF_OBJTYPE, PRIF_SGETCPR);
+ return Process(id);
+ }
+ Process(u32int id) : RessourceCaller(id, PRIF_OBJTYPE) {}
+
+ void exit() {
+ doCall(PRIF_EXIT);
+ }
+ void allocPage(u32int pos) {
+ doCall(PRIF_ALLOCPAGE, pos);
+ }
+ void freePage(u32int pos) {
+ doCall(PRIF_FREEPAGE, pos);
+ }
+};
diff --git a/Source/Library/Userland/Binding/Thread.class.h b/Source/Library/Userland/Binding/Thread.class.h
new file mode 100644
index 0000000..a19c256
--- /dev/null
+++ b/Source/Library/Userland/Binding/Thread.class.h
@@ -0,0 +1,19 @@
+#include <Syscall/RessourceCaller.class.h>
+
+#include <Thread.iface.h>
+
+class Thread : public RessourceCaller {
+ public:
+ static Thread get() {
+ u32int id = RessourceCaller::sCall(THIF_OBJTYPE, THIF_SGETCTH);
+ return Thread(id);
+ }
+ Thread(u32int id) : RessourceCaller(id, THIF_OBJTYPE) {}
+
+ void sleep(u32int msecs) {
+ doCall(THIF_SLEEP, msecs);
+ }
+ void finish(u32int errcode) {
+ doCall(THIF_FINISH, errcode);
+ }
+};
diff --git a/Source/Library/Userland/Binding/VirtualTerminal.class.h b/Source/Library/Userland/Binding/VirtualTerminal.class.h
new file mode 100644
index 0000000..9d438c6
--- /dev/null
+++ b/Source/Library/Userland/Binding/VirtualTerminal.class.h
@@ -0,0 +1,48 @@
+#include <Syscall/RessourceCaller.class.h>
+
+#include <VirtualTerminal.iface.h>
+
+#include <String.class.h>
+#include <WChar.class.h>
+
+class VirtualTerminal : public RessourceCaller {
+ public:
+ static VirtualTerminal get() {
+ u32int id = RessourceCaller::sCall(VTIF_OBJTYPE, VTIF_SGETPRVT);
+ return VirtualTerminal(id);
+ }
+ VirtualTerminal(u32int id) : RessourceCaller(id, VTIF_OBJTYPE) {}
+
+ void writeHex(u32int number) {
+ doCall(VTIF_WRITEHEX, number);
+ }
+ void writeDec(s64int number) {
+ doCall(VTIF_WRITEDEC, (number >> 32), number);
+ }
+ void write(String s) {
+ doCall(VTIF_WRITE, (u32int)&s);
+ }
+ String readLine() {
+ return String::unserialize(doCall(VTIF_READLINE));
+ }
+ void setColor(u8int fg, u8int bg = 0xFF) {
+ doCall(VTIF_SETCOLOR, (fg << 8) | bg);
+ }
+ void setCsrLine(u32int line) {
+ doCall(VTIF_SETCSRLINE, line);
+ }
+ void setCsrCol(u32int col) {
+ doCall(VTIF_SETCSRCOL, col);
+ }
+ bool isBoxed() {
+ return doCall(VTIF_ISBOXED) != 0;
+ }
+ void put(WChar c) {
+ doCall(VTIF_PUT, c);
+ }
+
+ inline VirtualTerminal& operator<<(const String& s) { write(s); return *this; }
+ inline VirtualTerminal& operator<<(s32int i) { writeDec(i); return *this; }
+ inline VirtualTerminal& operator<<(s64int i) { writeDec(i); return *this; }
+ inline VirtualTerminal& operator<<(u32int i) { writeHex(i); return *this; }
+};
diff --git a/Source/Library/Userland/Start.cpp b/Source/Library/Userland/Start.cpp
new file mode 100644
index 0000000..639210f
--- /dev/null
+++ b/Source/Library/Userland/Start.cpp
@@ -0,0 +1,36 @@
+#include <types.h>
+
+#include <Heap.class.h>
+
+extern "C" void __cxa_pure_virtual() {} //Required when using abstract classes
+void *__dso_handle; //Required when using global objects
+extern "C" int __cxa_atexit(void (*f)(void*), void *p, void *d) { return 0; }
+
+extern u32int start_ctors, end_ctors, start_dtors, end_dtors;
+
+Heap heap;
+
+int main();
+
+extern "C" void start() {
+ //Call static constructors
+ for(u32int * call = &start_ctors; call < &end_ctors; call++) {
+ ((void (*)(void))*call)();
+ }
+
+ heap.create(0x40000000, 0x00100000, 0x00004000); //Initially create a 1M heap with 16ko index
+ u32int r = main();
+
+ //Call static destructors
+ for(u32int * call = &start_dtors; call < &end_dtors; call++) {
+ ((void (*)(void))*call)();
+ }
+
+ asm volatile("int $66" : : "a"(r));
+}
+
+namespace Mem {
+ void* alloc (u32int sz) { return heap.alloc(sz); }
+ void free(void* ptr) { heap.free(ptr); }
+ void* mkXchgSpace (u32int sz) { return alloc(sz); }
+}
diff --git a/Source/Library/Userland/Syscall/RessourceCaller.class.cpp b/Source/Library/Userland/Syscall/RessourceCaller.class.cpp
new file mode 100644
index 0000000..f3b61a8
--- /dev/null
+++ b/Source/Library/Userland/Syscall/RessourceCaller.class.cpp
@@ -0,0 +1,18 @@
+#include "RessourceCaller.class.h"
+
+RessourceCaller::RessourceCaller(u32int id, u32int type) {
+ m_id = id;
+ m_type = 1;
+ m_type = doCall(0);
+ if (m_type != type) m_type = 0;
+}
+
+u32int RessourceCaller::sCall(u32int type, u8int wat, u32int a, u32int b, u32int c, u32int d) {
+ return syscall(0xFFFFFE00 | wat, type, a, b, c, d);
+}
+
+u32int RessourceCaller::doCall(u8int call, u32int a, u32int b, u32int c, u32int d, u32int e) {
+ if (m_type == 0) return (u32int) - 1; //Type 0 = invalid object
+ u32int x = ((m_id << 8) | call);
+ return syscall(x, a, b, c, d, e);
+}
diff --git a/Source/Library/Userland/Syscall/RessourceCaller.class.h b/Source/Library/Userland/Syscall/RessourceCaller.class.h
new file mode 100644
index 0000000..85beacf
--- /dev/null
+++ b/Source/Library/Userland/Syscall/RessourceCaller.class.h
@@ -0,0 +1,36 @@
+#ifndef DEF_RESSOURCECALLER_CLASS_H
+#define DEF_RESSOURCECALLER_CLASS_H
+
+#include <Syscall/Syscall.wtf.h>
+#include <common.h>
+
+class Serialized {
+ private:
+ u32int m_value;
+
+ public:
+ Serialized(u32int v) : m_value(v) {}
+ ~Serialized() { Mem::free( (void*)m_value); }
+ operator u32int () { return m_value; }
+};
+
+class RessourceCaller {
+ private:
+ u32int m_id;
+ u32int m_type;
+
+ protected:
+ RessourceCaller(u32int id, u32int type);
+
+ //Static call -- a call specific to a class and not an object
+ static u32int sCall(u32int type, u8int wat, u32int a = 0, u32int b = 0, u32int c = 0, u32int d = 0);
+
+ u32int doCall(u8int call, u32int a = 0, u32int b = 0, u32int c = 0, u32int d = 0, u32int e = 0);
+
+ public:
+ u32int resId() { return m_id; }
+ u32int resType() { return m_type; }
+ bool valid() { return m_type != 0; }
+};
+
+#endif
diff --git a/Source/Library/Userland/Syscall/Syscall.wtf.cpp b/Source/Library/Userland/Syscall/Syscall.wtf.cpp
new file mode 100644
index 0000000..a28c202
--- /dev/null
+++ b/Source/Library/Userland/Syscall/Syscall.wtf.cpp
@@ -0,0 +1,21 @@
+#include "Syscall.wtf.h"
+
+u32int syscall(u32int n, u32int a, u32int b, u32int c, u32int d, u32int e) {
+ u32int r;
+ asm volatile ("int $64;"
+ : "=a"(r) : "a"(n), "b"(a), "c"(b), "d"(c), "D"(d), "S"(e));
+ return r;
+}
+
+void putch(char c) {
+ u32int x = c;
+ syscall(0xFFFFFF01, x);
+}
+
+void sleep(u32int t) {
+ syscall(0xFFFFFF02, t);
+}
+
+void write_hex(u32int n) {
+ syscall(0XFFFFFF03, n);
+}
diff --git a/Source/Library/Userland/Syscall/Syscall.wtf.h b/Source/Library/Userland/Syscall/Syscall.wtf.h
new file mode 100644
index 0000000..0401a89
--- /dev/null
+++ b/Source/Library/Userland/Syscall/Syscall.wtf.h
@@ -0,0 +1,13 @@
+#ifndef DEF_SYSCALL_WTF_H
+#define DEF_SYSCALL_WTF_H
+
+#include <types.h>
+
+//Three basic syscalls, just for testing
+void putch(char);
+void sleep(u32int);
+void write_hex(u32int);
+
+u32int syscall(u32int n, u32int a, u32int b = 0, u32int c = 0, u32int d = 0, u32int e = 0);
+
+#endif
diff --git a/Source/Library/Userland/common.h b/Source/Library/Userland/common.h
new file mode 100644
index 0000000..6257841
--- /dev/null
+++ b/Source/Library/Userland/common.h
@@ -0,0 +1,27 @@
+#ifndef DEF_COMMON
+#define DEF_COMMON
+
+#define NULL 0
+
+#include <types.h>
+
+#include <CMem.ns.h>
+
+namespace Mem {
+ void* alloc(u32int);
+ void free(void*);
+ void* mkXchgSpace(u32int sz);
+}
+
+//Standard implemenations of operator new/delete
+inline void* operator new(u32int, void *p) { return p; }
+inline void* operator new[](u32int, void *p) { return p; }
+inline void operator delete(void*, void*) { }
+inline void operator delete[](void*, void*) { }
+
+inline void* operator new(u32int sz) { return Mem::alloc(sz); }
+inline void* operator new[](u32int sz) { return Mem::alloc(sz); }
+inline void operator delete(void *ptr) { Mem::free(ptr); }
+inline void operator delete[](void *ptr) { Mem::free(ptr); }
+
+#endif
diff --git a/Source/Tools/MakeRamFS/MakeRamFS b/Source/Tools/MakeRamFS/MakeRamFS
deleted file mode 100755
index be1dc1a..0000000
--- a/Source/Tools/MakeRamFS/MakeRamFS
+++ /dev/null
Binary files differ