diff options
20 files changed, 167 insertions, 23 deletions
@@ -1,5 +1,6 @@ *.swp *.o +*.uo Init.rfs Source/Kernel/Map.txt Source/Kernel/Melon.ke diff --git a/Source/Applications/SampleApps/Makefile b/Source/Applications/SampleApps/Makefile index d45011e..a632f87 100644 --- a/Source/Applications/SampleApps/Makefile +++ b/Source/Applications/SampleApps/Makefile @@ -7,7 +7,7 @@ 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 = --entry=start -Ttext=40000000 +LDFLAGS = -T ../../Library/Link.ld Applications = asmdemo cxxdemo 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/Makefile b/Source/Kernel/Makefile index a090ac6..1c83e5a 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -16,8 +16,6 @@ Objects = Core/loader.wtf.o \ Core/Sys.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 \ @@ -31,7 +29,6 @@ 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 \ @@ -52,6 +49,9 @@ Objects = Core/loader.wtf.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 \ @@ -95,6 +95,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/Mem.ns.cpp b/Source/Kernel/MemoryManager/Mem.ns.cpp index 6c64a53..c705b3b 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.cpp +++ b/Source/Kernel/MemoryManager/Mem.ns.cpp @@ -1,6 +1,6 @@ #include <common.h> #include <MemoryManager/PhysMem.ns.h> -#include <MemoryManager/Heap.class.h> +#include <Heap.class.h> namespace Mem { diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index 39428b4..aae8fce 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -57,6 +57,7 @@ Process* Process::run(String filename, FSNode* cwd, u32int uid) { Process::Process(String cmdline, u32int uid) : Ressource(PR_IFACE_OBJTYPE) { addCall0(PR_IFACE_EXIT, (call0)&Process::exitSC); addCall1(PR_IFACE_ALLOCPAGE, (call1)&Process::allocPageSC); + addCall1(PR_IFACE_FREEPAGE, (call1)&Process::freePageSC); m_pid = Task::nextPid(); m_cmdline = cmdline; m_retval = 0; @@ -150,3 +151,11 @@ u32int Process::allocPageSC(u32int pos) { 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 1b614b7..afdfe20 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -5,7 +5,7 @@ #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> @@ -72,6 +72,7 @@ class Process : public Ressource { //System calls u32int exitSC(); u32int allocPageSC(u32int); + u32int freePageSC(u32int); }; #endif diff --git a/Source/Kernel/TaskManager/Task.wtf.asm b/Source/Kernel/TaskManager/Task.wtf.asm index 36c1ade..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. diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.h b/Source/Kernel/VTManager/VirtualTerminal.proto.h index 487233d..b9d0eb8 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.h +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h @@ -3,7 +3,7 @@ #include <common.h> #include <String.class.h> -#include <TaskManager/Mutex.class.h> +#include <Mutex.class.h> #include <DeviceManager/Kbd.ns.h> #include <Vector.class.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 365b4f0..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,15 +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; @@ -56,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)); @@ -111,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 291c9ce..f5895c7 100644 --- a/Source/Kernel/MemoryManager/Heap.class.h +++ b/Source/Library/Common/Heap.class.h @@ -2,7 +2,7 @@ #define DEF_HEAP_CLASS_H #include <common.h> -#include <TaskManager/Mutex.class.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 1e3f63d..1e3f63d 100644 --- a/Source/Kernel/TaskManager/Mutex.class.h +++ b/Source/Library/Common/Mutex.class.h diff --git a/Source/Library/Interface/Process.iface.h b/Source/Library/Interface/Process.iface.h index d639725..0956679 100644 --- a/Source/Library/Interface/Process.iface.h +++ b/Source/Library/Interface/Process.iface.h @@ -4,5 +4,6 @@ #define PR_IFACE_OBJTYPE 0x20 #define PR_IFACE_EXIT 0x01 #define PR_IFACE_ALLOCPAGE 0x02 +#define PR_IFACE_FREEPAGE 0x03 #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 index b9be0a0..028e7a4 100644 --- a/Source/Library/Makefile +++ b/Source/Library/Makefile @@ -1,7 +1,10 @@ .PHONY: clean, mrproper CXX = g++ -CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I Common -I Userland -D THIS_IS_MELON_USERLAND +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 @@ -9,6 +12,9 @@ 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 \ Userland/Syscall/Syscall.wtf.uo \ Userland/Syscall/RessourceCaller.class.uo \ Userland/Start.uo @@ -26,6 +32,10 @@ $(Library): $(Objects) echo "* Compiling $<..." $(CXX) $(CXXFLAGS) -c $< -o $@ +%.uo: %.asm + echo "* Compiling $<..." + $(ASM) $(ASMFLAGS) $< -o $@ + clean: echo "* Removing object files..." rm -rf $(Objects) diff --git a/Source/Library/Userland/Binding/Process.class.h b/Source/Library/Userland/Binding/Process.class.h index c484e19..88af9d6 100644 --- a/Source/Library/Userland/Binding/Process.class.h +++ b/Source/Library/Userland/Binding/Process.class.h @@ -16,4 +16,7 @@ class Process : public RessourceCaller { void allocPage(u32int pos) { doCall(PR_IFACE_ALLOCPAGE, pos); } + void freePage(u32int pos) { + doCall(PR_IFACE_FREEPAGE, pos); + } }; diff --git a/Source/Library/Userland/Start.cpp b/Source/Library/Userland/Start.cpp index 02eb951..e185189 100644 --- a/Source/Library/Userland/Start.cpp +++ b/Source/Library/Userland/Start.cpp @@ -1,8 +1,35 @@ #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, 0x00003000); //Initially create a 1M heap with 12ko 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); } +} diff --git a/Source/Library/Userland/common.h b/Source/Library/Userland/common.h index 27218f7..3508513 100644 --- a/Source/Library/Userland/common.h +++ b/Source/Library/Userland/common.h @@ -7,4 +7,20 @@ #include <CMem.ns.h> +namespace Mem { + void* alloc(u32int); + void free(void*); +} + +//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 |