From ae49f59cc96e4ff3709c857b848132e82e6e0b14 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sat, 17 Oct 2009 18:20:46 +0200 Subject: User mode code can now run ! We have a sample process (hardcoded in ASM in Task.wtf.asm) that displays a's and sleeps 20ms, but it's on a hidden virtual terminal so it's useless :D --- Source/Kernel/Core/Sys.ns.cpp | 9 ++++- Source/Kernel/Core/kmain.wtf.cpp | 11 ++++++ Source/Kernel/MemoryManager/GDT.ns.cpp | 22 +++++++++++ Source/Kernel/MemoryManager/GDT.ns.h | 32 ++++++++++++++++ Source/Kernel/MemoryManager/GDT.wtf.asm | 6 +++ Source/Kernel/MemoryManager/PhysMem.ns.cpp | 1 - Source/Kernel/SyscallManager/IDT.ns.cpp | 11 +++++- Source/Kernel/TaskManager/Task.ns.cpp | 5 ++- Source/Kernel/TaskManager/Task.wtf.asm | 15 ++++++++ Source/Kernel/TaskManager/Thread.class.cpp | 59 +++++++++++++++++++++++++++--- Source/Kernel/TaskManager/Thread.class.h | 1 + 11 files changed, 162 insertions(+), 10 deletions(-) diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp index c0218d8..a8a6c91 100644 --- a/Source/Kernel/Core/Sys.ns.cpp +++ b/Source/Kernel/Core/Sys.ns.cpp @@ -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/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index c7b47e1..655bd8b 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -35,6 +35,9 @@ extern u32int end; //Placement address extern "C" void kmain(multiboot_info_t* mbd, u32int magic); +extern "C" void sample_task(); +extern u32int sample_task_size; + #define INFO(vt) vt->setColor(KVT_FGCOLOR); *vt << " - "; vt->setColor(KVT_LIGHTCOLOR); #define PROCESSING(vt, m) vt->setColor(KVT_BLECOLOR); *vt << " > "; vt->setColor(KVT_FGCOLOR); *vt << m; \ vt->setCursorCol(60); vt->setColor(KVT_LIGHTCOLOR); *vt << ": "; @@ -164,6 +167,14 @@ void kmain(multiboot_info_t* mbd, u32int magic) { FloppyController::detect(); Log::log(KL_STATUS, "kmain : Floppy drives detected"); + //Create dummy process, for testing user mode + Process* p; + p = new Process("dummy task", 0); + u8int *ptr = (u8int*)p->heap().alloc(sample_task_size); + memcpy(ptr, (const u8int*)sample_task, sample_task_size); + new Thread(p, (thread_entry_t)ptr, 0); + kernelPageDirectory->switchTo(); + asm volatile("sti"); Log::log(KL_STATUS, "kmain : Interrupts enabled."); 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..94306a4 100644 --- a/Source/Kernel/MemoryManager/GDT.ns.h +++ b/Source/Kernel/MemoryManager/GDT.ns.h @@ -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/PhysMem.ns.cpp b/Source/Kernel/MemoryManager/PhysMem.ns.cpp index 382e8a4..eb6fbf1 100644 --- a/Source/Kernel/MemoryManager/PhysMem.ns.cpp +++ b/Source/Kernel/MemoryManager/PhysMem.ns.cpp @@ -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/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index fcab741..fcdf2ff 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -55,6 +55,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 +74,13 @@ 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) { + if (regs.eax == 1) { + Task::currProcess()->getVirtualTerminal()->put(WChar(regs.ebx)); + } else if (regs.eax == 2) { + Task::currThread()->sleep(regs.ebx); + } + } 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 +97,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 +169,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/TaskManager/Task.ns.cpp b/Source/Kernel/TaskManager/Task.ns.cpp index a34f14f..1d1676e 100644 --- a/Source/Kernel/TaskManager/Task.ns.cpp +++ b/Source/Kernel/TaskManager/Task.ns.cpp @@ -94,8 +94,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; \ diff --git a/Source/Kernel/TaskManager/Task.wtf.asm b/Source/Kernel/TaskManager/Task.wtf.asm index 77db18e..2e5b9f8 100644 --- a/Source/Kernel/TaskManager/Task.wtf.asm +++ b/Source/Kernel/TaskManager/Task.wtf.asm @@ -47,3 +47,18 @@ copy_page_physical: popf ; Pop EFLAGS back. pop ebx ; Get the original value of EBX back. ret + + +[GLOBAL sample_task] +sample_task: + mov eax, 0x00000001 ;temporarily defined as syscall id for writing one char to screen + mov ebx, 'a' ;loopingly write a's to screen + int 64 + mov eax, 0x00000002 ;temporary syscall for sleeping + mov ebx, 20 ;20ms + int 64 + jmp sample_task + int 66 ;finish task - will never happen since we have an infinite loop +[GLOBAL sample_task_size] +sample_task_size: + dd sample_task_size - sample_task diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 6d62474..63d8160 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -2,11 +2,51 @@ #include #include #include +#include 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 @@ -27,7 +67,10 @@ Thread::Thread(Process* process, thread_entry_t entry_point, void* data) { Thread::~Thread() { Task::unregisterThread(this); Mem::kfree(m_kernelStack.addr); - if (!m_isKernel) m_process->heap().free(m_userStack.addr); + if (m_userStack.addr != 0) { + m_process->getPagedir()->switchTo(); + m_process->heap().free(m_userStack.addr); + } //Don't unregister thread in process, it has probably already been done } @@ -111,11 +154,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,6 +167,10 @@ 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; } diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h index 9c8fa26..aeb1f93 100644 --- a/Source/Kernel/TaskManager/Thread.class.h +++ b/Source/Kernel/TaskManager/Thread.class.h @@ -43,6 +43,7 @@ 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(); -- cgit v1.2.3 From e35e95188674ae4802df2a511825218253d01d2c Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sat, 17 Oct 2009 18:34:38 +0200 Subject: nothing --- Source/Kernel/VTManager/SimpleVT.class.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Source/Kernel/VTManager/SimpleVT.class.cpp b/Source/Kernel/VTManager/SimpleVT.class.cpp index 9639d50..89391b2 100644 --- a/Source/Kernel/VTManager/SimpleVT.class.cpp +++ b/Source/Kernel/VTManager/SimpleVT.class.cpp @@ -82,6 +82,7 @@ void SimpleVT::scroll() { } void SimpleVT::updateCursor() { + if (!m_mapped) return; Disp::moveCursor(m_csrlin + m_maprow, m_csrcol + m_mapcol); } @@ -126,7 +127,7 @@ void SimpleVT::put(WChar c, bool updatecsr) { scroll(); m_csrlin--; } - if (updatecsr) updateCursor(); + if (updatecsr && m_mapped) updateCursor(); } void SimpleVT::hexDump(u8int *ptr, u32int sz, bool addnl) { -- cgit v1.2.3 From 7dc8c19f7d6220c9e3dac43796faf77c4f11974f Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sat, 17 Oct 2009 23:22:41 +0200 Subject: Melon now loads a simple ASM application out of the ramfs The format is very simple, but an ELF loader is planned. --- .gitignore | 1 + Init.rfs | Bin 3984 -> 4081 bytes Makefile | 3 +- .../2009-10-17-225953_728x426_scrot.png | Bin 0 -> 17989 bytes .../2009-10-17-230014_728x426_scrot.png | Bin 0 -> 19788 bytes Source/Applications/ASMApps/Makefile | 20 +++++++++++++ Source/Applications/ASMApps/syscalls.asm | 7 +++++ Source/Applications/ASMApps/test | Bin 0 -> 62 bytes Source/Applications/ASMApps/test.asm | 20 +++++++++++++ Source/Kernel/Core/kmain.wtf.cpp | 13 +-------- Source/Kernel/MemoryManager/Heap.class.cpp | 1 + Source/Kernel/Shell/KernelShell-fs.class.cpp | 31 +++++++++++++++++++++ Source/Kernel/Shell/KernelShell.class.cpp | 3 ++ Source/Kernel/Shell/KernelShell.class.h | 1 + Source/Kernel/SyscallManager/IDT.ns.cpp | 4 +-- Source/Kernel/TaskManager/Process.class.cpp | 3 +- Source/Kernel/TaskManager/Process.class.h | 1 + Source/Kernel/TaskManager/Task.ns.cpp | 2 +- Source/Kernel/TaskManager/Task.wtf.asm | 13 --------- Source/Kernel/TaskManager/Thread.class.cpp | 1 - Source/Kernel/VTManager/SimpleVT.class.cpp | 2 +- .../Kernel/VTManager/VirtualTerminal-kbd.proto.cpp | 3 +- Source/Kernel/VTManager/VirtualTerminal.proto.cpp | 2 +- 23 files changed, 97 insertions(+), 34 deletions(-) create mode 100644 Media/Screenshots/2009-10-17-225953_728x426_scrot.png create mode 100644 Media/Screenshots/2009-10-17-230014_728x426_scrot.png create mode 100644 Source/Applications/ASMApps/Makefile create mode 100644 Source/Applications/ASMApps/syscalls.asm create mode 100644 Source/Applications/ASMApps/test create mode 100644 Source/Applications/ASMApps/test.asm diff --git a/.gitignore b/.gitignore index e604120..2cf7152 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ *.swp *.o +Init.rfs Source/Kernel/Map.txt Source/Kernel/Melon.ke diff --git a/Init.rfs b/Init.rfs index d3023af..b10aa86 100644 Binary files a/Init.rfs and b/Init.rfs differ diff --git a/Makefile b/Makefile index 9a7d72a..508aa76 100644 --- a/Makefile +++ b/Makefile @@ -1,12 +1,13 @@ .PHONY: clean, mrproper, Init.rfs -Projects = Kernel Tools/MakeRamFS +Projects = Kernel Tools/MakeRamFS Applications/ASMApps 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/ASMApps/test:/System/Applications/Test \ :/Useless \ Source/Kernel/Ressources/Texts/Info.txt:/Useless/Info.txt \ Source/Kernel/Ressources/Graphics/logo.text.cxd:/Useless/Melon-logo 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 Binary files /dev/null and b/Media/Screenshots/2009-10-17-225953_728x426_scrot.png 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 Binary files /dev/null and b/Media/Screenshots/2009-10-17-230014_728x426_scrot.png differ diff --git a/Source/Applications/ASMApps/Makefile b/Source/Applications/ASMApps/Makefile new file mode 100644 index 0000000..8cc8bfd --- /dev/null +++ b/Source/Applications/ASMApps/Makefile @@ -0,0 +1,20 @@ +.PHONY: clean, mrproper + +ASM = nasm + +Applications = test + +all: $(Applications) + echo "* Done with ASM applications : $(Applications)" + +rebuild: mrproper all + +%: %.asm + echo "* Compiling $<..." + $(ASM) -o $@ $< + +clean: + echo "* Removing files..." + rm -rf $(Applications) + +mrproper: clean diff --git a/Source/Applications/ASMApps/syscalls.asm b/Source/Applications/ASMApps/syscalls.asm new file mode 100644 index 0000000..cdd5cc6 --- /dev/null +++ b/Source/Applications/ASMApps/syscalls.asm @@ -0,0 +1,7 @@ +[bits 32] + +dd 0xFEEDBEEF ; magic number ^^ +dd end - start + +%define SC_PUTCH 0xFFFFFF01 +%define SC_SLEEP 0xFFFFFF02 diff --git a/Source/Applications/ASMApps/test b/Source/Applications/ASMApps/test new file mode 100644 index 0000000..397abf1 Binary files /dev/null and b/Source/Applications/ASMApps/test differ diff --git a/Source/Applications/ASMApps/test.asm b/Source/Applications/ASMApps/test.asm new file mode 100644 index 0000000..80965b4 --- /dev/null +++ b/Source/Applications/ASMApps/test.asm @@ -0,0 +1,20 @@ +%include "syscalls.asm" + +start: + mov ecx, ' ' + 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 +end: diff --git a/Source/Kernel/Core/kmain.wtf.cpp b/Source/Kernel/Core/kmain.wtf.cpp index 655bd8b..87e95de 100644 --- a/Source/Kernel/Core/kmain.wtf.cpp +++ b/Source/Kernel/Core/kmain.wtf.cpp @@ -35,9 +35,6 @@ extern u32int end; //Placement address extern "C" void kmain(multiboot_info_t* mbd, u32int magic); -extern "C" void sample_task(); -extern u32int sample_task_size; - #define INFO(vt) vt->setColor(KVT_FGCOLOR); *vt << " - "; vt->setColor(KVT_LIGHTCOLOR); #define PROCESSING(vt, m) vt->setColor(KVT_BLECOLOR); *vt << " > "; vt->setColor(KVT_FGCOLOR); *vt << m; \ vt->setCursorCol(60); vt->setColor(KVT_LIGHTCOLOR); *vt << ": "; @@ -167,20 +164,12 @@ void kmain(multiboot_info_t* mbd, u32int magic) { FloppyController::detect(); Log::log(KL_STATUS, "kmain : Floppy drives detected"); - //Create dummy process, for testing user mode - Process* p; - p = new Process("dummy task", 0); - u8int *ptr = (u8int*)p->heap().alloc(sample_task_size); - memcpy(ptr, (const u8int*)sample_task, sample_task_size); - new Thread(p, (thread_entry_t)ptr, 0); - kernelPageDirectory->switchTo(); - asm volatile("sti"); Log::log(KL_STATUS, "kmain : Interrupts enabled."); 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/MemoryManager/Heap.class.cpp b/Source/Kernel/MemoryManager/Heap.class.cpp index 7331cd0..365b4f0 100644 --- a/Source/Kernel/MemoryManager/Heap.class.cpp +++ b/Source/Kernel/MemoryManager/Heap.class.cpp @@ -27,6 +27,7 @@ void Heap::create(u32int start, u32int size, u32int idxsize, PageDirectory* page for (u32int i = start ; i < m_end; i += 0x1000) { m_pagedir->allocFrame(i, m_user, m_rw); } + m_pagedir->switchTo(); m_index.data = (heap_header_t **)start; //Set index start. start == start of all heap m_index.size = 0; diff --git a/Source/Kernel/Shell/KernelShell-fs.class.cpp b/Source/Kernel/Shell/KernelShell-fs.class.cpp index 3ac7b20..b34fa7f 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 #include +#include +#include void KernelShell::ls(Vector& args) { DirectoryNode* d = m_cwd; @@ -102,3 +104,32 @@ void KernelShell::wf(Vector& args) { } } } + +void KernelShell::run(Vector& args) { + if (args.size() == 1) { + *m_vt << "No app to run !\n"; + } else { + File f(args[1], FM_READ, m_cwd); + if (f.valid()) { + u32int magic = 0; + f.read(&magic); + if (magic == 0xFEEDBEEF) { + u32int size; + f.read(&size); + Process* p; + p = new Process(args[1], 0); + p->setVirtualTerminal(m_vt); + u8int *ptr = (u8int*)p->heap().alloc(size); + f.read(size, ptr); + new Thread(p, (thread_entry_t)ptr, 0); + kernelPageDirectory->switchTo(); + while (p->getState() != P_FINISHED) Task::currThread()->sleep(10); + delete p; + } else { + *m_vt << "Bad magic number : " << (u32int)magic << "\n"; + } + } else { + *m_vt << "Unable to read from file.\n"; + } + } +} diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index e2fbb69..ac89b68 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -3,7 +3,9 @@ #include #include #include +#include #include +#include u32int KernelShell::m_instances = 0; @@ -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..48d9704 100644 --- a/Source/Kernel/Shell/KernelShell.class.h +++ b/Source/Kernel/Shell/KernelShell.class.h @@ -26,6 +26,7 @@ class KernelShell { void mkdir(Vector& args); void rm(Vector& args); void wf(Vector& args); + void run(Vector& args); //in KernelShell-sys void devices(Vector& args); diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index fcdf2ff..0744e56 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -75,9 +75,9 @@ extern "C" void interrupt_handler(registers_t regs) { doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32); } if (regs.int_no == 64) { - if (regs.eax == 1) { + if (regs.eax == 0xFFFFFF01) { Task::currProcess()->getVirtualTerminal()->put(WChar(regs.ebx)); - } else if (regs.eax == 2) { + } else if (regs.eax == 0xFFFFFF02) { Task::currThread()->sleep(regs.ebx); } } diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index cf8f00a..9fdad96 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -42,6 +42,7 @@ Process::Process(String cmdline, u32int uid) { m_state = P_RUNNING; 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(); @@ -65,7 +66,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; } diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h index ac9614e..73421a9 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -61,6 +61,7 @@ class Process { VirtualTerminal* getVirtualTerminal(); void setVirtualTerminal(VirtualTerminal* vt); + u32int getState() { return m_state; } }; diff --git a/Source/Kernel/TaskManager/Task.ns.cpp b/Source/Kernel/TaskManager/Task.ns.cpp index 1d1676e..437d5b4 100644 --- a/Source/Kernel/TaskManager/Task.ns.cpp +++ b/Source/Kernel/TaskManager/Task.ns.cpp @@ -141,6 +141,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; @@ -149,7 +150,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.wtf.asm b/Source/Kernel/TaskManager/Task.wtf.asm index 2e5b9f8..36c1ade 100644 --- a/Source/Kernel/TaskManager/Task.wtf.asm +++ b/Source/Kernel/TaskManager/Task.wtf.asm @@ -49,16 +49,3 @@ copy_page_physical: ret -[GLOBAL sample_task] -sample_task: - mov eax, 0x00000001 ;temporarily defined as syscall id for writing one char to screen - mov ebx, 'a' ;loopingly write a's to screen - int 64 - mov eax, 0x00000002 ;temporary syscall for sleeping - mov ebx, 20 ;20ms - int 64 - jmp sample_task - int 66 ;finish task - will never happen since we have an infinite loop -[GLOBAL sample_task_size] -sample_task_size: - dd sample_task_size - sample_task diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 63d8160..8b4845e 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -75,7 +75,6 @@ Thread::~Thread() { } void Thread::setup(Process* process, thread_entry_t entry_point, void* data, bool isKernel) { - DEBUG("new Thread :: setup"); m_isKernel = isKernel; m_process = process; m_kernelStack.addr = Mem::kalloc(STACKSIZE); 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/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.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp index 7a9ffa8..0612f1d 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp @@ -2,7 +2,7 @@ #include #include -VirtualTerminal::VirtualTerminal() : m_kbdMutex(false), m_kbdbuffMutex(false) { +VirtualTerminal::VirtualTerminal() : m_kbdMutex(false), m_kbdbuffMutex(false), m_kbdbuff() { } VirtualTerminal::~VirtualTerminal() { -- cgit v1.2.3 From 22c06556ccbd07f4ef7da39a62d10e03fbee3fe0 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 10:34:11 +0200 Subject: Loading binaries now is done through a much more unified interface. --- Init.rfs | Bin 4081 -> 0 bytes Source/Applications/ASMApps/syscalls.asm | 11 ++++++++++ Source/Applications/ASMApps/test | Bin 62 -> 92 bytes Source/Applications/ASMApps/test.asm | 16 +++++++++++--- Source/Kernel/Linker/Binary.proto.cpp | 19 +++++++++++++++++ Source/Kernel/Linker/Binary.proto.h | 16 ++++++++++++++ Source/Kernel/Linker/MelonBinary.class.cpp | 30 +++++++++++++++++++++++++++ Source/Kernel/Linker/MelonBinary.class.h | 21 +++++++++++++++++++ Source/Kernel/Makefile | 2 ++ Source/Kernel/MemoryManager/Mem.ns.cpp | 2 +- Source/Kernel/MemoryManager/PhysMem.ns.cpp | 2 +- Source/Kernel/Shell/KernelShell-fs.class.cpp | 27 +++++++----------------- Source/Kernel/SyscallManager/IDT.ns.cpp | 4 ++++ Source/Kernel/TaskManager/Process.class.cpp | 24 ++++++++++++++++++++- Source/Kernel/TaskManager/Process.class.h | 6 +++++- Source/Kernel/TaskManager/Thread.class.cpp | 1 + 16 files changed, 154 insertions(+), 27 deletions(-) delete mode 100644 Init.rfs create mode 100644 Source/Kernel/Linker/Binary.proto.cpp create mode 100644 Source/Kernel/Linker/Binary.proto.h create mode 100644 Source/Kernel/Linker/MelonBinary.class.cpp create mode 100644 Source/Kernel/Linker/MelonBinary.class.h diff --git a/Init.rfs b/Init.rfs deleted file mode 100644 index b10aa86..0000000 Binary files a/Init.rfs and /dev/null differ diff --git a/Source/Applications/ASMApps/syscalls.asm b/Source/Applications/ASMApps/syscalls.asm index cdd5cc6..1a634d7 100644 --- a/Source/Applications/ASMApps/syscalls.asm +++ b/Source/Applications/ASMApps/syscalls.asm @@ -1,7 +1,18 @@ [bits 32] +%ifidn __OUTPUT_FORMAT__, bin + +%define MEM_ORIGIN 0x10000000 + dd 0xFEEDBEEF ; magic number ^^ dd end - start +dd MEM_ORIGIN + +; the ($-$$) permits not taking into account the header above +[org MEM_ORIGIN - ($-$$)] + +%endif %define SC_PUTCH 0xFFFFFF01 %define SC_SLEEP 0xFFFFFF02 +%define SC_WHEX 0xFFFFFF03 diff --git a/Source/Applications/ASMApps/test b/Source/Applications/ASMApps/test index 397abf1..781a4b6 100644 Binary files a/Source/Applications/ASMApps/test and b/Source/Applications/ASMApps/test differ diff --git a/Source/Applications/ASMApps/test.asm b/Source/Applications/ASMApps/test.asm index 80965b4..a79d4a3 100644 --- a/Source/Applications/ASMApps/test.asm +++ b/Source/Applications/ASMApps/test.asm @@ -1,7 +1,13 @@ %include "syscalls.asm" -start: - mov ecx, ' ' +start: ; label used for calculating app size + mov ecx, [data] + mov ebx, ecx + mov eax, SC_WHEX + int 64 + mov eax, SC_PUTCH + mov ebx, 10 + int 64 loop: inc ecx mov eax, SC_PUTCH ;temporarily defined for writing one char to screen @@ -17,4 +23,8 @@ start: mov ebx, 10 ;newline int 64 int 66 ;finish task -end: + +data: +dd 0x00000020 + +end: ; label used for calculating app size diff --git a/Source/Kernel/Linker/Binary.proto.cpp b/Source/Kernel/Linker/Binary.proto.cpp new file mode 100644 index 0000000..6053f22 --- /dev/null +++ b/Source/Kernel/Linker/Binary.proto.cpp @@ -0,0 +1,19 @@ +#include "Binary.proto.h" + +#include + +Binary* (*loaders[])(File& file) = { + &MelonBinary::load, + +0 }; + +Binary* Binary::load(File& file) { + Binary* r = 0; + u32int i = 0; + while (loaders[i] != 0) { + r = loaders[i](file); //Call loader + if (r != 0) break; + i++; + } + return r; +} diff --git a/Source/Kernel/Linker/Binary.proto.h b/Source/Kernel/Linker/Binary.proto.h new file mode 100644 index 0000000..d0bd039 --- /dev/null +++ b/Source/Kernel/Linker/Binary.proto.h @@ -0,0 +1,16 @@ +#ifndef DEF_BINARY_PROTO_H +#define DEF_BINARY_PROTO_H + +#include +#include +#include + +class Binary { + public: + static Binary* load(File& file); + virtual ~Binary() {} + + virtual thread_entry_t toProcess(Process* p) = 0; +}; + +#endif diff --git a/Source/Kernel/Linker/MelonBinary.class.cpp b/Source/Kernel/Linker/MelonBinary.class.cpp new file mode 100644 index 0000000..d6074de --- /dev/null +++ b/Source/Kernel/Linker/MelonBinary.class.cpp @@ -0,0 +1,30 @@ +#include "MelonBinary.class.h" + +Binary* MelonBinary::load(File& file) { + u32int magic; + file.read(&magic); + if (magic == 0xFEEDBEEF) { + MelonBinary* r = new MelonBinary; + file.read(&r->m_size); + file.read(&r->m_org); + r->m_data = (u8int*)Mem::kalloc(r->m_size); + file.read(r->m_size, r->m_data); + return r; + } else { + return 0; + } +} + +MelonBinary::~MelonBinary() { + delete m_data; +} + +thread_entry_t MelonBinary::toProcess(Process* p) { + if (p == 0) return 0; + for (u32int i = m_org; i < m_org + m_size; i += 0x1000) { + p->getPagedir()->allocFrame(i, true, true); + } + p->getPagedir()->switchTo(); + memcpy((u8int*)m_org, m_data, m_size); + return (thread_entry_t)m_org; +} diff --git a/Source/Kernel/Linker/MelonBinary.class.h b/Source/Kernel/Linker/MelonBinary.class.h new file mode 100644 index 0000000..4300c7e --- /dev/null +++ b/Source/Kernel/Linker/MelonBinary.class.h @@ -0,0 +1,21 @@ +#ifndef DEF_MELONBINARY_CLASS_H +#define DEF_MELONBINARY_CLASS_H + +#include + +class MelonBinary : public Binary { + private: + u32int m_size; + u32int m_org; + u8int* m_data; + + MelonBinary() {} + + public: + virtual ~MelonBinary(); + static Binary* load(File& file); + + thread_entry_t toProcess(Process* p); +}; + +#endif diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 118ea29..521e32a 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -43,6 +43,8 @@ Objects = Core/loader.wtf.o \ Shell/KernelShell.class.o \ Shell/KernelShell-fs.class.o \ Shell/KernelShell-sys.class.o \ + Linker/Binary.proto.o \ + Linker/MelonBinary.class.o \ Library/Bitset.class.o \ Library/String.class.o \ Library/ByteArray.class.o \ diff --git a/Source/Kernel/MemoryManager/Mem.ns.cpp b/Source/Kernel/MemoryManager/Mem.ns.cpp index b2f2d59..0698a12 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.cpp +++ b/Source/Kernel/MemoryManager/Mem.ns.cpp @@ -19,7 +19,7 @@ void *kallocInternal(u32int sz, bool align) { u32int temp = placementAddress; placementAddress += sz; for (u32int i = temp; i < placementAddress; i += 0x1000) { - if (pagingEnabled) kernelPageDirectory->allocFrame(i, true, false); + if (pagingEnabled) kernelPageDirectory->allocFrame(i, false, false); } return (void*)temp; } diff --git a/Source/Kernel/MemoryManager/PhysMem.ns.cpp b/Source/Kernel/MemoryManager/PhysMem.ns.cpp index eb6fbf1..9e4b36a 100644 --- a/Source/Kernel/MemoryManager/PhysMem.ns.cpp +++ b/Source/Kernel/MemoryManager/PhysMem.ns.cpp @@ -19,7 +19,7 @@ void initPaging(u32int mem_size) { u32int i = 0xC0000000; while (i < Mem::placementAddress) { page_t *p2 = kernelPageDirectory->getPage(i, true); - allocFrame(p2, true, false); + allocFrame(p2, false, false); i += 0x1000; } //Also map thoses pages at begning of virtual memory diff --git a/Source/Kernel/Shell/KernelShell-fs.class.cpp b/Source/Kernel/Shell/KernelShell-fs.class.cpp index b34fa7f..fe1ecbf 100644 --- a/Source/Kernel/Shell/KernelShell-fs.class.cpp +++ b/Source/Kernel/Shell/KernelShell-fs.class.cpp @@ -109,27 +109,14 @@ void KernelShell::run(Vector& args) { if (args.size() == 1) { *m_vt << "No app to run !\n"; } else { - File f(args[1], FM_READ, m_cwd); - if (f.valid()) { - u32int magic = 0; - f.read(&magic); - if (magic == 0xFEEDBEEF) { - u32int size; - f.read(&size); - Process* p; - p = new Process(args[1], 0); - p->setVirtualTerminal(m_vt); - u8int *ptr = (u8int*)p->heap().alloc(size); - f.read(size, ptr); - new Thread(p, (thread_entry_t)ptr, 0); - kernelPageDirectory->switchTo(); - while (p->getState() != P_FINISHED) Task::currThread()->sleep(10); - delete p; - } else { - *m_vt << "Bad magic number : " << (u32int)magic << "\n"; - } + Process* p = Process::run(args[1], m_cwd, 0); + if (p == 0) { + *m_vt << "Error while launching process.\n"; } else { - *m_vt << "Unable to read from file.\n"; + p->setVirtualTerminal(m_vt); + p->start(); + while (p->getState() != P_FINISHED) Task::currThread()->sleep(10); + delete p; } } } diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index 0744e56..46e6ee2 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -79,7 +79,11 @@ extern "C" void interrupt_handler(registers_t regs) { Task::currProcess()->getVirtualTerminal()->put(WChar(regs.ebx)); } else if (regs.eax == 0xFFFFFF02) { Task::currThread()->sleep(regs.ebx); + } else if (regs.eax == 0xFFFFFF03) { + Task::currProcess()->getVirtualTerminal()->writeHex(regs.ebx); } + //Some syscalls have maybee modified current page directory, set it back to one for current process + Task::currProcess()->getPagedir()->switchTo(); } if (regs.int_no == 66) { //This syscall signals to kernel that thread ended. Task::currentThreadExits(regs.eax); //DO NOT COUNT ON COMMING BACK FROM HERE diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index 9fdad96..bad4e52 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -2,6 +2,7 @@ #include #include #include +#include namespace Mem { extern Heap kheap; @@ -35,11 +36,28 @@ Process* Process::createKernel(String cmdline, VirtualTerminal *vt) { return p; } +Process* Process::run(String filename, FSNode* cwd, u32int uid) { + File file(filename, FM_READ, cwd); + if (!file.valid()) return 0; + Binary* b = Binary::load(file); + if (b == 0) return 0; + Process* p = new Process(filename, uid); + thread_entry_t e = b->toProcess(p); + delete b; + if (e != 0) { + new Thread(p, e, 0); + return p; + } else { + delete p; + return 0; + } +} + Process::Process(String cmdline, u32int uid) { m_pid = Task::nextPid(); m_cmdline = cmdline; m_retval = 0; - m_state = P_RUNNING; + m_state = P_STARTING; m_uid = uid; m_vt = Task::currProcess()->getVirtualTerminal(); m_fileDescriptors = 0; @@ -57,6 +75,10 @@ Process::~Process() { delete m_userHeap; } +void Process::start() { + if (m_state == P_STARTING) m_state = P_RUNNING; +} + void Process::exit() { for (u32int i = 0; i < m_threads.size(); i++) { delete m_threads[i]; diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h index 73421a9..7cd78fc 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -7,10 +7,12 @@ #include #include #include +#include #define P_ZOMBIE 0 #define P_RUNNING 1 -#define P_FINISHED 2 +#define P_STARTING 2 +#define P_FINISHED 3 #define E_PAGEFAULT 0x0FFFFF00 #define E_ABORTED 0x0FFFFF01 @@ -45,11 +47,13 @@ class Process { public: static Process* createKernel(String cmdline, VirtualTerminal *vt); //Also creates a Thread for what's curently happening + static Process* run(String filename, FSNode* cwd, u32int uid); Process(String cmdline, u32int uid); ~Process(); Heap& heap() { return *m_userHeap; } + void start(); //Starts thread execution - sets m_state to P_RUNNING if == P_STARTING void exit(); //Exits properly process by killing all threads and deleting file descriptors void registerThread(Thread* t); //Called when a thread starts void threadFinishes(Thread* thread, u32int retval); //Called when a thread finishes diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 8b4845e..9a2df3f 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -191,6 +191,7 @@ void Thread::waitIRQ(u8int irq) { } bool Thread::runnable() { + if (m_process->getState() != P_RUNNING) return false; if (m_state == T_RUNNING) return true; if (m_state == T_SLEEPING and Time::time() >= waitfor.m_time) { m_state = T_RUNNING; -- cgit v1.2.3 From bc2eccdd11c27029096fb3e891073503eb269e27 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 12:35:07 +0200 Subject: We can now load ELF binaries !!! --- Makefile | 4 +- Source/Applications/ASMApps/Makefile | 20 ------- Source/Applications/ASMApps/syscalls.asm | 18 ------- Source/Applications/ASMApps/test | Bin 92 -> 0 bytes Source/Applications/ASMApps/test.asm | 30 ----------- Source/Applications/SampleApps/Makefile | 29 ++++++++++ Source/Applications/SampleApps/asmdemo | Bin 0 -> 4725 bytes Source/Applications/SampleApps/asmdemo.asm | 30 +++++++++++ Source/Applications/SampleApps/lib-melonasm.asm | 24 +++++++++ Source/Kernel/Linker/Binary.proto.cpp | 4 +- Source/Kernel/Linker/ElfBinary.class.cpp | 55 +++++++++++++++++++ Source/Kernel/Linker/ElfBinary.class.h | 68 ++++++++++++++++++++++++ Source/Kernel/Makefile | 1 + Source/Kernel/Shell/KernelShell.class.cpp | 1 + 14 files changed, 213 insertions(+), 71 deletions(-) delete mode 100644 Source/Applications/ASMApps/Makefile delete mode 100644 Source/Applications/ASMApps/syscalls.asm delete mode 100644 Source/Applications/ASMApps/test delete mode 100644 Source/Applications/ASMApps/test.asm create mode 100644 Source/Applications/SampleApps/Makefile create mode 100755 Source/Applications/SampleApps/asmdemo create mode 100644 Source/Applications/SampleApps/asmdemo.asm create mode 100644 Source/Applications/SampleApps/lib-melonasm.asm create mode 100644 Source/Kernel/Linker/ElfBinary.class.cpp create mode 100644 Source/Kernel/Linker/ElfBinary.class.h diff --git a/Makefile b/Makefile index 508aa76..324deb7 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: clean, mrproper, Init.rfs -Projects = Kernel Tools/MakeRamFS Applications/ASMApps +Projects = Kernel Tools/MakeRamFS 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/ASMApps/test:/System/Applications/Test \ + Source/Applications/SampleApps/asmdemo:/ASMDemo.app \ :/Useless \ Source/Kernel/Ressources/Texts/Info.txt:/Useless/Info.txt \ Source/Kernel/Ressources/Graphics/logo.text.cxd:/Useless/Melon-logo diff --git a/Source/Applications/ASMApps/Makefile b/Source/Applications/ASMApps/Makefile deleted file mode 100644 index 8cc8bfd..0000000 --- a/Source/Applications/ASMApps/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -.PHONY: clean, mrproper - -ASM = nasm - -Applications = test - -all: $(Applications) - echo "* Done with ASM applications : $(Applications)" - -rebuild: mrproper all - -%: %.asm - echo "* Compiling $<..." - $(ASM) -o $@ $< - -clean: - echo "* Removing files..." - rm -rf $(Applications) - -mrproper: clean diff --git a/Source/Applications/ASMApps/syscalls.asm b/Source/Applications/ASMApps/syscalls.asm deleted file mode 100644 index 1a634d7..0000000 --- a/Source/Applications/ASMApps/syscalls.asm +++ /dev/null @@ -1,18 +0,0 @@ -[bits 32] - -%ifidn __OUTPUT_FORMAT__, bin - -%define MEM_ORIGIN 0x10000000 - -dd 0xFEEDBEEF ; magic number ^^ -dd end - start -dd MEM_ORIGIN - -; the ($-$$) permits not taking into account the header above -[org MEM_ORIGIN - ($-$$)] - -%endif - -%define SC_PUTCH 0xFFFFFF01 -%define SC_SLEEP 0xFFFFFF02 -%define SC_WHEX 0xFFFFFF03 diff --git a/Source/Applications/ASMApps/test b/Source/Applications/ASMApps/test deleted file mode 100644 index 781a4b6..0000000 Binary files a/Source/Applications/ASMApps/test and /dev/null differ diff --git a/Source/Applications/ASMApps/test.asm b/Source/Applications/ASMApps/test.asm deleted file mode 100644 index a79d4a3..0000000 --- a/Source/Applications/ASMApps/test.asm +++ /dev/null @@ -1,30 +0,0 @@ -%include "syscalls.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/Makefile b/Source/Applications/SampleApps/Makefile new file mode 100644 index 0000000..28dad49 --- /dev/null +++ b/Source/Applications/SampleApps/Makefile @@ -0,0 +1,29 @@ +.PHONY: clean, mrproper + +ASM = nasm +ASMFLAGS = -f elf +LD = ld +LDFLAGS = --entry=start -Ttext=40000000 + +Applications = asmdemo + +all: $(Applications) + echo "* Done with applications : $(Applications)" + +rebuild: mrproper all + +%: %.o + echo "* Linking $<..." + $(LD) $(LDFLAGS) $< -o $@ + +%.o: %.asm + echo "* Compiling $<..." + $(ASM) $(ASMFLAGS) -o $@ $< + +clean: + echo "* Removing object files..." + rm -rf *.o + +mrproper: clean + echo "* Removing applications..." + rm -rf $(Applications) diff --git a/Source/Applications/SampleApps/asmdemo b/Source/Applications/SampleApps/asmdemo new file mode 100755 index 0000000..9e6822d Binary files /dev/null and b/Source/Applications/SampleApps/asmdemo differ 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/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/Kernel/Linker/Binary.proto.cpp b/Source/Kernel/Linker/Binary.proto.cpp index 6053f22..c0345da 100644 --- a/Source/Kernel/Linker/Binary.proto.cpp +++ b/Source/Kernel/Linker/Binary.proto.cpp @@ -1,16 +1,18 @@ #include "Binary.proto.h" #include +#include 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++; diff --git a/Source/Kernel/Linker/ElfBinary.class.cpp b/Source/Kernel/Linker/ElfBinary.class.cpp new file mode 100644 index 0000000..450053f --- /dev/null +++ b/Source/Kernel/Linker/ElfBinary.class.cpp @@ -0,0 +1,55 @@ +#include "ElfBinary.class.h" +#include + +ElfBinary::~ElfBinary() { + for (SimpleList *iter = m_phdr; iter != 0; iter = iter->next()) { + delete iter->v().data; + } +} + +Binary* ElfBinary::load(File& file) { + elf_ehdr_t hdr; + file.read (&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(&b->m_phdr->v().h); //Load current entry from file + } + //Load data + for (SimpleList *iter = b->m_phdr; iter != 0; iter = iter->next()) { + iter->v().data = (u8int*)Mem::kalloc(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 *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..311e2e6 --- /dev/null +++ b/Source/Kernel/Linker/ElfBinary.class.h @@ -0,0 +1,68 @@ +#ifndef DEF_ELFBINARY_CLASS_H +#define DEF_ELFBINARY_CLASS_H + +#include +#include + +/* 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 *m_phdr; + + ElfBinary() {} + + public: + virtual ~ElfBinary(); + static Binary* load(File& file); + + thread_entry_t toProcess(Process* p); +}; + +#endif diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 521e32a..af1f9db 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -45,6 +45,7 @@ Objects = Core/loader.wtf.o \ Shell/KernelShell-sys.class.o \ Linker/Binary.proto.o \ Linker/MelonBinary.class.o \ + Linker/ElfBinary.class.o \ Library/Bitset.class.o \ Library/String.class.o \ Library/ByteArray.class.o \ diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index ac89b68..cb6246d 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -20,6 +20,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; -- cgit v1.2.3 From 323e12f1f9ab33df15dcfed210e807561d98fa8c Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 15:27:34 +0200 Subject: Re-organized everything --- Makefile | 9 +- Source/Applications/SampleApps/Makefile | 20 ++- Source/Applications/SampleApps/asmdemo | Bin 4725 -> 0 bytes Source/Applications/SampleApps/cxxdemo.cpp | 10 ++ Source/Kernel/Core/CMem.ns.cpp | 35 ----- Source/Kernel/Core/CMem.ns.h | 17 -- Source/Kernel/Core/Sys.ns.cpp | 2 +- Source/Kernel/Core/common.wtf.h | 28 ---- Source/Kernel/Core/cppsupport.wtf.cpp | 2 +- Source/Kernel/Core/kmain.wtf.cpp | 6 +- Source/Kernel/Core/types.wtf.h | 19 --- Source/Kernel/DeviceManager/Dev.ns.h | 2 +- Source/Kernel/DeviceManager/Disp.ns.h | 2 +- Source/Kernel/DeviceManager/Kbd.ns.cpp | 2 +- Source/Kernel/DeviceManager/Kbd.ns.h | 4 +- Source/Kernel/Devices/Device.proto.h | 2 +- Source/Kernel/Devices/Display/Display.proto.h | 4 +- Source/Kernel/Library/BasicString.class.cpp | 175 --------------------- Source/Kernel/Library/BasicString.class.h | 53 ------- Source/Kernel/Library/Bitset.class.cpp | 62 -------- Source/Kernel/Library/Bitset.class.h | 31 ---- Source/Kernel/Library/ByteArray.class.cpp | 63 -------- Source/Kernel/Library/ByteArray.class.h | 30 ---- Source/Kernel/Library/OrderedArray.class.cpp | 54 ------- Source/Kernel/Library/OrderedArray.class.h | 29 ---- Source/Kernel/Library/Rand.ns.cpp | 18 --- Source/Kernel/Library/Rand.ns.h | 12 -- Source/Kernel/Library/SimpleList.class.h | 70 --------- Source/Kernel/Library/String.class.cpp | 181 ---------------------- Source/Kernel/Library/String.class.h | 47 ------ Source/Kernel/Library/Vector.class.cpp | 135 ---------------- Source/Kernel/Library/Vector.class.h | 36 ----- Source/Kernel/Library/WChar.class.cpp | 151 ------------------ Source/Kernel/Library/WChar.class.h | 89 ----------- Source/Kernel/Linker/ElfBinary.class.h | 2 +- Source/Kernel/Makefile | 14 +- Source/Kernel/MemoryManager/GDT.ns.h | 2 +- Source/Kernel/MemoryManager/Heap.class.h | 2 +- Source/Kernel/MemoryManager/Mem.ns.cpp | 2 +- Source/Kernel/MemoryManager/PageAlloc.ns.h | 2 +- Source/Kernel/MemoryManager/PageDirectory.class.h | 2 +- Source/Kernel/MemoryManager/PhysMem.ns.cpp | 2 +- Source/Kernel/Ressources/Keymaps/Keymap.h | 2 +- Source/Kernel/Ressources/Keymaps/MakeMKM.sh | 4 +- Source/Kernel/Shell/KernelShell.class.cpp | 3 +- Source/Kernel/Shell/KernelShell.class.h | 2 +- Source/Kernel/SyscallManager/IDT.ns.h | 2 +- Source/Kernel/TaskManager/Mutex.class.h | 2 +- Source/Kernel/TaskManager/Process.class.h | 6 +- Source/Kernel/TaskManager/Task.ns.cpp | 1 - Source/Kernel/TaskManager/Task.ns.h | 2 +- Source/Kernel/VFS/DirectoryNode.class.h | 2 +- Source/Kernel/VFS/FSNode.proto.h | 4 +- Source/Kernel/VFS/File.class.h | 2 +- Source/Kernel/VFS/Part.ns.h | 2 +- Source/Kernel/VTManager/VT.ns.cpp | 2 +- Source/Kernel/VTManager/VT.ns.h | 2 +- Source/Kernel/VTManager/VirtualTerminal.proto.h | 6 +- Source/Kernel/common.h | 28 ++++ Source/Library/Common/BasicString.class.cpp | 175 +++++++++++++++++++++ Source/Library/Common/BasicString.class.h | 53 +++++++ Source/Library/Common/Bitset.class.cpp | 62 ++++++++ Source/Library/Common/Bitset.class.h | 31 ++++ Source/Library/Common/ByteArray.class.cpp | 59 +++++++ Source/Library/Common/ByteArray.class.h | 27 ++++ Source/Library/Common/CMem.ns.cpp | 35 +++++ Source/Library/Common/CMem.ns.h | 17 ++ Source/Library/Common/OrderedArray.class.cpp | 54 +++++++ Source/Library/Common/OrderedArray.class.h | 29 ++++ Source/Library/Common/Rand.ns.cpp | 18 +++ Source/Library/Common/Rand.ns.h | 12 ++ Source/Library/Common/SimpleList.class.h | 70 +++++++++ Source/Library/Common/String.class.cpp | 181 ++++++++++++++++++++++ Source/Library/Common/String.class.h | 46 ++++++ Source/Library/Common/Vector.class.cpp | 135 ++++++++++++++++ Source/Library/Common/Vector.class.h | 36 +++++ Source/Library/Common/WChar.class.cpp | 155 ++++++++++++++++++ Source/Library/Common/WChar.class.h | 89 +++++++++++ Source/Library/Common/types.h | 19 +++ Source/Library/Makefile | 33 ++++ Source/Library/Userland/Syscall/Syscall.wtf.cpp | 20 +++ Source/Library/Userland/Syscall/Syscall.wtf.h | 9 ++ Source/Library/Userland/common.h | 10 ++ Source/Tools/MakeRamFS/MakeRamFS | Bin 12483 -> 0 bytes 84 files changed, 1480 insertions(+), 1395 deletions(-) delete mode 100755 Source/Applications/SampleApps/asmdemo create mode 100644 Source/Applications/SampleApps/cxxdemo.cpp delete mode 100644 Source/Kernel/Core/CMem.ns.cpp delete mode 100644 Source/Kernel/Core/CMem.ns.h delete mode 100644 Source/Kernel/Core/common.wtf.h delete mode 100644 Source/Kernel/Core/types.wtf.h delete mode 100644 Source/Kernel/Library/BasicString.class.cpp delete mode 100644 Source/Kernel/Library/BasicString.class.h delete mode 100644 Source/Kernel/Library/Bitset.class.cpp delete mode 100644 Source/Kernel/Library/Bitset.class.h delete mode 100644 Source/Kernel/Library/ByteArray.class.cpp delete mode 100644 Source/Kernel/Library/ByteArray.class.h delete mode 100644 Source/Kernel/Library/OrderedArray.class.cpp delete mode 100644 Source/Kernel/Library/OrderedArray.class.h delete mode 100644 Source/Kernel/Library/Rand.ns.cpp delete mode 100644 Source/Kernel/Library/Rand.ns.h delete mode 100644 Source/Kernel/Library/SimpleList.class.h delete mode 100644 Source/Kernel/Library/String.class.cpp delete mode 100644 Source/Kernel/Library/String.class.h delete mode 100644 Source/Kernel/Library/Vector.class.cpp delete mode 100644 Source/Kernel/Library/Vector.class.h delete mode 100644 Source/Kernel/Library/WChar.class.cpp delete mode 100644 Source/Kernel/Library/WChar.class.h create mode 100644 Source/Kernel/common.h create mode 100644 Source/Library/Common/BasicString.class.cpp create mode 100644 Source/Library/Common/BasicString.class.h create mode 100644 Source/Library/Common/Bitset.class.cpp create mode 100644 Source/Library/Common/Bitset.class.h create mode 100644 Source/Library/Common/ByteArray.class.cpp create mode 100644 Source/Library/Common/ByteArray.class.h create mode 100644 Source/Library/Common/CMem.ns.cpp create mode 100644 Source/Library/Common/CMem.ns.h create mode 100644 Source/Library/Common/OrderedArray.class.cpp create mode 100644 Source/Library/Common/OrderedArray.class.h create mode 100644 Source/Library/Common/Rand.ns.cpp create mode 100644 Source/Library/Common/Rand.ns.h create mode 100644 Source/Library/Common/SimpleList.class.h create mode 100644 Source/Library/Common/String.class.cpp create mode 100644 Source/Library/Common/String.class.h create mode 100644 Source/Library/Common/Vector.class.cpp create mode 100644 Source/Library/Common/Vector.class.h create mode 100644 Source/Library/Common/WChar.class.cpp create mode 100644 Source/Library/Common/WChar.class.h create mode 100644 Source/Library/Common/types.h create mode 100644 Source/Library/Makefile create mode 100644 Source/Library/Userland/Syscall/Syscall.wtf.cpp create mode 100644 Source/Library/Userland/Syscall/Syscall.wtf.h create mode 100644 Source/Library/Userland/common.h delete mode 100755 Source/Tools/MakeRamFS/MakeRamFS diff --git a/Makefile b/Makefile index 324deb7..9bb7f84 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,14 @@ .PHONY: clean, mrproper, Init.rfs -Projects = Kernel Tools/MakeRamFS Applications/SampleApps +Projects = Kernel Library Tools/MakeRamFS 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:/ASMDemo.app \ + Source/Applications/SampleApps/asmdemo:/ad \ + Source/Applications/SampleApps/cxxdemo:/cd \ :/Useless \ Source/Kernel/Ressources/Texts/Info.txt:/Useless/Info.txt \ Source/Kernel/Ressources/Graphics/logo.text.cxd:/Useless/Melon-logo @@ -32,9 +33,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/Source/Applications/SampleApps/Makefile b/Source/Applications/SampleApps/Makefile index 28dad49..6d12f3f 100644 --- a/Source/Applications/SampleApps/Makefile +++ b/Source/Applications/SampleApps/Makefile @@ -2,23 +2,31 @@ ASM = nasm ASMFLAGS = -f elf + +CXX = g++ +CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Userland -D THIS_IS_MELON_USERLAND + LD = ld LDFLAGS = --entry=start -Ttext=40000000 -Applications = asmdemo +Applications = asmdemo cxxdemo all: $(Applications) echo "* Done with applications : $(Applications)" rebuild: mrproper all -%: %.o - echo "* Linking $<..." - $(LD) $(LDFLAGS) $< -o $@ +%: %.cpp + echo "* Compiling $<..." + $(CXX) $(CXXFLAGS) -c $< -o $@.o + echo "* Linking $@.o..." + $(LD) $(LDFLAGS) ../../Library/Melon.o $@.o -o $@ -%.o: %.asm +%: %.asm echo "* Compiling $<..." - $(ASM) $(ASMFLAGS) -o $@ $< + $(ASM) $(ASMFLAGS) -o $@.o $< + echo "* Linking $@.o..." + $(LD) $(LDFLAGS) $@.o -o $@ clean: echo "* Removing object files..." diff --git a/Source/Applications/SampleApps/asmdemo b/Source/Applications/SampleApps/asmdemo deleted file mode 100755 index 9e6822d..0000000 Binary files a/Source/Applications/SampleApps/asmdemo and /dev/null differ diff --git a/Source/Applications/SampleApps/cxxdemo.cpp b/Source/Applications/SampleApps/cxxdemo.cpp new file mode 100644 index 0000000..5d95d28 --- /dev/null +++ b/Source/Applications/SampleApps/cxxdemo.cpp @@ -0,0 +1,10 @@ +#include +#include + +int main() { + for (char c = ' '; c <= 'z'; c++) { + syscall(0xFFFFFF02, (unsigned int)c); + putch(c); + } + putch('\n'); +} diff --git a/Source/Kernel/Core/CMem.ns.cpp b/Source/Kernel/Core/CMem.ns.cpp deleted file mode 100644 index c2129ec..0000000 --- a/Source/Kernel/Core/CMem.ns.cpp +++ /dev/null @@ -1,35 +0,0 @@ -#include - -namespace CMem { - -//Standard C functions -u8int *memcpy(u8int *dest, const u8int *src, int count) { - for (int i = 0; i < count; i++) { - dest[i] = src[i]; - } - return dest; -} - -u8int *memset(u8int *dest, u8int val, int count) { - for (int i = 0; i < count; i++) { - dest[i] = val; - } - return dest; -} - -u16int *memsetw(u16int *dest, u16int val, int count) { - for (int i = 0; i < count; i++) { - dest[i] = val; - } - return dest; -} - -u32int strlen(const char *str) { - u32int i = 0; - while (str[i]) { - i++; - } - return i; -} - -} diff --git a/Source/Kernel/Core/CMem.ns.h b/Source/Kernel/Core/CMem.ns.h deleted file mode 100644 index f0c15da..0000000 --- a/Source/Kernel/Core/CMem.ns.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifdef DEF_COMMON - -#ifndef DEF_CMEM_NS_H -#define DEF_CMEM_NS_H - -//This namespace contains basic memory managment functions - -namespace CMem { - u8int *memcpy(u8int *dest, const u8int *src, int count); - u8int *memset(u8int *dest, u8int val, int count); - u16int *memsetw(u16int *dest, u16int val, int count); - u32int strlen(const char *str); -} - -#endif - -#endif diff --git a/Source/Kernel/Core/Sys.ns.cpp b/Source/Kernel/Core/Sys.ns.cpp index a8a6c91..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 +#include #include #include #include diff --git a/Source/Kernel/Core/common.wtf.h b/Source/Kernel/Core/common.wtf.h deleted file mode 100644 index 5fb67b4..0000000 --- a/Source/Kernel/Core/common.wtf.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef DEF_COMMON -#define DEF_COMMON - -#include - -//This file is very important : it contains type definitions, macro definitions and new/delete implementations. - -#define NULL 0 - -#include - -#include -#include - -#include - -//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::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); } - -#endif 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 +#include 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 87e95de..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 +#include #include #include @@ -18,8 +18,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include diff --git a/Source/Kernel/Core/types.wtf.h b/Source/Kernel/Core/types.wtf.h deleted file mode 100644 index ca6f73d..0000000 --- a/Source/Kernel/Core/types.wtf.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef DEF_TYPES_WTF_H -#define DEF_TYPES_WTF_H - -//This file defines base types. It's made to be used also by C programs - -typedef unsigned int addr_t; -typedef unsigned long long u64int; -typedef unsigned int u32int; -typedef unsigned short u16int; -typedef unsigned char u8int; -typedef long long s64int; -typedef int s32int; -typedef short s16int; -typedef char s8int; - -#define U64 unsigned long long -#define S64 long long - -#endif 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 -#include +#include 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 -#include +#include 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 -#include +#include #include #include #include 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 -#include +#include +#include //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 +#include #include 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 +#include #include -#include +#include class Display : public Device { public: diff --git a/Source/Kernel/Library/BasicString.class.cpp b/Source/Kernel/Library/BasicString.class.cpp deleted file mode 100644 index ae89fe4..0000000 --- a/Source/Kernel/Library/BasicString.class.cpp +++ /dev/null @@ -1,175 +0,0 @@ -#include - -#define FREE if (m_string != 0) delete m_string; -#define ALLOC m_string = new T[m_length]; -#define VRFY if (m_length == 0) { m_string = NULL; return; } - -using namespace CMem; - -template -BasicString::BasicString() { - m_string = NULL; - m_length = 0; -} - -template -BasicString::BasicString(const T* string, u32int length) { - m_string = NULL; - affect(string, length); -} - -template -BasicString::BasicString(const BasicString &other) { - m_string = NULL; - affect(other); -} - -template -BasicString::BasicString(const T value, u32int count) { - m_string = NULL; - affect(value, count); -} - -template -BasicString::~BasicString() { - FREE; -} - -template -void BasicString::affect(const BasicString &other) { - FREE; - m_length = other.m_length; - VRFY; - ALLOC; - memcpy((u8int*)m_string, (u8int*)(other.m_string), m_length * sizeof(T)); -} - -template -void BasicString::affect(const T* string, u32int length) { - FREE; - m_length = length; - VRFY; - ALLOC; - memcpy((u8int*)string, (u8int*)string, m_length * sizeof(T)); -} - -template -void BasicString::affect(const T value, u32int count) { - FREE; - m_length = count; - VRFY; - ALLOC; - for (u32int i = 0; i < count; i++) { - m_string[i] = value; - } -} - -template -bool BasicString::compare(const BasicString &other) const { - if (m_length != other.m_length) return false; - for (u32int i = 0; i < m_length; i++) { - if (m_string[i] != other.m_string[i]) return false; - } - return true; -} - -template -bool BasicString::compare(const T* string, u32int length) const { - if (m_length != length) return false; - for (u32int i = 0; i < m_length; i++) { - if (m_string[i] != string[i]) return false; - } - return true; -} - -template -BasicString &BasicString::append(const BasicString &other) { - T* newdata = new T[m_length + other.m_length]; - for (u32int i = 0; i < m_length; i++) { - newdata[i] = m_string[i]; - } - for (u32int i = 0; i < other.m_length; i++) { - newdata[i + m_length] = other.m_string[i]; - } - FREE; - m_string = newdata; - m_length += other.m_length; - return *this; -} - -template -BasicString &BasicString::append(const T* string, u32int length) { - T* newdata = new T[m_length + length]; - for (u32int i = 0; i < m_length; i++) { - newdata[i] = m_string[i]; - } - for (u32int i = 0; i < length; i++) { - newdata[i + m_length] = string[i]; - } - FREE; - m_string = newdata; - m_length += length; - return *this; -} - -template -BasicString &BasicString::append(const T other) { - T* newdata = new T[m_length + 1]; - for (u32int i = 0; i < m_length; i++) { - newdata[i] = m_string[i]; - } - FREE; - m_string = newdata; - m_string[m_length] = other; - m_length++; - return *this; -} - -template -BasicString BasicString::concat(const BasicString &other) const { - BasicString ret(*this); - return (ret.append(other)); -} - -template -BasicString BasicString::concat(const T* string, u32int length) const { - BasicString ret(*this); - return (ret.append(string, length)); -} - -template -BasicString BasicString::concat(const T other) const { - BasicString ret(*this); - return (ret.append(other)); -} - -template -void BasicString::clear() { - FREE; - m_string = 0; - m_length = 0; -} - -template -Vector< BasicString > BasicString::split(T sep) const { - Vector< BasicString > ret; - ret.push(BasicString()); - for (u32int i = 0; i < m_length; i++) { - if (m_string[i] == sep) { - ret.push(BasicString()); - } else { - ret.back().append(m_string[i]); - } - } - return ret; -} - -template -BasicString BasicString::substr(s32int start, u32int size) { - if (start < 0) start = m_length - start; - BasicString ret; - ret.m_string = new T[size + 1]; - ret.m_length = size; - memcpy((u8int*)ret.m_string, (u8int*)(&m_string[start]), size * sizeof(T)); - return ret; -} diff --git a/Source/Kernel/Library/BasicString.class.h b/Source/Kernel/Library/BasicString.class.h deleted file mode 100644 index 5c69d00..0000000 --- a/Source/Kernel/Library/BasicString.class.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef DEF_BASICSTRING_CLASS_H -#define DEF_BASICSTRING_CLASS_H - -#include - -template class Vector; - -template -class BasicString { - protected: - T *m_string; - u32int m_length; - - public: - BasicString(); - BasicString(const T* string, u32int length); - BasicString(const BasicString &other); - BasicString(const T, u32int count = 1); - virtual ~BasicString(); - - void affect(const BasicString &other); - void affect(const T* string, u32int length); - void affect(const T value, u32int count = 1); - void operator= (const BasicString &other) { affect(other); } - - bool compare(const BasicString &other) const; - bool compare(const T* string, u32int length) const; - bool operator== (const BasicString &other) const { return compare(other); } - bool operator!= (const BasicString &other) const { return !compare(other); } - - BasicString& append(const BasicString &other); - BasicString& append(const T* string, u32int length); - BasicString& append(const T other); - BasicString& operator+= (const BasicString &other) { return append(other); } - BasicString& operator+= (const T other) { return append(other); } - - BasicString concat(const BasicString &other) const; - BasicString concat(const T* string, u32int length) const; - BasicString concat(const T other) const; - - T& operator[] (int index) const { return m_string[index]; } - - u32int size() const { return m_length; } - void clear(); - bool empty() const { return m_length == 0; } - - Vector< BasicString > split(T sep) const; - BasicString substr(s32int start, u32int size); -}; - -#include "BasicString.class.cpp" - -#endif diff --git a/Source/Kernel/Library/Bitset.class.cpp b/Source/Kernel/Library/Bitset.class.cpp deleted file mode 100644 index ec4e62c..0000000 --- a/Source/Kernel/Library/Bitset.class.cpp +++ /dev/null @@ -1,62 +0,0 @@ -#include "Bitset.class.h" - -Bitset::Bitset() { -} - -Bitset::Bitset(u32int size) { - init(size, (u32int*)Mem::kalloc(INDEX_FROM_BIT(size))); -} - -Bitset::Bitset(u32int size, u32int *ptr) { - init(size, ptr); -} - -Bitset::~Bitset() { - Mem::kfree(m_data); -} - -void Bitset::init(u32int size, u32int *ptr) { - m_size = size; - m_data = ptr; - for (u32int i = 0; i < INDEX_FROM_BIT(m_size); i++) { - m_data[i] = 0; - } - m_usedCount = 0; -} - -void Bitset::setBit(u32int number) { - u32int idx = INDEX_FROM_BIT(number); - u32int off = OFFSET_FROM_BIT(number); - m_data[idx] |= (0x1 << off); - m_usedCount++; -} - -void Bitset::clearBit(u32int number) { - u32int idx = INDEX_FROM_BIT(number); - u32int off = OFFSET_FROM_BIT(number); - m_data[idx] &= ~(0x1 << off); - m_usedCount--; -} - -bool Bitset::testBit(u32int number) { - u32int idx = INDEX_FROM_BIT(number); - u32int off = OFFSET_FROM_BIT(number); - return (m_data[idx] & (0x1 << off)); -} - -u32int Bitset::firstFreeBit() { - for (u32int i = 0; i < INDEX_FROM_BIT(m_size); i++) { - if (m_data[i] != 0xFFFFFFFF) { - for (int j = 0; j < 32; j++) { - if (!(m_data[i] & (0x1 << j))) { - return (i * 4 * 8) + j; - } - } - } - } - return (u32int) - 1; -} - -u32int Bitset::usedBits() { - return m_usedCount; -} diff --git a/Source/Kernel/Library/Bitset.class.h b/Source/Kernel/Library/Bitset.class.h deleted file mode 100644 index 75fde24..0000000 --- a/Source/Kernel/Library/Bitset.class.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef DEF_BITSET_CLASS_H -#define DEF_BITSET_CLASS_H - -#include - -#define INDEX_FROM_BIT(a) (a/(8*4)) -#define OFFSET_FROM_BIT(a) (a%(8*4)) - -class Bitset { - private: - u32int m_size; - u32int *m_data; - u32int m_usedCount; - - public: - Bitset(); - Bitset(u32int size); - Bitset(u32int size, u32int *ptr); - ~Bitset(); - - void init(u32int size, u32int *ptr); - - void setBit(u32int number); - void clearBit(u32int number); - bool testBit(u32int number); - u32int firstFreeBit(); - - u32int usedBits(); -}; - -#endif diff --git a/Source/Kernel/Library/ByteArray.class.cpp b/Source/Kernel/Library/ByteArray.class.cpp deleted file mode 100644 index 9972493..0000000 --- a/Source/Kernel/Library/ByteArray.class.cpp +++ /dev/null @@ -1,63 +0,0 @@ -#include "ByteArray.class.h" - -//Define size of a uchar_repr_t -#define CHARSZ(x) (x.c[0] == 0 ? 0 : (x.c[1] == 0 ? 1 : (x.c[2] == 0 ? 2 : (x.c[3] == 0 ? 3 : 4)))) - -using namespace CMem; - -ByteArray::ByteArray(const char* c) : BasicString() { - m_length = strlen(c); - memcpy(m_string, (u8int*)c, m_length); -} - -void ByteArray::affect(const String &string, u8int encoding) { - m_length = 0; - for (u32int i = 0; i < string.size(); i++) { - uchar_repr_t a = string[i].encode(encoding); - m_length += CHARSZ(a); - } - if (m_string != 0) delete m_string; - if (m_length == 0) { - m_string = 0; - return; - } - m_string = new u8int[m_length]; - u32int x = 0; - for (u32int i = 0; i < string.size(); i++) { - uchar_repr_t a = string[i].encode(encoding); - memcpy(m_string + x, (u8int*)a.c, CHARSZ(a)); - x += CHARSZ(a); - } -} - -void ByteArray::resize(u32int size) { - if (size == m_length) return; - if (size == 0) { - delete m_string; - m_length = 0; - m_string = 0; - } - u8int *nd = new u8int[size]; - if (size < m_length) { - memcpy(nd, m_string, size); - } else { - memcpy(nd, m_string, m_length); - memset(nd + m_length, 0, size - m_length); - } - delete m_string; - m_string = nd; - 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); - c[m_length] = 0; //Add NULL terminator - String r(c, encoding); - delete c; - return r; -} diff --git a/Source/Kernel/Library/ByteArray.class.h b/Source/Kernel/Library/ByteArray.class.h deleted file mode 100644 index a6d594f..0000000 --- a/Source/Kernel/Library/ByteArray.class.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef DEF_BYTEARRAY_CLASS_H -#define DEF_BYTEARRAY_CLASS_H - -#include -#include - -class ByteArray : public BasicString { - public: - ByteArray() : BasicString() {} - ByteArray(const BasicString &bs) : BasicString() { - m_length = bs.size(); - m_string = new u8int[m_length]; - for (u32int i = 0; i < m_length; i++) - m_string[i] = bs[i]; - } - ByteArray(const ByteArray& other) : BasicString(other) {} - ByteArray(const char* c); - ByteArray(u32int size) : BasicString((u8int)0, size) {} - ByteArray(const String &string, u8int encoding = UE_UTF8) : BasicString() { affect(string, encoding); } - - 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; } -}; - -#endif diff --git a/Source/Kernel/Library/OrderedArray.class.cpp b/Source/Kernel/Library/OrderedArray.class.cpp deleted file mode 100644 index 8b8f24f..0000000 --- a/Source/Kernel/Library/OrderedArray.class.cpp +++ /dev/null @@ -1,54 +0,0 @@ -template -OrderedArray::OrderedArray(u32int max_size) { - m_array = (T*)Memory::alloc(max_size * sizeof(T*)); - m_size = 0; - m_maxSize = max_size; -} - -template -OrderedArray::OrderedArray(T **addr, u32int max_size) { - m_array = addr; - memset((u8int*)addr, 0, max_size * sizeof(T*)); - m_size = 0; - m_maxSize = max_size; -} - -template -OrderedArray::~OrderedArray() { - //Free memory -} - -template -void OrderedArray::insert(T *element) { - if (m_size == m_maxSize) return; //Array is full - u32int iterator = 0; - while (iterator < m_size && *(m_array[iterator]) < *element) { - iterator++; - } - if (iterator == m_size) { - m_array[m_size++] = element; - } else { - u32int pos = iterator; - while (iterator < m_size) { - iterator++; - m_array[iterator] = m_array[iterator - 1]; - } - m_size++; - m_array[pos] = element; - } -} - -template -T *OrderedArray::lookup(int index) { - return m_array[index]; -} - -template -void OrderedArray::remove(int index) { - m_size--; - while (index < m_size) { - m_array[index] = m_array[index + 1]; - index++; - } -} - diff --git a/Source/Kernel/Library/OrderedArray.class.h b/Source/Kernel/Library/OrderedArray.class.h deleted file mode 100644 index 2a5acdd..0000000 --- a/Source/Kernel/Library/OrderedArray.class.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef DEF_ORDARRAY_CLASS -#define DEF_ORDARRAY_CLASS - -#include - -template -class OrderedArray { - private: - T *m_array[]; - u32int m_size; - u32int m_maxSize; - - public: - OrderedArray(u32int max_size); - OrderedArray(T **addr, u32int max_size); - ~OrderedArray(); - - u32int size() { return m_size; } - - void insert(T *element); - T *lookup(int index); - void remove(int index); - - T *operator[] (int index) { return lookup(index); } -}; - -#include "OrderedArray.class.cpp" - -#endif diff --git a/Source/Kernel/Library/Rand.ns.cpp b/Source/Kernel/Library/Rand.ns.cpp deleted file mode 100644 index e568678..0000000 --- a/Source/Kernel/Library/Rand.ns.cpp +++ /dev/null @@ -1,18 +0,0 @@ -#include "Rand.ns.h" - -namespace Rand { - -u32int m = 2073741824, a = 50000, b = 1534; -u64int current = RANDOM_SEED; - -u64int rand() { - current = (u32int)(a*current + b); - while (current > m) current -= m; - return current; -} - -u64int max() { - return m; -} - -} diff --git a/Source/Kernel/Library/Rand.ns.h b/Source/Kernel/Library/Rand.ns.h deleted file mode 100644 index 3598de0..0000000 --- a/Source/Kernel/Library/Rand.ns.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef DEF_RAND_NS_H -#define DEF_RAND_NS_H - -#include - -namespace Rand { - u64int rand(); - u64int max(); -} - -#endif - diff --git a/Source/Kernel/Library/SimpleList.class.h b/Source/Kernel/Library/SimpleList.class.h deleted file mode 100644 index 64e37aa..0000000 --- a/Source/Kernel/Library/SimpleList.class.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef DEF_SIMPLELIST_CLASS_H -#define DEF_SIMPLELIST_CLASS_H - -/* This class implements a singly linked list. It is also used to represent one of its elements. */ - -template -class SimpleList { - protected: - T m_value; - SimpleList* m_next; - - public: - SimpleList(const T& value, SimpleList* next = 0) : m_value(value), m_next(next) {} - ~SimpleList() { - if (m_next != 0) - delete m_next; - } - - T& v() { return m_value; } - T& operator* () { return m_value; } - - SimpleList* cons(const T& value) { - return new SimpleList(value, this); - } - - SimpleList* next() { - return m_next; - } - - SimpleList* last() { - if (m_next == 0) return this; - return m_next->last(); - } - - SimpleList* delThis() { - SimpleList* ret = m_next; - Mem::kfree(this); - return ret; - } - - void delNext() { - if (m_next == 0) return; - SimpleList* temp = m_next; - m_next = m_next->m_next; - Mem::kfree(temp); - } - - SimpleList* removeOnce(const T& value) { - if (value == m_value) return delThis(); - for (SimpleList *iter = this; iter->next() != 0; iter = iter->next()) { - if (iter->next()->v() == value) { - iter->delNext(); - break; - } - } - return this; - } - - bool isEnd() { - return m_next == 0; - } - - u32int size() { - if (m_next == 0) - return 0; - return m_next->size() + 1; - } -}; - -#endif diff --git a/Source/Kernel/Library/String.class.cpp b/Source/Kernel/Library/String.class.cpp deleted file mode 100644 index 693a11a..0000000 --- a/Source/Kernel/Library/String.class.cpp +++ /dev/null @@ -1,181 +0,0 @@ -#include "String.class.h" -#include - -using namespace CMem; //strlen and memcpy - -String String::hex(u32int number) { - String ret; - ret.m_length = 10; - ret.m_string = new WChar[11]; - ret.m_string[0] = '0'; - ret.m_string[1] = 'x'; - ret.m_string[10] = 0; - - char hexdigits[] = "0123456789ABCDEF"; - for (unsigned int j = 0; j < 8; j++) { - ret.m_string[j + 2] = hexdigits[(number & 0xF0000000) >> 28]; - number = number << 4; - } - return ret; -} - -String String::number(s32int number) { - if (number == 0) return String("0"); - bool negative = false; - if (number < 0) { - negative = true; - number = 0 - number; - } - u32int order = 0, temp = number; - char numbers[] = "0123456789"; - while (temp > 0) { - order++; - temp /= 10; - } - - String ret; - ret.m_length = order; - ret.m_string = new WChar[order + 1]; - - for (u32int i = order; i > 0; i--) { - ret.m_string[i - 1] = numbers[number % 10]; - number /= 10; - } - - ret.m_string[order] = 0; - - if (negative) return String("-") += ret; - - return ret; -} - -String::String(const char* string, u8int encoding) { - m_string = 0; - m_length = 0; - affect(string, encoding); -} - -void String::affect (const char* string, u8int encoding) { - m_length = WChar::utfLen(string, encoding); - if (m_string != 0) delete [] m_string; - if (m_length == 0) { - m_string = 0; - return; - } - m_string = new WChar[m_length + 1]; - int i = 0, l = strlen(string), c = 0; - while (i < l) { - i += m_string[c].affect(string + i, encoding); - c++; - } - m_string[m_length] = 0; -} - -bool String::compare (const char* string, u8int encoding) const { - if (m_length != WChar::utfLen(string, encoding)) return false; - int i = 0, l = strlen(string), c = 0; - WChar tmp; - while (i < l) { - i += tmp.affect(string + i, encoding); - if (m_string[c] != tmp) return false; - c++; - } - return true; -} - -String& String::append (const char* other, u8int encoding) { - WChar* newdata = new WChar[m_length + WChar::utfLen(other, encoding) + 1]; - for (u32int i = 0; i < m_length; i++) { - newdata[i] = m_string[i]; - } - int i = 0, l = strlen(other), c = 0; - while (i < l) { - i += newdata[c + m_length].affect(other + i, encoding); - c++; - } - if (m_string != 0) delete [] m_string; - m_string = newdata; - m_length += strlen(other); - m_string[m_length] = 0; - return *this; -} - -String String::concat (const String &other) const { //Can be optimized - String ret(*this); - return (ret += other); -} - -String String::concat (const char* other, u8int encoding) const { //Can be optimized - String ret(*this); - return (ret.append(other, encoding)); -} - -String String::concat (WChar other) const { - String ret(*this); - return (ret += other); -} - -s64int String::toInt() const { - if (m_string == 0) return 0; - s32int pos = 0; - s64int number = 0; - bool negative = false; - if (m_string[0].value == '-') { - negative = true; - pos = 1; - } - while (m_string[pos] >= '0' && m_string[pos] <= '9') { - number *= 10; - number += (m_string[pos].value - '0'); - pos++; - } - if (negative) return 0 - number; - return number; -} - -u64int String::toInt16() const { - if (m_string == 0) return 0; - u32int pos = 0; - u64int number = 0; - if (m_string[0].value == '0' && m_string[1].value == 'x') pos = 2; - while (1) { - char c = m_string[pos]; - pos++; - if (c >= 'a' && c <= 'f') c -= ('a' - 'A'); //To uppercase - if (c >= '0' && c <= '9') { - number *= 16; - number += (c - '0'); - continue; - } - if (c >= 'A' && c <= 'F') { - number *= 16; - number += (c - 'A' + 10); - continue; - } - break; - } - return number; -} - -Vector String::split(WChar c) const { - Vector ret; - ret.push(String("")); - for (u32int i = 0; i < m_length; i++) { - if (m_string[i] == c) { - ret.push(String("")); - } else { - ret.back() += m_string[i]; - } - } - return ret; -} - -String String::substr(s32int start, u32int size) { - if (start < 0) start = m_length - start; - String ret; - ret.m_string = new WChar[size + 1]; - ret.m_length = size; - memcpy((u8int*)ret.m_string, (const u8int*)(m_string + start), size * sizeof(WChar)); - ret.m_string[size] = 0; - return ret; -} diff --git a/Source/Kernel/Library/String.class.h b/Source/Kernel/Library/String.class.h deleted file mode 100644 index db274c9..0000000 --- a/Source/Kernel/Library/String.class.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef DEF_STRING_CLASS -#define DEF_STRING_CLASS - -#include -#include -#include - -class String : public BasicString { - public: - static String hex(u32int number); - static String number(s32int number); - - String(const char* string, u8int encoding = UE_UTF8); - String() : BasicString() {} - String(const String &other) : BasicString (other) {} - - void affect(const char* string, u8int encoding = UE_UTF8); - void operator= (const char* other) { affect(other); } - void operator= (const String& other) { BasicString::affect(other); } - - bool compare(const char* string, u8int encoding = UE_UTF8) const; - bool operator== (const char* other) const { return compare(other); } - bool operator!= (const char* other) { return !compare(other); } - bool operator== (const String& other) const { return BasicString::compare(other); } - bool operator!= (const String& other) const { return !BasicString::compare(other); } - - String& append(const char* other, u8int encoding = UE_UTF8); - String &operator+= (const String &other) { BasicString::append(other); return *this; } - String &operator+= (const char* other) { return append(other); } - String &operator+= (WChar other) { BasicString::append(other); return *this; } - - String concat(const String &other) const; - String concat(const char* other, u8int encoding = UE_UTF8) const; - String concat(WChar other) const; - 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 - - Vector split(WChar c) const; - - String substr(s32int start, u32int size); -}; - -#endif diff --git a/Source/Kernel/Library/Vector.class.cpp b/Source/Kernel/Library/Vector.class.cpp deleted file mode 100644 index 02ae9be..0000000 --- a/Source/Kernel/Library/Vector.class.cpp +++ /dev/null @@ -1,135 +0,0 @@ -using namespace CMem; //strlen and memcpy - -#define DELDATA if (m_data != NULL and m_size != 0) { \ - for (u32int i = 0; i < m_size; i++) { \ - m_data[i].~T(); \ - } \ - Mem::kfree(m_data); \ -} - -template -Vector::Vector() { - //DEBUG_HEX((u32int)this); DEBUG(" NEW EMPTY"); - //DEBUG_HEX(sizeof(T)); DEBUG(" sizeof(T)"); - m_data = 0; - m_size = 0; -} - -template -Vector::Vector(u32int size) { - //DEBUG_HEX((u32int)this); DEBUG(" NEW ZERO"); - m_data = new T[size]; - m_size = size; -} - -template -Vector::Vector(u32int size, const T& value) { - //DEBUG_HEX((u32int)this); DEBUG(" NEW FILLED"); - //m_data = (T*)Mem::kalloc(size * sizeof(T)); - m_data = new T[size]; - m_size = size; - for (u32int i = 0; i < m_size; i++) { - new (&m_data[i]) T(value); - } - /*for (u32int i = 0; i < size; i++) { - m_data[i] = new(&m_data[i]) T(value); - }*/ -} - -template -Vector::Vector(const Vector &other) { - //DEBUG_HEX((u32int)this); DEBUG(" COPY REF"); - m_size = other.m_size; - m_data = (T*)Mem::kalloc(m_size * sizeof(T)); - for (u32int i = 0; i < m_size; i++) { - new(&m_data[i]) T(other.m_data[i]); - } -} - -template -Vector& Vector::operator= (const Vector &other) { - //DEBUG_HEX((u32int)this); DEBUG(" COPY EQ"); - DELDATA; - m_size = other.m_size; - m_data = (T*)Mem::kalloc(m_size * sizeof(T)); - for (u32int i = 0; i < m_size; i++) { - new(&m_data[i]) T(other.m_data[i]); - } - return *this; -} - -template -Vector::~Vector() { - //DEBUG_HEX((u32int)this); DEBUG(" DELETE"); - DELDATA; - //if (m_data != 0) delete[] m_data; -} - -template -T& Vector::operator[] (u32int index) const { - return m_data[index]; -} - -template -void Vector::push(const T& element) { - T* newdata = (T*)Mem::kalloc((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); - m_data = newdata; -} - -/* template -void Vector::push(T& element) { - T* newdata = (T*)Memory::alloc((m_size + 1) * sizeof(T)); - memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T)); - //memcpy((u8int*)newdata + (m_size * sizeof(T)), (const u8int*) element, sizeof(T)); //Copy - new(&newdata[m_size]) T(element); //Construct by copy - m_size++; - Memory::free(m_data); - m_data = newdata; -} */ - -template -void Vector::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)); - memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T)); - Mem::kfree(m_data); - m_data = newdata; -} - -template -T& Vector::back() const { - return m_data[m_size - 1]; -} - -template -T& Vector::front() const { - return m_data[0]; -} - - -template -u32int Vector::size() const { - return m_size; -} - -template -bool Vector::empty() const { - return m_size == 0; -} - -template -void Vector::clear() { - if (empty()) return; - DELDATA - m_data = 0; - m_size = 0; -} diff --git a/Source/Kernel/Library/Vector.class.h b/Source/Kernel/Library/Vector.class.h deleted file mode 100644 index 61c26a4..0000000 --- a/Source/Kernel/Library/Vector.class.h +++ /dev/null @@ -1,36 +0,0 @@ -#ifndef DEF_VECTOR_CLASS -#define DEF_VECTOR_CLASS - -#include - -template -class Vector { - private: - T *m_data; - u32int m_size; - - public: - Vector(); - Vector(u32int size); - Vector(u32int size, const T& value); - Vector(const Vector &other); - Vector& operator= (const Vector &other); - ~Vector(); - - T& operator[] (u32int index) const; - - void push(const T& element); - //void push(T& element); - void pop(); - - T& back() const; - T& front() const; - - u32int size() const; - bool empty() const; - void clear(); -}; - -#include "Vector.class.cpp" - -#endif diff --git a/Source/Kernel/Library/WChar.class.cpp b/Source/Kernel/Library/WChar.class.cpp deleted file mode 100644 index ee42849..0000000 --- a/Source/Kernel/Library/WChar.class.cpp +++ /dev/null @@ -1,151 +0,0 @@ -#include "WChar.class.h" - -#ifdef THIS_IS_MELON -using namespace CMem; -#endif - -WChar WChar::CP437[] = { //These are the UTF8 equivalents for the 128 extra characters of code page 437 - "Ç", "ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å", - "É", "æ", "Æ", "ô", "ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "₧", "ƒ", - "á", "í", "ó", "ú", "ñ", "Ñ", "ª", "º", "¿", "⌐", "¬", "½", "¼", "¡", "«", "»", - "░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣", "║", "╗", "╝", "╜", "╛", "┐", - "└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠", "═", "╬", "¤", - "╨", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀", - "α", "ß", "Γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩", - "≡", "±", "≥", "≤", "⌠", "⌡", "÷", "≈", "°", "∙", "·", "√", "ⁿ", "²", "■", "⍽" -}; - -WChar::WChar() { - value = 0; -} - -WChar::WChar(char c) { - affectAscii(c); -} - -WChar::WChar(const char* c, u8int encoding) { - if (encoding == UE_UTF8) affectUtf8(c); - if (encoding == UE_UTF16) affectUtf16(c); - if (encoding == UE_UTF32) affectUtf32(c); -} - -u32int WChar::ucharLen(const char* c, u8int encoding) { - if (encoding == UE_UTF8) { - if ((c[0] & 0x80) == 0) return 1; - else if ((c[0] & 0xE0) == 0xC0) return 2; - else if ((c[0] & 0xF0) == 0xE0) return 3; - else if ((c[0] & 0xF8) == 0xF0) return 4; - else return 1; - } else if (encoding == UE_UTF16) { - if ((c[0] & 0xFC) == 0xD8 and (c[2] & 0xFC) == 0xDC) return 4; - else return 2; - } else if (encoding == UE_UTF32) { - return 4; - } - return 1; -} - -u32int WChar::utfLen(const char* c, u8int encoding) { - int i = 0, l = strlen(c), co = 0; - while (i < l) { - i += ucharLen(c + i, encoding); - co++; - } - return co; -} - -void WChar::affectAscii(char c) { - if (c >= 0) value = c; - else value = CP437[c + 128]; -} - -u32int WChar::affectUtf8(const char* c) { //Returns the number of bytes for the character - if ((c[0] & 0x80) == 0) { - value = c[0]; //0x80 = 10000000b - return 1; - } - if ((c[0] & 0xE0) == 0xC0) { // 11100000b, 11000000b - value = ((c[0] & 0x1F) << 6) | (c[1] & 0x3F); - if (value < 128) value = 0; //Bad value - return 2; - } - if ((c[0] & 0xF0) == 0xE0) { // 11110000b, 11100000b - value = ((c[0] & 0x0F) << 12) | ((c[1] & 0x3F) << 6) | (c[2] & 0x3F); - if (value < 2048) value = 0; //Bad value - if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed - if (value >= 0xFFFE and value <= 0xFFFF) value = 0; - return 3; - } - if ((c[0] & 0xF8) == 0xF0) { // 11111000b, 11110000b - value = ((c[0] & 0x0E) << 18) | ((c[1] & 0x3F) << 12) | ((c[2] & 0x3F) << 6) | (c[3] & 0x3F); - if (value < 65536) value = 0; //Bad value - return 4; - } - value = 0; //Something wrong happenned - return 1; -} - -u32int WChar::affectUtf16(const char* c) { - if ((c[0] & 0xFC) == 0xD8 and // 11111100b, 11011000b - (c[2] & 0xFC) == 0xDC) { // 11111100b, 11011100b - u32int w = ((c[0] & 0x03) << 2) | ((c[1] & 0xC0) >> 6); - u32int x = (c[1] & 0x3F); - u32int y = ((c[2] & 0x03) << 8) | (c[2]); - value = ((w + 1) << 16) | (x << 10) | y; - if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed - if (value >= 0xFFFE and value <= 0xFFFF) value = 0; - return 4; - } else { - value = (c[0] << 8) | (c[1]); - if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed - if (value >= 0xFFFE and value <= 0xFFFF) value = 0; - return 2; - } -} - -u32int WChar::affectUtf32(const char* c) { - value = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; - if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed - if (value >= 0xFFFE and value <= 0xFFFF) value = 0; - return 4; -} - -u8int WChar::toAscii() { - if (value < 128) return (char)value; - for (int i = 0; i < 128; i++) { - if (CP437[i] == value) return (i + 128); - } - return '?'; -} - -uchar_repr_t WChar::toUtf8() { - uchar_repr_t r; - r.i = 0; - if (value < 128) { - r.c[0] = value; - } else if (value < 4096) { - r.c[0] = 0xC0 | ((value & 0x07C0) >> 6); - r.c[1] = 0x80 | (value & 0x3F); - } else if (value < 65536) { - r.c[0] = 0xE0 | ((value & 0xF000) >> 12); - r.c[1] = 0x80 | ((value & 0x0FC0) >> 6); - r.c[2] = 0x80 | (value & 0x003F); - } else { - r.c[0] = 0xF0 | ((value & 0x1C0000) >> 18); - r.c[1] = 0x80 | ((value & 0x3F000) >> 12); - r.c[2] = 0x80 | ((value & 0x0FC0) >> 6); - r.c[3] = 0x80 | (value & 0x003F); - } - return r; -} - -//TODO : code WChar::toUtf16 - -uchar_repr_t WChar::toUtf32() { - uchar_repr_t r; - r.c[0] = (value >> 24) & 0xFF; - r.c[1] = (value >> 16) & 0xFF; - r.c[2] = (value >> 8) & 0xFF; - r.c[3] = value & 0xFF; - return r; -} diff --git a/Source/Kernel/Library/WChar.class.h b/Source/Kernel/Library/WChar.class.h deleted file mode 100644 index e4da603..0000000 --- a/Source/Kernel/Library/WChar.class.h +++ /dev/null @@ -1,89 +0,0 @@ -#ifndef DEF_UCHAR_CLASS_H -#define DEF_UCHAR_CLASS_H - -#include - -#ifndef THIS_IS_NOT_MELON -#include -#endif - -enum { - UE_UTF8, - UE_UTF16, - UE_UTF32, -}; - -union uchar_repr_t { - char c[4]; - u32int i; -}; - -struct WChar { - u32int value; - static WChar CP437[]; //Codepage 437, used for conversion from/to ascii - - WChar(); //Creates a null character - WChar(char c); //From ascii character - WChar(const char* c, u8int encoding = UE_UTF8); //From utf8 string - - static u32int ucharLen(const char* c, u8int encoding = UE_UTF8); //Returns count of bytes in one unicode character - static u32int utfLen(const char* c, u8int encoding = UE_UTF8); //Returns count of utf8 characters in string - - void affectAscii(char c); - u32int affectUtf8(const char* c); - u32int affectUtf16(const char* c); - u32int affectUtf32(const char* c); - - u32int affect(const char* c, u8int encoding = UE_UTF8) { - if (encoding == UE_UTF8) return affectUtf8(c); - if (encoding == UE_UTF16) return affectUtf16(c); - if (encoding == UE_UTF32) return affectUtf32(c); - affectAscii(c[0]); //Default case :/ - return 1; - } - - u8int toAscii(); - - uchar_repr_t toUtf8(); - uchar_repr_t toUtf16(); - uchar_repr_t toUtf32(); - - uchar_repr_t encode(u8int encoding = UE_UTF8) { - if (encoding == UE_UTF8) return toUtf8(); - //if (encoding == UE_UTF16) return toUtf16(); - if (encoding == UE_UTF32) return toUtf32(); - uchar_repr_t x; - x.c[0] = toAscii(); - return x; - } - - inline WChar operator+ (u32int other) { - WChar r; - r.value = value + other; - return r; - } - inline WChar operator- (u32int other) { - WChar r; - r.value = value - other; - return r; - } - inline WChar& operator+= (u32int other) { - value += other; - return *this; - } - inline WChar& operator-= (u32int other) { - value -= other; - return *this; - } - inline bool operator== (u32int other) { - return value == other; - } - inline u32int operator= (u32int v) { - value = v; - return v; - } - - inline operator u32int () { return value; } -}; - -#endif diff --git a/Source/Kernel/Linker/ElfBinary.class.h b/Source/Kernel/Linker/ElfBinary.class.h index 311e2e6..1fb9929 100644 --- a/Source/Kernel/Linker/ElfBinary.class.h +++ b/Source/Kernel/Linker/ElfBinary.class.h @@ -2,7 +2,7 @@ #define DEF_ELFBINARY_CLASS_H #include -#include +#include /* p_type */ #define PT_NULL 0 diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index af1f9db..257c53d 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 -g +CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I . -I ../Library/Common -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,7 +14,6 @@ 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 \ @@ -46,11 +45,12 @@ Objects = Core/loader.wtf.o \ Linker/Binary.proto.o \ Linker/MelonBinary.class.o \ Linker/ElfBinary.class.o \ - Library/Bitset.class.o \ - Library/String.class.o \ - Library/ByteArray.class.o \ - Library/WChar.class.o \ - Library/Rand.ns.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 \ VFS/Partition.class.o \ VFS/Part.ns.o \ VFS/VFS.ns.o \ diff --git a/Source/Kernel/MemoryManager/GDT.ns.h b/Source/Kernel/MemoryManager/GDT.ns.h index 94306a4..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 +#include namespace GDT { struct gdt_entry_t { diff --git a/Source/Kernel/MemoryManager/Heap.class.h b/Source/Kernel/MemoryManager/Heap.class.h index 930a589..291c9ce 100644 --- a/Source/Kernel/MemoryManager/Heap.class.h +++ b/Source/Kernel/MemoryManager/Heap.class.h @@ -1,7 +1,7 @@ #ifndef DEF_HEAP_CLASS_H #define DEF_HEAP_CLASS_H -#include +#include #include //Heap minimum size : 2M diff --git a/Source/Kernel/MemoryManager/Mem.ns.cpp b/Source/Kernel/MemoryManager/Mem.ns.cpp index 0698a12..6c64a53 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.cpp +++ b/Source/Kernel/MemoryManager/Mem.ns.cpp @@ -1,4 +1,4 @@ -#include +#include #include #include 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 +#include 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 +#include struct page_t { u32int present : 1; diff --git a/Source/Kernel/MemoryManager/PhysMem.ns.cpp b/Source/Kernel/MemoryManager/PhysMem.ns.cpp index 9e4b36a..25869f1 100644 --- a/Source/Kernel/MemoryManager/PhysMem.ns.cpp +++ b/Source/Kernel/MemoryManager/PhysMem.ns.cpp @@ -1,5 +1,5 @@ #include "PhysMem.ns.h" -#include +#include #include PageDirectory* kernelPageDirectory; 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 +#include 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 " >> kmtemp.cpp - echo "#include " >> kmtemp.cpp + echo "#include " >> 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.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index cb6246d..d90fc4c 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -1,8 +1,7 @@ #include "KernelShell.class.h" #include #include -#include -#include +#include #include #include #include diff --git a/Source/Kernel/Shell/KernelShell.class.h b/Source/Kernel/Shell/KernelShell.class.h index 48d9704..e7549c2 100644 --- a/Source/Kernel/Shell/KernelShell.class.h +++ b/Source/Kernel/Shell/KernelShell.class.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include class KernelShell { friend u32int shellRun(void* ks); 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 +#include struct registers_t { u32int ds; // Data segment selector diff --git a/Source/Kernel/TaskManager/Mutex.class.h b/Source/Kernel/TaskManager/Mutex.class.h index 5545559..1e3f63d 100644 --- a/Source/Kernel/TaskManager/Mutex.class.h +++ b/Source/Kernel/TaskManager/Mutex.class.h @@ -1,7 +1,7 @@ #ifndef DEF_MUTEX_CLASS_H #define DEF_MUTEX_CLASS_H -#include +#include #define MUTEX_FALSE 0 #define MUTEX_TRUE 1 diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h index 7cd78fc..fdd1377 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -1,9 +1,9 @@ #ifndef DEF_PROCESS_CLASS_H #define DEF_PROCESS_CLASS_H -#include -#include -#include +#include +#include +#include #include #include #include diff --git a/Source/Kernel/TaskManager/Task.ns.cpp b/Source/Kernel/TaskManager/Task.ns.cpp index 437d5b4..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 #include #define INVALID_TASK_MAGIC 0xBEEFFEED 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 #include -#include +#include namespace Task { Thread* currThread(); 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 -#include +#include class DirectoryNode : public FSNode { protected: diff --git a/Source/Kernel/VFS/FSNode.proto.h b/Source/Kernel/VFS/FSNode.proto.h index 8773543..c3cd1c1 100644 --- a/Source/Kernel/VFS/FSNode.proto.h +++ b/Source/Kernel/VFS/FSNode.proto.h @@ -1,8 +1,8 @@ #ifndef DEF_FSNODE_PROTO_H #define DEF_FSNODE_PROTO_H -#include -#include +#include +#include class FSNode; #include 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 -#include +#include 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 -#include +#include #include namespace Part { 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 +#include #include 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 +#include #include namespace VT { diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.h b/Source/Kernel/VTManager/VirtualTerminal.proto.h index ea6284f..9d0afa0 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.h +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h @@ -1,11 +1,11 @@ #ifndef DEF_VIRTUALTERMINAL_CLASS_H #define DEF_VIRTUALTERMINAL_CLASS_H -#include -#include +#include +#include #include #include -#include +#include struct vtchr { u8int color; diff --git a/Source/Kernel/common.h b/Source/Kernel/common.h new file mode 100644 index 0000000..c6da25e --- /dev/null +++ b/Source/Kernel/common.h @@ -0,0 +1,28 @@ +#ifndef DEF_COMMON +#define DEF_COMMON + +#include + +//This file is very important : it contains type definitions, macro definitions and new/delete implementations. + +#define NULL 0 + +#include + +#include +#include + +#include + +//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::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); } + +#endif diff --git a/Source/Library/Common/BasicString.class.cpp b/Source/Library/Common/BasicString.class.cpp new file mode 100644 index 0000000..ceab60b --- /dev/null +++ b/Source/Library/Common/BasicString.class.cpp @@ -0,0 +1,175 @@ +#include + +#define FREE if (m_string != 0) delete m_string; +#define ALLOC m_string = new T[m_length]; +#define VRFY if (m_length == 0) { m_string = NULL; return; } + +using namespace CMem; + +template +BasicString::BasicString() { + m_string = NULL; + m_length = 0; +} + +template +BasicString::BasicString(const T* string, u32int length) { + m_string = NULL; + affect(string, length); +} + +template +BasicString::BasicString(const BasicString &other) { + m_string = NULL; + affect(other); +} + +template +BasicString::BasicString(const T value, u32int count) { + m_string = NULL; + affect(value, count); +} + +template +BasicString::~BasicString() { + FREE; +} + +template +void BasicString::affect(const BasicString &other) { + FREE; + m_length = other.m_length; + VRFY; + ALLOC; + memcpy((u8int*)m_string, (u8int*)(other.m_string), m_length * sizeof(T)); +} + +template +void BasicString::affect(const T* string, u32int length) { + FREE; + m_length = length; + VRFY; + ALLOC; + memcpy((u8int*)string, (u8int*)string, m_length * sizeof(T)); +} + +template +void BasicString::affect(const T value, u32int count) { + FREE; + m_length = count; + VRFY; + ALLOC; + for (u32int i = 0; i < count; i++) { + m_string[i] = value; + } +} + +template +bool BasicString::compare(const BasicString &other) const { + if (m_length != other.m_length) return false; + for (u32int i = 0; i < m_length; i++) { + if (m_string[i] != other.m_string[i]) return false; + } + return true; +} + +template +bool BasicString::compare(const T* string, u32int length) const { + if (m_length != length) return false; + for (u32int i = 0; i < m_length; i++) { + if (m_string[i] != string[i]) return false; + } + return true; +} + +template +BasicString &BasicString::append(const BasicString &other) { + T* newdata = new T[m_length + other.m_length]; + for (u32int i = 0; i < m_length; i++) { + newdata[i] = m_string[i]; + } + for (u32int i = 0; i < other.m_length; i++) { + newdata[i + m_length] = other.m_string[i]; + } + FREE; + m_string = newdata; + m_length += other.m_length; + return *this; +} + +template +BasicString &BasicString::append(const T* string, u32int length) { + T* newdata = new T[m_length + length]; + for (u32int i = 0; i < m_length; i++) { + newdata[i] = m_string[i]; + } + for (u32int i = 0; i < length; i++) { + newdata[i + m_length] = string[i]; + } + FREE; + m_string = newdata; + m_length += length; + return *this; +} + +template +BasicString &BasicString::append(const T other) { + T* newdata = new T[m_length + 1]; + for (u32int i = 0; i < m_length; i++) { + newdata[i] = m_string[i]; + } + FREE; + m_string = newdata; + m_string[m_length] = other; + m_length++; + return *this; +} + +template +BasicString BasicString::concat(const BasicString &other) const { + BasicString ret(*this); + return (ret.append(other)); +} + +template +BasicString BasicString::concat(const T* string, u32int length) const { + BasicString ret(*this); + return (ret.append(string, length)); +} + +template +BasicString BasicString::concat(const T other) const { + BasicString ret(*this); + return (ret.append(other)); +} + +template +void BasicString::clear() { + FREE; + m_string = 0; + m_length = 0; +} + +template +Vector< BasicString > BasicString::split(T sep) const { + Vector< BasicString > ret; + ret.push(BasicString()); + for (u32int i = 0; i < m_length; i++) { + if (m_string[i] == sep) { + ret.push(BasicString()); + } else { + ret.back().append(m_string[i]); + } + } + return ret; +} + +template +BasicString BasicString::substr(s32int start, u32int size) { + if (start < 0) start = m_length - start; + BasicString ret; + ret.m_string = new T[size + 1]; + ret.m_length = size; + memcpy((u8int*)ret.m_string, (u8int*)(&m_string[start]), size * sizeof(T)); + return ret; +} diff --git a/Source/Library/Common/BasicString.class.h b/Source/Library/Common/BasicString.class.h new file mode 100644 index 0000000..17055e8 --- /dev/null +++ b/Source/Library/Common/BasicString.class.h @@ -0,0 +1,53 @@ +#ifndef DEF_BASICSTRING_CLASS_H +#define DEF_BASICSTRING_CLASS_H + +#include + +template class Vector; + +template +class BasicString { + protected: + T *m_string; + u32int m_length; + + public: + BasicString(); + BasicString(const T* string, u32int length); + BasicString(const BasicString &other); + BasicString(const T, u32int count = 1); + virtual ~BasicString(); + + void affect(const BasicString &other); + void affect(const T* string, u32int length); + void affect(const T value, u32int count = 1); + void operator= (const BasicString &other) { affect(other); } + + bool compare(const BasicString &other) const; + bool compare(const T* string, u32int length) const; + bool operator== (const BasicString &other) const { return compare(other); } + bool operator!= (const BasicString &other) const { return !compare(other); } + + BasicString& append(const BasicString &other); + BasicString& append(const T* string, u32int length); + BasicString& append(const T other); + BasicString& operator+= (const BasicString &other) { return append(other); } + BasicString& operator+= (const T other) { return append(other); } + + BasicString concat(const BasicString &other) const; + BasicString concat(const T* string, u32int length) const; + BasicString concat(const T other) const; + + T& operator[] (int index) const { return m_string[index]; } + + u32int size() const { return m_length; } + void clear(); + bool empty() const { return m_length == 0; } + + Vector< BasicString > split(T sep) const; + BasicString substr(s32int start, u32int size); +}; + +#include "BasicString.class.cpp" + +#endif diff --git a/Source/Library/Common/Bitset.class.cpp b/Source/Library/Common/Bitset.class.cpp new file mode 100644 index 0000000..ec4e62c --- /dev/null +++ b/Source/Library/Common/Bitset.class.cpp @@ -0,0 +1,62 @@ +#include "Bitset.class.h" + +Bitset::Bitset() { +} + +Bitset::Bitset(u32int size) { + init(size, (u32int*)Mem::kalloc(INDEX_FROM_BIT(size))); +} + +Bitset::Bitset(u32int size, u32int *ptr) { + init(size, ptr); +} + +Bitset::~Bitset() { + Mem::kfree(m_data); +} + +void Bitset::init(u32int size, u32int *ptr) { + m_size = size; + m_data = ptr; + for (u32int i = 0; i < INDEX_FROM_BIT(m_size); i++) { + m_data[i] = 0; + } + m_usedCount = 0; +} + +void Bitset::setBit(u32int number) { + u32int idx = INDEX_FROM_BIT(number); + u32int off = OFFSET_FROM_BIT(number); + m_data[idx] |= (0x1 << off); + m_usedCount++; +} + +void Bitset::clearBit(u32int number) { + u32int idx = INDEX_FROM_BIT(number); + u32int off = OFFSET_FROM_BIT(number); + m_data[idx] &= ~(0x1 << off); + m_usedCount--; +} + +bool Bitset::testBit(u32int number) { + u32int idx = INDEX_FROM_BIT(number); + u32int off = OFFSET_FROM_BIT(number); + return (m_data[idx] & (0x1 << off)); +} + +u32int Bitset::firstFreeBit() { + for (u32int i = 0; i < INDEX_FROM_BIT(m_size); i++) { + if (m_data[i] != 0xFFFFFFFF) { + for (int j = 0; j < 32; j++) { + if (!(m_data[i] & (0x1 << j))) { + return (i * 4 * 8) + j; + } + } + } + } + return (u32int) - 1; +} + +u32int Bitset::usedBits() { + return m_usedCount; +} diff --git a/Source/Library/Common/Bitset.class.h b/Source/Library/Common/Bitset.class.h new file mode 100644 index 0000000..8a0707d --- /dev/null +++ b/Source/Library/Common/Bitset.class.h @@ -0,0 +1,31 @@ +#ifndef DEF_BITSET_CLASS_H +#define DEF_BITSET_CLASS_H + +#include + +#define INDEX_FROM_BIT(a) (a/(8*4)) +#define OFFSET_FROM_BIT(a) (a%(8*4)) + +class Bitset { + private: + u32int m_size; + u32int *m_data; + u32int m_usedCount; + + public: + Bitset(); + Bitset(u32int size); + Bitset(u32int size, u32int *ptr); + ~Bitset(); + + void init(u32int size, u32int *ptr); + + void setBit(u32int number); + void clearBit(u32int number); + bool testBit(u32int number); + u32int firstFreeBit(); + + u32int usedBits(); +}; + +#endif diff --git a/Source/Library/Common/ByteArray.class.cpp b/Source/Library/Common/ByteArray.class.cpp new file mode 100644 index 0000000..2a42702 --- /dev/null +++ b/Source/Library/Common/ByteArray.class.cpp @@ -0,0 +1,59 @@ +#include "ByteArray.class.h" + +//Define size of a uchar_repr_t +#define CHARSZ(x) (x.c[0] == 0 ? 0 : (x.c[1] == 0 ? 1 : (x.c[2] == 0 ? 2 : (x.c[3] == 0 ? 3 : 4)))) + +using namespace CMem; + +ByteArray::ByteArray(const char* c) : BasicString() { + m_length = strlen(c); + memcpy(m_string, (u8int*)c, m_length); +} + +void ByteArray::affect(const String &string, u8int encoding) { + m_length = 0; + for (u32int i = 0; i < string.size(); i++) { + uchar_repr_t a = string[i].encode(encoding); + m_length += CHARSZ(a); + } + if (m_string != 0) delete m_string; + if (m_length == 0) { + m_string = 0; + return; + } + m_string = new u8int[m_length]; + u32int x = 0; + for (u32int i = 0; i < string.size(); i++) { + uchar_repr_t a = string[i].encode(encoding); + memcpy(m_string + x, (u8int*)a.c, CHARSZ(a)); + x += CHARSZ(a); + } +} + +void ByteArray::resize(u32int size) { + if (size == m_length) return; + if (size == 0) { + delete m_string; + m_length = 0; + m_string = 0; + } + u8int *nd = new u8int[size]; + if (size < m_length) { + memcpy(nd, m_string, size); + } else { + memcpy(nd, m_string, m_length); + memset(nd + m_length, 0, size - m_length); + } + delete m_string; + m_string = nd; + m_length = size; +} + +String ByteArray::toString (u8int encoding) { + char* c = new char[m_length + 1]; + memcpy((u8int*)c, m_string, m_length); + c[m_length] = 0; //Add NULL terminator + String r(c, encoding); + delete c; + return r; +} diff --git a/Source/Library/Common/ByteArray.class.h b/Source/Library/Common/ByteArray.class.h new file mode 100644 index 0000000..339e0d4 --- /dev/null +++ b/Source/Library/Common/ByteArray.class.h @@ -0,0 +1,27 @@ +#ifndef DEF_BYTEARRAY_CLASS_H +#define DEF_BYTEARRAY_CLASS_H + +#include + +class ByteArray : public BasicString { + public: + ByteArray() : BasicString() {} + ByteArray(const BasicString &bs) : BasicString() { + m_length = bs.size(); + m_string = new u8int[m_length]; + for (u32int i = 0; i < m_length; i++) + m_string[i] = bs[i]; + } + ByteArray(const ByteArray& other) : BasicString(other) {} + ByteArray(const char* c); + ByteArray(u32int size) : BasicString((u8int)0, size) {} + ByteArray(const String &string, u8int encoding = UE_UTF8) : BasicString() { affect(string, encoding); } + + void affect(const String& string, u8int encoding = UE_UTF8); + void resize(u32int size); + + String toString(u8int encoding = UE_UTF8); + operator u8int* () { return m_string; } +}; + +#endif diff --git a/Source/Library/Common/CMem.ns.cpp b/Source/Library/Common/CMem.ns.cpp new file mode 100644 index 0000000..37cdf0c --- /dev/null +++ b/Source/Library/Common/CMem.ns.cpp @@ -0,0 +1,35 @@ +#include + +namespace CMem { + +//Standard C functions +u8int *memcpy(u8int *dest, const u8int *src, int count) { + for (int i = 0; i < count; i++) { + dest[i] = src[i]; + } + return dest; +} + +u8int *memset(u8int *dest, u8int val, int count) { + for (int i = 0; i < count; i++) { + dest[i] = val; + } + return dest; +} + +u16int *memsetw(u16int *dest, u16int val, int count) { + for (int i = 0; i < count; i++) { + dest[i] = val; + } + return dest; +} + +u32int strlen(const char *str) { + u32int i = 0; + while (str[i]) { + i++; + } + return i; +} + +} diff --git a/Source/Library/Common/CMem.ns.h b/Source/Library/Common/CMem.ns.h new file mode 100644 index 0000000..f0c15da --- /dev/null +++ b/Source/Library/Common/CMem.ns.h @@ -0,0 +1,17 @@ +#ifdef DEF_COMMON + +#ifndef DEF_CMEM_NS_H +#define DEF_CMEM_NS_H + +//This namespace contains basic memory managment functions + +namespace CMem { + u8int *memcpy(u8int *dest, const u8int *src, int count); + u8int *memset(u8int *dest, u8int val, int count); + u16int *memsetw(u16int *dest, u16int val, int count); + u32int strlen(const char *str); +} + +#endif + +#endif diff --git a/Source/Library/Common/OrderedArray.class.cpp b/Source/Library/Common/OrderedArray.class.cpp new file mode 100644 index 0000000..8b8f24f --- /dev/null +++ b/Source/Library/Common/OrderedArray.class.cpp @@ -0,0 +1,54 @@ +template +OrderedArray::OrderedArray(u32int max_size) { + m_array = (T*)Memory::alloc(max_size * sizeof(T*)); + m_size = 0; + m_maxSize = max_size; +} + +template +OrderedArray::OrderedArray(T **addr, u32int max_size) { + m_array = addr; + memset((u8int*)addr, 0, max_size * sizeof(T*)); + m_size = 0; + m_maxSize = max_size; +} + +template +OrderedArray::~OrderedArray() { + //Free memory +} + +template +void OrderedArray::insert(T *element) { + if (m_size == m_maxSize) return; //Array is full + u32int iterator = 0; + while (iterator < m_size && *(m_array[iterator]) < *element) { + iterator++; + } + if (iterator == m_size) { + m_array[m_size++] = element; + } else { + u32int pos = iterator; + while (iterator < m_size) { + iterator++; + m_array[iterator] = m_array[iterator - 1]; + } + m_size++; + m_array[pos] = element; + } +} + +template +T *OrderedArray::lookup(int index) { + return m_array[index]; +} + +template +void OrderedArray::remove(int index) { + m_size--; + while (index < m_size) { + m_array[index] = m_array[index + 1]; + index++; + } +} + diff --git a/Source/Library/Common/OrderedArray.class.h b/Source/Library/Common/OrderedArray.class.h new file mode 100644 index 0000000..3091249 --- /dev/null +++ b/Source/Library/Common/OrderedArray.class.h @@ -0,0 +1,29 @@ +#ifndef DEF_ORDARRAY_CLASS +#define DEF_ORDARRAY_CLASS + +#include + +template +class OrderedArray { + private: + T *m_array[]; + u32int m_size; + u32int m_maxSize; + + public: + OrderedArray(u32int max_size); + OrderedArray(T **addr, u32int max_size); + ~OrderedArray(); + + u32int size() { return m_size; } + + void insert(T *element); + T *lookup(int index); + void remove(int index); + + T *operator[] (int index) { return lookup(index); } +}; + +#include "OrderedArray.class.cpp" + +#endif diff --git a/Source/Library/Common/Rand.ns.cpp b/Source/Library/Common/Rand.ns.cpp new file mode 100644 index 0000000..e568678 --- /dev/null +++ b/Source/Library/Common/Rand.ns.cpp @@ -0,0 +1,18 @@ +#include "Rand.ns.h" + +namespace Rand { + +u32int m = 2073741824, a = 50000, b = 1534; +u64int current = RANDOM_SEED; + +u64int rand() { + current = (u32int)(a*current + b); + while (current > m) current -= m; + return current; +} + +u64int max() { + return m; +} + +} diff --git a/Source/Library/Common/Rand.ns.h b/Source/Library/Common/Rand.ns.h new file mode 100644 index 0000000..71d4f60 --- /dev/null +++ b/Source/Library/Common/Rand.ns.h @@ -0,0 +1,12 @@ +#ifndef DEF_RAND_NS_H +#define DEF_RAND_NS_H + +#include + +namespace Rand { + u64int rand(); + u64int max(); +} + +#endif + diff --git a/Source/Library/Common/SimpleList.class.h b/Source/Library/Common/SimpleList.class.h new file mode 100644 index 0000000..64e37aa --- /dev/null +++ b/Source/Library/Common/SimpleList.class.h @@ -0,0 +1,70 @@ +#ifndef DEF_SIMPLELIST_CLASS_H +#define DEF_SIMPLELIST_CLASS_H + +/* This class implements a singly linked list. It is also used to represent one of its elements. */ + +template +class SimpleList { + protected: + T m_value; + SimpleList* m_next; + + public: + SimpleList(const T& value, SimpleList* next = 0) : m_value(value), m_next(next) {} + ~SimpleList() { + if (m_next != 0) + delete m_next; + } + + T& v() { return m_value; } + T& operator* () { return m_value; } + + SimpleList* cons(const T& value) { + return new SimpleList(value, this); + } + + SimpleList* next() { + return m_next; + } + + SimpleList* last() { + if (m_next == 0) return this; + return m_next->last(); + } + + SimpleList* delThis() { + SimpleList* ret = m_next; + Mem::kfree(this); + return ret; + } + + void delNext() { + if (m_next == 0) return; + SimpleList* temp = m_next; + m_next = m_next->m_next; + Mem::kfree(temp); + } + + SimpleList* removeOnce(const T& value) { + if (value == m_value) return delThis(); + for (SimpleList *iter = this; iter->next() != 0; iter = iter->next()) { + if (iter->next()->v() == value) { + iter->delNext(); + break; + } + } + return this; + } + + bool isEnd() { + return m_next == 0; + } + + u32int size() { + if (m_next == 0) + return 0; + return m_next->size() + 1; + } +}; + +#endif diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp new file mode 100644 index 0000000..d8913d9 --- /dev/null +++ b/Source/Library/Common/String.class.cpp @@ -0,0 +1,181 @@ +#include "String.class.h" +#include + +using namespace CMem; //strlen and memcpy + +String String::hex(u32int number) { + String ret; + ret.m_length = 10; + ret.m_string = new WChar[11]; + ret.m_string[0] = '0'; + ret.m_string[1] = 'x'; + ret.m_string[10] = 0; + + char hexdigits[] = "0123456789ABCDEF"; + for (unsigned int j = 0; j < 8; j++) { + ret.m_string[j + 2] = hexdigits[(number & 0xF0000000) >> 28]; + number = number << 4; + } + return ret; +} + +String String::number(s32int number) { + if (number == 0) return String("0"); + bool negative = false; + if (number < 0) { + negative = true; + number = 0 - number; + } + u32int order = 0, temp = number; + char numbers[] = "0123456789"; + while (temp > 0) { + order++; + temp /= 10; + } + + String ret; + ret.m_length = order; + ret.m_string = new WChar[order + 1]; + + for (u32int i = order; i > 0; i--) { + ret.m_string[i - 1] = numbers[number % 10]; + number /= 10; + } + + ret.m_string[order] = 0; + + if (negative) return String("-") += ret; + + return ret; +} + +String::String(const char* string, u8int encoding) { + m_string = 0; + m_length = 0; + affect(string, encoding); +} + +void String::affect (const char* string, u8int encoding) { + m_length = WChar::utfLen(string, encoding); + if (m_string != 0) delete [] m_string; + if (m_length == 0) { + m_string = 0; + return; + } + m_string = new WChar[m_length + 1]; + int i = 0, l = strlen(string), c = 0; + while (i < l) { + i += m_string[c].affect(string + i, encoding); + c++; + } + m_string[m_length] = 0; +} + +bool String::compare (const char* string, u8int encoding) const { + if (m_length != WChar::utfLen(string, encoding)) return false; + int i = 0, l = strlen(string), c = 0; + WChar tmp; + while (i < l) { + i += tmp.affect(string + i, encoding); + if (m_string[c] != tmp) return false; + c++; + } + return true; +} + +String& String::append (const char* other, u8int encoding) { + WChar* newdata = new WChar[m_length + WChar::utfLen(other, encoding) + 1]; + for (u32int i = 0; i < m_length; i++) { + newdata[i] = m_string[i]; + } + int i = 0, l = strlen(other), c = 0; + while (i < l) { + i += newdata[c + m_length].affect(other + i, encoding); + c++; + } + if (m_string != 0) delete [] m_string; + m_string = newdata; + m_length += strlen(other); + m_string[m_length] = 0; + return *this; +} + +String String::concat (const String &other) const { //Can be optimized + String ret(*this); + return (ret += other); +} + +String String::concat (const char* other, u8int encoding) const { //Can be optimized + String ret(*this); + return (ret.append(other, encoding)); +} + +String String::concat (WChar other) const { + String ret(*this); + return (ret += other); +} + +s64int String::toInt() const { + if (m_string == 0) return 0; + s32int pos = 0; + s64int number = 0; + bool negative = false; + if (m_string[0].value == '-') { + negative = true; + pos = 1; + } + while (m_string[pos] >= '0' && m_string[pos] <= '9') { + number *= 10; + number += (m_string[pos].value - '0'); + pos++; + } + if (negative) return 0 - number; + return number; +} + +u64int String::toInt16() const { + if (m_string == 0) return 0; + u32int pos = 0; + u64int number = 0; + if (m_string[0].value == '0' && m_string[1].value == 'x') pos = 2; + while (1) { + char c = m_string[pos]; + pos++; + if (c >= 'a' && c <= 'f') c -= ('a' - 'A'); //To uppercase + if (c >= '0' && c <= '9') { + number *= 16; + number += (c - '0'); + continue; + } + if (c >= 'A' && c <= 'F') { + number *= 16; + number += (c - 'A' + 10); + continue; + } + break; + } + return number; +} + +Vector String::split(WChar c) const { + Vector ret; + ret.push(String("")); + for (u32int i = 0; i < m_length; i++) { + if (m_string[i] == c) { + ret.push(String("")); + } else { + ret.back() += m_string[i]; + } + } + return ret; +} + +String String::substr(s32int start, u32int size) { + if (start < 0) start = m_length - start; + String ret; + ret.m_string = new WChar[size + 1]; + ret.m_length = size; + memcpy((u8int*)ret.m_string, (const u8int*)(m_string + start), size * sizeof(WChar)); + ret.m_string[size] = 0; + return ret; +} diff --git a/Source/Library/Common/String.class.h b/Source/Library/Common/String.class.h new file mode 100644 index 0000000..3e50d35 --- /dev/null +++ b/Source/Library/Common/String.class.h @@ -0,0 +1,46 @@ +#ifndef DEF_STRING_CLASS +#define DEF_STRING_CLASS + +#include +#include + +class String : public BasicString { + public: + static String hex(u32int number); + static String number(s32int number); + + String(const char* string, u8int encoding = UE_UTF8); + String() : BasicString() {} + String(const String &other) : BasicString (other) {} + + void affect(const char* string, u8int encoding = UE_UTF8); + void operator= (const char* other) { affect(other); } + void operator= (const String& other) { BasicString::affect(other); } + + bool compare(const char* string, u8int encoding = UE_UTF8) const; + bool operator== (const char* other) const { return compare(other); } + bool operator!= (const char* other) { return !compare(other); } + bool operator== (const String& other) const { return BasicString::compare(other); } + bool operator!= (const String& other) const { return !BasicString::compare(other); } + + String& append(const char* other, u8int encoding = UE_UTF8); + String &operator+= (const String &other) { BasicString::append(other); return *this; } + String &operator+= (const char* other) { return append(other); } + String &operator+= (WChar other) { BasicString::append(other); return *this; } + + String concat(const String &other) const; + String concat(const char* other, u8int encoding = UE_UTF8) const; + String concat(WChar other) const; + 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 + + Vector split(WChar c) const; + + String substr(s32int start, u32int size); +}; + +#endif diff --git a/Source/Library/Common/Vector.class.cpp b/Source/Library/Common/Vector.class.cpp new file mode 100644 index 0000000..02ae9be --- /dev/null +++ b/Source/Library/Common/Vector.class.cpp @@ -0,0 +1,135 @@ +using namespace CMem; //strlen and memcpy + +#define DELDATA if (m_data != NULL and m_size != 0) { \ + for (u32int i = 0; i < m_size; i++) { \ + m_data[i].~T(); \ + } \ + Mem::kfree(m_data); \ +} + +template +Vector::Vector() { + //DEBUG_HEX((u32int)this); DEBUG(" NEW EMPTY"); + //DEBUG_HEX(sizeof(T)); DEBUG(" sizeof(T)"); + m_data = 0; + m_size = 0; +} + +template +Vector::Vector(u32int size) { + //DEBUG_HEX((u32int)this); DEBUG(" NEW ZERO"); + m_data = new T[size]; + m_size = size; +} + +template +Vector::Vector(u32int size, const T& value) { + //DEBUG_HEX((u32int)this); DEBUG(" NEW FILLED"); + //m_data = (T*)Mem::kalloc(size * sizeof(T)); + m_data = new T[size]; + m_size = size; + for (u32int i = 0; i < m_size; i++) { + new (&m_data[i]) T(value); + } + /*for (u32int i = 0; i < size; i++) { + m_data[i] = new(&m_data[i]) T(value); + }*/ +} + +template +Vector::Vector(const Vector &other) { + //DEBUG_HEX((u32int)this); DEBUG(" COPY REF"); + m_size = other.m_size; + m_data = (T*)Mem::kalloc(m_size * sizeof(T)); + for (u32int i = 0; i < m_size; i++) { + new(&m_data[i]) T(other.m_data[i]); + } +} + +template +Vector& Vector::operator= (const Vector &other) { + //DEBUG_HEX((u32int)this); DEBUG(" COPY EQ"); + DELDATA; + m_size = other.m_size; + m_data = (T*)Mem::kalloc(m_size * sizeof(T)); + for (u32int i = 0; i < m_size; i++) { + new(&m_data[i]) T(other.m_data[i]); + } + return *this; +} + +template +Vector::~Vector() { + //DEBUG_HEX((u32int)this); DEBUG(" DELETE"); + DELDATA; + //if (m_data != 0) delete[] m_data; +} + +template +T& Vector::operator[] (u32int index) const { + return m_data[index]; +} + +template +void Vector::push(const T& element) { + T* newdata = (T*)Mem::kalloc((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); + m_data = newdata; +} + +/* template +void Vector::push(T& element) { + T* newdata = (T*)Memory::alloc((m_size + 1) * sizeof(T)); + memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T)); + //memcpy((u8int*)newdata + (m_size * sizeof(T)), (const u8int*) element, sizeof(T)); //Copy + new(&newdata[m_size]) T(element); //Construct by copy + m_size++; + Memory::free(m_data); + m_data = newdata; +} */ + +template +void Vector::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)); + memcpy((u8int*)newdata, (const u8int*) m_data, m_size * sizeof(T)); + Mem::kfree(m_data); + m_data = newdata; +} + +template +T& Vector::back() const { + return m_data[m_size - 1]; +} + +template +T& Vector::front() const { + return m_data[0]; +} + + +template +u32int Vector::size() const { + return m_size; +} + +template +bool Vector::empty() const { + return m_size == 0; +} + +template +void Vector::clear() { + if (empty()) return; + DELDATA + m_data = 0; + m_size = 0; +} diff --git a/Source/Library/Common/Vector.class.h b/Source/Library/Common/Vector.class.h new file mode 100644 index 0000000..436e2f9 --- /dev/null +++ b/Source/Library/Common/Vector.class.h @@ -0,0 +1,36 @@ +#ifndef DEF_VECTOR_CLASS +#define DEF_VECTOR_CLASS + +#include + +template +class Vector { + private: + T *m_data; + u32int m_size; + + public: + Vector(); + Vector(u32int size); + Vector(u32int size, const T& value); + Vector(const Vector &other); + Vector& operator= (const Vector &other); + ~Vector(); + + T& operator[] (u32int index) const; + + void push(const T& element); + //void push(T& element); + void pop(); + + T& back() const; + T& front() const; + + u32int size() const; + bool empty() const; + void clear(); +}; + +#include "Vector.class.cpp" + +#endif diff --git a/Source/Library/Common/WChar.class.cpp b/Source/Library/Common/WChar.class.cpp new file mode 100644 index 0000000..5485bb8 --- /dev/null +++ b/Source/Library/Common/WChar.class.cpp @@ -0,0 +1,155 @@ +#include "WChar.class.h" + +#ifdef THIS_IS_MELON_KERNEL +using namespace CMem; +#endif + +#ifdef THIS_IS_MELON_USERLAND +using namespace CMem; +#endif + +WChar WChar::CP437[] = { //These are the UTF8 equivalents for the 128 extra characters of code page 437 + "Ç", "ü", "é", "â", "ä", "à", "å", "ç", "ê", "ë", "è", "ï", "î", "ì", "Ä", "Å", + "É", "æ", "Æ", "ô", "ö", "ò", "û", "ù", "ÿ", "Ö", "Ü", "¢", "£", "¥", "₧", "ƒ", + "á", "í", "ó", "ú", "ñ", "Ñ", "ª", "º", "¿", "⌐", "¬", "½", "¼", "¡", "«", "»", + "░", "▒", "▓", "│", "┤", "╡", "╢", "╖", "╕", "╣", "║", "╗", "╝", "╜", "╛", "┐", + "└", "┴", "┬", "├", "─", "┼", "╞", "╟", "╚", "╔", "╩", "╦", "╠", "═", "╬", "¤", + "╨", "╤", "╥", "╙", "╘", "╒", "╓", "╫", "╪", "┘", "┌", "█", "▄", "▌", "▐", "▀", + "α", "ß", "Γ", "π", "Σ", "σ", "µ", "τ", "Φ", "Θ", "Ω", "δ", "∞", "φ", "ε", "∩", + "≡", "±", "≥", "≤", "⌠", "⌡", "÷", "≈", "°", "∙", "·", "√", "ⁿ", "²", "■", "⍽" +}; + +WChar::WChar() { + value = 0; +} + +WChar::WChar(char c) { + affectAscii(c); +} + +WChar::WChar(const char* c, u8int encoding) { + if (encoding == UE_UTF8) affectUtf8(c); + if (encoding == UE_UTF16) affectUtf16(c); + if (encoding == UE_UTF32) affectUtf32(c); +} + +u32int WChar::ucharLen(const char* c, u8int encoding) { + if (encoding == UE_UTF8) { + if ((c[0] & 0x80) == 0) return 1; + else if ((c[0] & 0xE0) == 0xC0) return 2; + else if ((c[0] & 0xF0) == 0xE0) return 3; + else if ((c[0] & 0xF8) == 0xF0) return 4; + else return 1; + } else if (encoding == UE_UTF16) { + if ((c[0] & 0xFC) == 0xD8 and (c[2] & 0xFC) == 0xDC) return 4; + else return 2; + } else if (encoding == UE_UTF32) { + return 4; + } + return 1; +} + +u32int WChar::utfLen(const char* c, u8int encoding) { + int i = 0, l = strlen(c), co = 0; + while (i < l) { + i += ucharLen(c + i, encoding); + co++; + } + return co; +} + +void WChar::affectAscii(char c) { + if (c >= 0) value = c; + else value = CP437[c + 128]; +} + +u32int WChar::affectUtf8(const char* c) { //Returns the number of bytes for the character + if ((c[0] & 0x80) == 0) { + value = c[0]; //0x80 = 10000000b + return 1; + } + if ((c[0] & 0xE0) == 0xC0) { // 11100000b, 11000000b + value = ((c[0] & 0x1F) << 6) | (c[1] & 0x3F); + if (value < 128) value = 0; //Bad value + return 2; + } + if ((c[0] & 0xF0) == 0xE0) { // 11110000b, 11100000b + value = ((c[0] & 0x0F) << 12) | ((c[1] & 0x3F) << 6) | (c[2] & 0x3F); + if (value < 2048) value = 0; //Bad value + if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed + if (value >= 0xFFFE and value <= 0xFFFF) value = 0; + return 3; + } + if ((c[0] & 0xF8) == 0xF0) { // 11111000b, 11110000b + value = ((c[0] & 0x0E) << 18) | ((c[1] & 0x3F) << 12) | ((c[2] & 0x3F) << 6) | (c[3] & 0x3F); + if (value < 65536) value = 0; //Bad value + return 4; + } + value = 0; //Something wrong happenned + return 1; +} + +u32int WChar::affectUtf16(const char* c) { + if ((c[0] & 0xFC) == 0xD8 and // 11111100b, 11011000b + (c[2] & 0xFC) == 0xDC) { // 11111100b, 11011100b + u32int w = ((c[0] & 0x03) << 2) | ((c[1] & 0xC0) >> 6); + u32int x = (c[1] & 0x3F); + u32int y = ((c[2] & 0x03) << 8) | (c[2]); + value = ((w + 1) << 16) | (x << 10) | y; + if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed + if (value >= 0xFFFE and value <= 0xFFFF) value = 0; + return 4; + } else { + value = (c[0] << 8) | (c[1]); + if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed + if (value >= 0xFFFE and value <= 0xFFFF) value = 0; + return 2; + } +} + +u32int WChar::affectUtf32(const char* c) { + value = (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3]; + if (value >= 0xD800 and value <= 0xDFFF) value = 0; //These values are unallowed + if (value >= 0xFFFE and value <= 0xFFFF) value = 0; + return 4; +} + +u8int WChar::toAscii() { + if (value < 128) return (char)value; + for (int i = 0; i < 128; i++) { + if (CP437[i] == value) return (i + 128); + } + return '?'; +} + +uchar_repr_t WChar::toUtf8() { + uchar_repr_t r; + r.i = 0; + if (value < 128) { + r.c[0] = value; + } else if (value < 4096) { + r.c[0] = 0xC0 | ((value & 0x07C0) >> 6); + r.c[1] = 0x80 | (value & 0x3F); + } else if (value < 65536) { + r.c[0] = 0xE0 | ((value & 0xF000) >> 12); + r.c[1] = 0x80 | ((value & 0x0FC0) >> 6); + r.c[2] = 0x80 | (value & 0x003F); + } else { + r.c[0] = 0xF0 | ((value & 0x1C0000) >> 18); + r.c[1] = 0x80 | ((value & 0x3F000) >> 12); + r.c[2] = 0x80 | ((value & 0x0FC0) >> 6); + r.c[3] = 0x80 | (value & 0x003F); + } + return r; +} + +//TODO : code WChar::toUtf16 + +uchar_repr_t WChar::toUtf32() { + uchar_repr_t r; + r.c[0] = (value >> 24) & 0xFF; + r.c[1] = (value >> 16) & 0xFF; + r.c[2] = (value >> 8) & 0xFF; + r.c[3] = value & 0xFF; + return r; +} diff --git a/Source/Library/Common/WChar.class.h b/Source/Library/Common/WChar.class.h new file mode 100644 index 0000000..3eca3d3 --- /dev/null +++ b/Source/Library/Common/WChar.class.h @@ -0,0 +1,89 @@ +#ifndef DEF_UCHAR_CLASS_H +#define DEF_UCHAR_CLASS_H + +#include + +#ifndef THIS_IS_NOT_MELON +#include +#endif + +enum { + UE_UTF8, + UE_UTF16, + UE_UTF32, +}; + +union uchar_repr_t { + char c[4]; + u32int i; +}; + +struct WChar { + u32int value; + static WChar CP437[]; //Codepage 437, used for conversion from/to ascii + + WChar(); //Creates a null character + WChar(char c); //From ascii character + WChar(const char* c, u8int encoding = UE_UTF8); //From utf8 string + + static u32int ucharLen(const char* c, u8int encoding = UE_UTF8); //Returns count of bytes in one unicode character + static u32int utfLen(const char* c, u8int encoding = UE_UTF8); //Returns count of utf8 characters in string + + void affectAscii(char c); + u32int affectUtf8(const char* c); + u32int affectUtf16(const char* c); + u32int affectUtf32(const char* c); + + u32int affect(const char* c, u8int encoding = UE_UTF8) { + if (encoding == UE_UTF8) return affectUtf8(c); + if (encoding == UE_UTF16) return affectUtf16(c); + if (encoding == UE_UTF32) return affectUtf32(c); + affectAscii(c[0]); //Default case :/ + return 1; + } + + u8int toAscii(); + + uchar_repr_t toUtf8(); + uchar_repr_t toUtf16(); + uchar_repr_t toUtf32(); + + uchar_repr_t encode(u8int encoding = UE_UTF8) { + if (encoding == UE_UTF8) return toUtf8(); + //if (encoding == UE_UTF16) return toUtf16(); + if (encoding == UE_UTF32) return toUtf32(); + uchar_repr_t x; + x.c[0] = toAscii(); + return x; + } + + inline WChar operator+ (u32int other) { + WChar r; + r.value = value + other; + return r; + } + inline WChar operator- (u32int other) { + WChar r; + r.value = value - other; + return r; + } + inline WChar& operator+= (u32int other) { + value += other; + return *this; + } + inline WChar& operator-= (u32int other) { + value -= other; + return *this; + } + inline bool operator== (u32int other) { + return value == other; + } + inline u32int operator= (u32int v) { + value = v; + return v; + } + + inline operator u32int () { return value; } +}; + +#endif diff --git a/Source/Library/Common/types.h b/Source/Library/Common/types.h new file mode 100644 index 0000000..ca6f73d --- /dev/null +++ b/Source/Library/Common/types.h @@ -0,0 +1,19 @@ +#ifndef DEF_TYPES_WTF_H +#define DEF_TYPES_WTF_H + +//This file defines base types. It's made to be used also by C programs + +typedef unsigned int addr_t; +typedef unsigned long long u64int; +typedef unsigned int u32int; +typedef unsigned short u16int; +typedef unsigned char u8int; +typedef long long s64int; +typedef int s32int; +typedef short s16int; +typedef char s8int; + +#define U64 unsigned long long +#define S64 long long + +#endif diff --git a/Source/Library/Makefile b/Source/Library/Makefile new file mode 100644 index 0000000..f7d337b --- /dev/null +++ b/Source/Library/Makefile @@ -0,0 +1,33 @@ +.PHONY: clean, mrproper + +CXX = g++ +CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I Common -I Userland -D THIS_IS_MELON_USERLAND + +LDFLAGS = -r +LD = ld + +Library = Melon.o +Objects = Common/WChar.class.uo \ + Common/CMem.ns.uo \ + Userland/Syscall/Syscall.wtf.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 $@ + +clean: + echo "* Removing object files..." + rm -rf $(Objects) + +mrproper: clean + echo "* Removing library..." + rm -rf $(Library) diff --git a/Source/Library/Userland/Syscall/Syscall.wtf.cpp b/Source/Library/Userland/Syscall/Syscall.wtf.cpp new file mode 100644 index 0000000..2c03b20 --- /dev/null +++ b/Source/Library/Userland/Syscall/Syscall.wtf.cpp @@ -0,0 +1,20 @@ +#include "Syscall.wtf.h" + +int main(); + +unsigned int syscall(unsigned int n, unsigned int a, unsigned int b, unsigned int c) { + unsigned int r; + asm volatile ("int $64;" + : "=a"(r) : "a"(n), "b"(a), "c"(b), "d"(c)); + return r; +} + +extern "C" void start() { + unsigned int r = main(); + asm volatile("int $66" : : "a"(r)); +} + +void putch(char c) { + unsigned int x = c; + syscall(0xFFFFFF01, x); +} diff --git a/Source/Library/Userland/Syscall/Syscall.wtf.h b/Source/Library/Userland/Syscall/Syscall.wtf.h new file mode 100644 index 0000000..b220d14 --- /dev/null +++ b/Source/Library/Userland/Syscall/Syscall.wtf.h @@ -0,0 +1,9 @@ +#ifndef DEF_SYSCALL_WTF_H +#define DEF_SYSCALL_WTF_H + +#include + +void putch(char); +unsigned int syscall(unsigned int n, unsigned int a, unsigned int b = 0, unsigned int c = 0); + +#endif diff --git a/Source/Library/Userland/common.h b/Source/Library/Userland/common.h new file mode 100644 index 0000000..27218f7 --- /dev/null +++ b/Source/Library/Userland/common.h @@ -0,0 +1,10 @@ +#ifndef DEF_COMMON +#define DEF_COMMON + +#define NULL 0 + +#include + +#include + +#endif diff --git a/Source/Tools/MakeRamFS/MakeRamFS b/Source/Tools/MakeRamFS/MakeRamFS deleted file mode 100755 index be1dc1a..0000000 Binary files a/Source/Tools/MakeRamFS/MakeRamFS and /dev/null differ -- cgit v1.2.3 From e589a45295a871f38d4a1d1f23b370b612f99be5 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 17:17:36 +0200 Subject: Syscall interface starts being implemented ! --- Source/Applications/SampleApps/Makefile | 2 +- Source/Applications/SampleApps/cxxdemo.cpp | 10 +++- Source/Kernel/Makefile | 5 +- Source/Kernel/SyscallManager/IDT.ns.cpp | 19 +++++-- Source/Kernel/SyscallManager/Res.ns.cpp | 55 ++++++++++++++++++ Source/Kernel/SyscallManager/Res.ns.h | 15 +++++ Source/Kernel/SyscallManager/Ressource.class.cpp | 65 ++++++++++++++++++++++ Source/Kernel/SyscallManager/Ressource.class.h | 54 ++++++++++++++++++ .../Kernel/VTManager/VirtualTerminal-sc.proto.cpp | 11 ++++ Source/Kernel/VTManager/VirtualTerminal.proto.cpp | 7 ++- Source/Kernel/VTManager/VirtualTerminal.proto.h | 8 ++- Source/Library/Common/SimpleList.class.h | 2 + Source/Library/Interface/VirtualTerminal.iface.h | 8 +++ Source/Library/Makefile | 4 +- Source/Library/Userland/Start.cpp | 8 +++ .../Userland/Syscall/RessourceCaller.class.cpp | 18 ++++++ .../Userland/Syscall/RessourceCaller.class.h | 22 ++++++++ Source/Library/Userland/Syscall/Syscall.wtf.cpp | 23 ++++---- Source/Library/Userland/Syscall/Syscall.wtf.h | 6 +- Source/Library/Userland/VirtualTerminal.class.h | 22 ++++++++ 20 files changed, 338 insertions(+), 26 deletions(-) create mode 100644 Source/Kernel/SyscallManager/Res.ns.cpp create mode 100644 Source/Kernel/SyscallManager/Res.ns.h create mode 100644 Source/Kernel/SyscallManager/Ressource.class.cpp create mode 100644 Source/Kernel/SyscallManager/Ressource.class.h create mode 100644 Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp create mode 100644 Source/Library/Interface/VirtualTerminal.iface.h create mode 100644 Source/Library/Userland/Start.cpp create mode 100644 Source/Library/Userland/Syscall/RessourceCaller.class.cpp create mode 100644 Source/Library/Userland/Syscall/RessourceCaller.class.h create mode 100644 Source/Library/Userland/VirtualTerminal.class.h diff --git a/Source/Applications/SampleApps/Makefile b/Source/Applications/SampleApps/Makefile index 6d12f3f..d45011e 100644 --- a/Source/Applications/SampleApps/Makefile +++ b/Source/Applications/SampleApps/Makefile @@ -4,7 +4,7 @@ ASM = nasm ASMFLAGS = -f elf CXX = g++ -CXXFLAGS = -nostartfiles -nostdlib -fno-exceptions -fno-rtti -I ../../Library/Common -I ../../Library/Userland -D THIS_IS_MELON_USERLAND +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 diff --git a/Source/Applications/SampleApps/cxxdemo.cpp b/Source/Applications/SampleApps/cxxdemo.cpp index 5d95d28..af16599 100644 --- a/Source/Applications/SampleApps/cxxdemo.cpp +++ b/Source/Applications/SampleApps/cxxdemo.cpp @@ -1,10 +1,14 @@ #include #include +#include int main() { + VirtualTerminal x = VirtualTerminal::get(); for (char c = ' '; c <= 'z'; c++) { - syscall(0xFFFFFF02, (unsigned int)c); - putch(c); + sleep((u32int)c / 4); + x.put(c); } - putch('\n'); + x.put("\n"); + x.writeHex(0xDEADBEEF); + x.put("\n"); } diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 257c53d..a090ac6 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 . -I ../Library/Common -Wall -Werror -Wno-write-strings -funsigned-char -D THIS_IS_MELON_KERNEL -D RANDOM_SEED=1`date +%N`LL -g +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 @@ -38,6 +38,7 @@ Objects = Core/loader.wtf.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 \ @@ -59,6 +60,8 @@ Objects = Core/loader.wtf.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 \ diff --git a/Source/Kernel/SyscallManager/IDT.ns.cpp b/Source/Kernel/SyscallManager/IDT.ns.cpp index 46e6ee2..63b340a 100644 --- a/Source/Kernel/SyscallManager/IDT.ns.cpp +++ b/Source/Kernel/SyscallManager/IDT.ns.cpp @@ -2,6 +2,7 @@ #include #include #include +#include using namespace Sys; //For outb @@ -75,12 +76,18 @@ extern "C" void interrupt_handler(registers_t regs) { doSwitch = doSwitch or Task::IRQwakeup(regs.int_no - 32); } if (regs.int_no == 64) { - 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); + 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(); diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp new file mode 100644 index 0000000..aceadf7 --- /dev/null +++ b/Source/Kernel/SyscallManager/Res.ns.cpp @@ -0,0 +1,55 @@ +#include "Res.ns.h" + +#include +#include + +namespace Res { + +Ressource** ressources = 0; +u32int size = 0; + +void expand() { //Expands size of ressources array of 20 entries + size += 20; + Ressource** tmp = (Ressource**)Mem::kalloc(size * sizeof(Ressource*)); + for (u32int i = 0; i < size; i++) { + if (i < size - 20) tmp[i] = ressources[i]; + else tmp[i] = 0; + } + Mem::kfree(ressources); + ressources = tmp; +} + +u32int registerRes(Ressource* r) { + if (ressources == 0 or size == 0) { + ressources = (Ressource**)Mem::kalloc(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 + if (a == VT_IFACE_OBJTYPE) return Task::currProcess()->getVirtualTerminal()->resId(); + 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 + +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..4e62d79 --- /dev/null +++ b/Source/Kernel/SyscallManager/Ressource.class.cpp @@ -0,0 +1,65 @@ +#include "Ressource.class.h" +#include + +Ressource::Ressource(u8int type) { + m_id = Res::registerRes(this); + m_type = type; + m_calls = 0; + + addCall0(0, (call0)&Ressource::resType); +} + +Ressource::~Ressource() { + Res::unregisterRes(m_id); + delete m_calls; +} + +void Ressource::addCall0(u8int id, call0 c) { + call_t e = {0, id, {c}}; + m_calls = m_calls->cons(e); +} + +void Ressource::addCall1(u8int id, call1 c) { + call_t e = {1, id, {0}}; + e.c1 = c; + m_calls = m_calls->cons(e); +} + +void Ressource::addCall2(u8int id, call2 c) { + call_t e = {2, id, {0}}; + e.c2 = c; + m_calls = m_calls->cons(e); +} + +void Ressource::addCall3(u8int id, call3 c) { + call_t e = {3, id, {0}}; + e.c3 = c; + m_calls = m_calls->cons(e); +} + +void Ressource::addCall4(u8int id, call4 c) { + call_t e = {4, id, {0}}; + e.c4 = c; + m_calls = m_calls->cons(e); +} + +void Ressource::addCall5(u8int id, call5 c) { + call_t e = {5, id, {0}}; + e.c5 = c; + m_calls = m_calls->cons(e); +} + +u32int Ressource::doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e) { + for (SimpleList *iter = m_calls; iter != 0; iter = iter->next()) { + call_t &ce = iter->v(); + 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); + } + } + 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..5f4e6bf --- /dev/null +++ b/Source/Kernel/SyscallManager/Ressource.class.h @@ -0,0 +1,54 @@ +#ifndef DEF_RESSOURCE_CLASS_H +#define DEF_RESSOURCE_CLASS_H + +#include + +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); + +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 *m_calls; + + protected: + Ressource(u8int type); + ~Ressource(); + + void addCall0(u8int id, call0 c); + void addCall1(u8int id, call1 c); + void addCall2(u8int id, call2 c); + void addCall3(u8int id, call3 c); + void addCall4(u8int id, call4 c); + void addCall5(u8int id, call5 c); + + 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/VTManager/VirtualTerminal-sc.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp new file mode 100644 index 0000000..8948657 --- /dev/null +++ b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp @@ -0,0 +1,11 @@ +#include "VirtualTerminal.proto.h" + +u32int VirtualTerminal::writeHexSC(u32int number) { + writeHex(number); + return 0; +} + +u32int VirtualTerminal::putSC(u32int code) { + put(WChar(code)); + return 0; +} diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp index 0612f1d..b7c7340 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp @@ -2,7 +2,12 @@ #include #include -VirtualTerminal::VirtualTerminal() : m_kbdMutex(false), m_kbdbuffMutex(false), m_kbdbuff() { +#include + +VirtualTerminal::VirtualTerminal() : + Ressource(VT_IFACE_OBJTYPE), m_kbdMutex(false), m_kbdbuffMutex(false), m_kbdbuff() { + addCall1(VT_IFACE_WRITEHEX, (call1)&VirtualTerminal::writeHexSC); + addCall1(VT_IFACE_PUT, (call1)&VirtualTerminal::putSC); } VirtualTerminal::~VirtualTerminal() { diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.h b/Source/Kernel/VTManager/VirtualTerminal.proto.h index 9d0afa0..487233d 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.h +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h @@ -7,16 +7,22 @@ #include #include +#include + struct vtchr { u8int color; WChar c; }; -class VirtualTerminal { +class VirtualTerminal : public Ressource { protected: Mutex m_kbdMutex, m_kbdbuffMutex; Vector m_kbdbuff; //Key press events buffer + //SYSCALLS : + u32int writeHexSC(u32int); + u32int putSC(u32int); + public: VirtualTerminal(); virtual ~VirtualTerminal(); diff --git a/Source/Library/Common/SimpleList.class.h b/Source/Library/Common/SimpleList.class.h index 64e37aa..3e0f968 100644 --- a/Source/Library/Common/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 + /* This class implements a singly linked list. It is also used to represent one of its elements. */ template diff --git a/Source/Library/Interface/VirtualTerminal.iface.h b/Source/Library/Interface/VirtualTerminal.iface.h new file mode 100644 index 0000000..661162f --- /dev/null +++ b/Source/Library/Interface/VirtualTerminal.iface.h @@ -0,0 +1,8 @@ +#ifndef DEF_VITRUALTERMINAL_IFACE_H +#define DEF_VITRUALTERMINAL_IFACE_H + +#define VT_IFACE_OBJTYPE 0x10 +#define VT_IFACE_PUT 0x01 +#define VT_IFACE_WRITEHEX 0x02 + +#endif diff --git a/Source/Library/Makefile b/Source/Library/Makefile index f7d337b..b9be0a0 100644 --- a/Source/Library/Makefile +++ b/Source/Library/Makefile @@ -9,7 +9,9 @@ LD = ld Library = Melon.o Objects = Common/WChar.class.uo \ Common/CMem.ns.uo \ - Userland/Syscall/Syscall.wtf.uo + Userland/Syscall/Syscall.wtf.uo \ + Userland/Syscall/RessourceCaller.class.uo \ + Userland/Start.uo all: $(Library) echo "* Done with library" diff --git a/Source/Library/Userland/Start.cpp b/Source/Library/Userland/Start.cpp new file mode 100644 index 0000000..02eb951 --- /dev/null +++ b/Source/Library/Userland/Start.cpp @@ -0,0 +1,8 @@ +#include + +int main(); + +extern "C" void start() { + u32int r = main(); + asm volatile("int $66" : : "a"(r)); +} diff --git a/Source/Library/Userland/Syscall/RessourceCaller.class.cpp b/Source/Library/Userland/Syscall/RessourceCaller.class.cpp new file mode 100644 index 0000000..2d7b6ba --- /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::getObjId(u32int type) { + return syscall(0xFFFFFE00, type); +} + +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..3ad8900 --- /dev/null +++ b/Source/Library/Userland/Syscall/RessourceCaller.class.h @@ -0,0 +1,22 @@ +#ifndef DEF_RESSOURCECALLER_CLASS_H +#define DEF_RESSOURCECALLER_CLASS_H + +#include + +class RessourceCaller { + private: + u32int m_id; + u32int m_type; + + protected: + RessourceCaller(u32int id, u32int type); + static u32int getObjId(u32int type); + 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 index 2c03b20..a28c202 100644 --- a/Source/Library/Userland/Syscall/Syscall.wtf.cpp +++ b/Source/Library/Userland/Syscall/Syscall.wtf.cpp @@ -1,20 +1,21 @@ #include "Syscall.wtf.h" -int main(); - -unsigned int syscall(unsigned int n, unsigned int a, unsigned int b, unsigned int c) { - unsigned int r; +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)); + : "=a"(r) : "a"(n), "b"(a), "c"(b), "d"(c), "D"(d), "S"(e)); return r; } -extern "C" void start() { - unsigned int r = main(); - asm volatile("int $66" : : "a"(r)); -} - void putch(char c) { - unsigned int x = 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 index b220d14..0401a89 100644 --- a/Source/Library/Userland/Syscall/Syscall.wtf.h +++ b/Source/Library/Userland/Syscall/Syscall.wtf.h @@ -3,7 +3,11 @@ #include +//Three basic syscalls, just for testing void putch(char); -unsigned int syscall(unsigned int n, unsigned int a, unsigned int b = 0, unsigned int c = 0); +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/VirtualTerminal.class.h b/Source/Library/Userland/VirtualTerminal.class.h new file mode 100644 index 0000000..a7bb4c2 --- /dev/null +++ b/Source/Library/Userland/VirtualTerminal.class.h @@ -0,0 +1,22 @@ +#include + +#include + +#include + +class VirtualTerminal : public RessourceCaller { + public: + static VirtualTerminal get() { + u32int id = RessourceCaller::getObjId(VT_IFACE_OBJTYPE); + return VirtualTerminal(id); + } + VirtualTerminal(u32int id) : RessourceCaller(id, VT_IFACE_OBJTYPE) {} + + void writeHex(u32int number) { + doCall(VT_IFACE_WRITEHEX, number); + } + + void put(WChar c) { + doCall(VT_IFACE_PUT, c); + } +}; -- cgit v1.2.3 From eb7b832d47bcbd74181028c62e871d407ba63a23 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 17:50:02 +0200 Subject: More work on syscalls --- Source/Applications/SampleApps/cxxdemo.cpp | 6 ++++-- Source/Kernel/SyscallManager/Res.ns.cpp | 4 ++++ Source/Kernel/TaskManager/Process.class.cpp | 23 +++++++++++++++++--- Source/Kernel/TaskManager/Process.class.h | 9 ++++++-- Source/Kernel/TaskManager/Thread.class.cpp | 25 +++++++++++++++++++--- Source/Kernel/TaskManager/Thread.class.h | 6 +++++- Source/Library/Interface/Process.iface.h | 8 +++++++ Source/Library/Interface/Thread.iface.h | 8 +++++++ Source/Library/Userland/Binding/Process.class.h | 19 ++++++++++++++++ Source/Library/Userland/Binding/Thread.class.h | 19 ++++++++++++++++ .../Userland/Binding/VirtualTerminal.class.h | 22 +++++++++++++++++++ Source/Library/Userland/VirtualTerminal.class.h | 22 ------------------- 12 files changed, 138 insertions(+), 33 deletions(-) create mode 100644 Source/Library/Interface/Process.iface.h create mode 100644 Source/Library/Interface/Thread.iface.h create mode 100644 Source/Library/Userland/Binding/Process.class.h create mode 100644 Source/Library/Userland/Binding/Thread.class.h create mode 100644 Source/Library/Userland/Binding/VirtualTerminal.class.h delete mode 100644 Source/Library/Userland/VirtualTerminal.class.h diff --git a/Source/Applications/SampleApps/cxxdemo.cpp b/Source/Applications/SampleApps/cxxdemo.cpp index af16599..8da475a 100644 --- a/Source/Applications/SampleApps/cxxdemo.cpp +++ b/Source/Applications/SampleApps/cxxdemo.cpp @@ -1,11 +1,13 @@ #include #include -#include +#include +#include int main() { VirtualTerminal x = VirtualTerminal::get(); + Thread t = Thread::get(); for (char c = ' '; c <= 'z'; c++) { - sleep((u32int)c / 4); + t.sleep((u32int)c / 4); x.put(c); } x.put("\n"); diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp index aceadf7..274f6f1 100644 --- a/Source/Kernel/SyscallManager/Res.ns.cpp +++ b/Source/Kernel/SyscallManager/Res.ns.cpp @@ -1,6 +1,8 @@ #include "Res.ns.h" #include +#include +#include #include namespace Res { @@ -42,6 +44,8 @@ void unregisterRes(u32int id) { 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 if (a == VT_IFACE_OBJTYPE) return Task::currProcess()->getVirtualTerminal()->resId(); + if (a == PR_IFACE_OBJTYPE) return Task::currProcess()->resId(); + if (a == TH_IFACE_OBJTYPE) return Task::currThread()->resId(); return 0; } else { if (ressource > size or ressources[ressource] == 0) { diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index bad4e52..39428b4 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -3,12 +3,13 @@ #include #include #include +#include namespace Mem { extern Heap kheap; } -Process::Process() { //Private constructor, does nothing +Process::Process() : Ressource(PR_IFACE_OBJTYPE) { //Private constructor, does nothing } Process* Process::createKernel(String cmdline, VirtualTerminal *vt) { @@ -53,7 +54,9 @@ Process* Process::run(String filename, FSNode* cwd, u32int uid) { } } -Process::Process(String cmdline, 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); m_pid = Task::nextPid(); m_cmdline = cmdline; m_retval = 0; @@ -99,7 +102,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 @@ -133,3 +136,17 @@ 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; +} diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h index fdd1377..1b614b7 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -9,13 +9,15 @@ #include #include +#include + #define P_ZOMBIE 0 #define P_RUNNING 1 #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 @@ -26,7 +28,7 @@ class Thread; class File; -class Process { +class Process : public Ressource { friend class Thread; private: @@ -67,6 +69,9 @@ class Process { void setVirtualTerminal(VirtualTerminal* vt); u32int getState() { return m_state; } + //System calls + u32int exitSC(); + u32int allocPageSC(u32int); }; #endif diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 9a2df3f..2237457 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -4,6 +4,8 @@ #include #include +#include + void runThread(Thread* thread, void* data, thread_entry_t entry_point) { if (thread->m_isKernel) { asm volatile("sti"); @@ -49,10 +51,10 @@ void runThread(Thread* thread, void* data, thread_entry_t entry_point) { } } -Thread::Thread() { //Private constructor, does nothing +Thread::Thread() : Ressource(TH_IFACE_OBJTYPE) { //Private constructor, does nothing } -Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) { +Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) : Ressource(TH_IFACE_OBJTYPE) { if (iskernel) { setup(Task::getKernelProcess(), entry_point, data, true); } else { @@ -60,7 +62,7 @@ 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(TH_IFACE_OBJTYPE) { setup(process, entry_point, data, false); } @@ -75,6 +77,9 @@ Thread::~Thread() { } void Thread::setup(Process* process, thread_entry_t entry_point, void* data, bool isKernel) { + addCall1(TH_IFACE_SLEEP, (call1)&Thread::sleepSC); + addCall1(TH_IFACE_FINISH, (call1)&Thread::finishSC); + m_isKernel = isKernel; m_process = process; m_kernelStack.addr = Mem::kalloc(STACKSIZE); @@ -199,3 +204,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 aeb1f93..8a7d45e 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); @@ -59,6 +59,10 @@ class Thread { } return false; } + + //Syscalls + u32int sleepSC(u32int msecs); + u32int finishSC(u32int errcode); }; #endif diff --git a/Source/Library/Interface/Process.iface.h b/Source/Library/Interface/Process.iface.h new file mode 100644 index 0000000..d639725 --- /dev/null +++ b/Source/Library/Interface/Process.iface.h @@ -0,0 +1,8 @@ +#ifndef DEF_PROCESS_IFACE_H +#define DEF_PROCESS_IFACE_H + +#define PR_IFACE_OBJTYPE 0x20 +#define PR_IFACE_EXIT 0x01 +#define PR_IFACE_ALLOCPAGE 0x02 + +#endif diff --git a/Source/Library/Interface/Thread.iface.h b/Source/Library/Interface/Thread.iface.h new file mode 100644 index 0000000..2a64924 --- /dev/null +++ b/Source/Library/Interface/Thread.iface.h @@ -0,0 +1,8 @@ +#ifndef DEF_THREAD_IFACE_H +#define DEF_THREAD_IFACE_H + +#define TH_IFACE_OBJTYPE 0x21 +#define TH_IFACE_SLEEP 0x01 +#define TH_IFACE_FINISH 0x02 + +#endif diff --git a/Source/Library/Userland/Binding/Process.class.h b/Source/Library/Userland/Binding/Process.class.h new file mode 100644 index 0000000..c484e19 --- /dev/null +++ b/Source/Library/Userland/Binding/Process.class.h @@ -0,0 +1,19 @@ +#include + +#include + +class Process : public RessourceCaller { + public: + static Process get() { + u32int id = RessourceCaller::getObjId(PR_IFACE_OBJTYPE); + return Process(id); + } + Process(u32int id) : RessourceCaller(id, PR_IFACE_OBJTYPE) {} + + void exit() { + doCall(PR_IFACE_EXIT); + } + void allocPage(u32int pos) { + doCall(PR_IFACE_ALLOCPAGE, 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..beef9c5 --- /dev/null +++ b/Source/Library/Userland/Binding/Thread.class.h @@ -0,0 +1,19 @@ +#include + +#include + +class Thread : public RessourceCaller { + public: + static Thread get() { + u32int id = RessourceCaller::getObjId(TH_IFACE_OBJTYPE); + return Thread(id); + } + Thread(u32int id) : RessourceCaller(id, TH_IFACE_OBJTYPE) {} + + void sleep(u32int msecs) { + doCall(TH_IFACE_SLEEP, msecs); + } + void finish(u32int errcode) { + doCall(TH_IFACE_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..a7bb4c2 --- /dev/null +++ b/Source/Library/Userland/Binding/VirtualTerminal.class.h @@ -0,0 +1,22 @@ +#include + +#include + +#include + +class VirtualTerminal : public RessourceCaller { + public: + static VirtualTerminal get() { + u32int id = RessourceCaller::getObjId(VT_IFACE_OBJTYPE); + return VirtualTerminal(id); + } + VirtualTerminal(u32int id) : RessourceCaller(id, VT_IFACE_OBJTYPE) {} + + void writeHex(u32int number) { + doCall(VT_IFACE_WRITEHEX, number); + } + + void put(WChar c) { + doCall(VT_IFACE_PUT, c); + } +}; diff --git a/Source/Library/Userland/VirtualTerminal.class.h b/Source/Library/Userland/VirtualTerminal.class.h deleted file mode 100644 index a7bb4c2..0000000 --- a/Source/Library/Userland/VirtualTerminal.class.h +++ /dev/null @@ -1,22 +0,0 @@ -#include - -#include - -#include - -class VirtualTerminal : public RessourceCaller { - public: - static VirtualTerminal get() { - u32int id = RessourceCaller::getObjId(VT_IFACE_OBJTYPE); - return VirtualTerminal(id); - } - VirtualTerminal(u32int id) : RessourceCaller(id, VT_IFACE_OBJTYPE) {} - - void writeHex(u32int number) { - doCall(VT_IFACE_WRITEHEX, number); - } - - void put(WChar c) { - doCall(VT_IFACE_PUT, c); - } -}; -- cgit v1.2.3 From ccf807eb4ff541bb849c4f370d34123cb23d7d76 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 18:39:52 +0200 Subject: Heap included as well in userland library --- .gitignore | 1 + Source/Applications/SampleApps/Makefile | 2 +- .../Kernel/Devices/Floppy/FloppyController.class.h | 2 +- Source/Kernel/Makefile | 7 +- Source/Kernel/MemoryManager/Heap-index.class.cpp | 51 ----- Source/Kernel/MemoryManager/Heap.class.cpp | 212 ------------------- Source/Kernel/MemoryManager/Heap.class.h | 79 ------- Source/Kernel/MemoryManager/Mem.ns.cpp | 2 +- Source/Kernel/TaskManager/Mutex.class.cpp | 28 --- Source/Kernel/TaskManager/Mutex.class.h | 21 -- Source/Kernel/TaskManager/Process.class.cpp | 9 + Source/Kernel/TaskManager/Process.class.h | 3 +- Source/Kernel/TaskManager/Task.wtf.asm | 7 - Source/Kernel/VTManager/VirtualTerminal.proto.h | 2 +- Source/Library/Common/Heap-index.class.cpp | 51 +++++ Source/Library/Common/Heap.class.cpp | 232 +++++++++++++++++++++ Source/Library/Common/Heap.class.h | 92 ++++++++ Source/Library/Common/Mutex.class.cpp | 45 ++++ Source/Library/Common/Mutex.class.h | 21 ++ Source/Library/Interface/Process.iface.h | 1 + Source/Library/Link.ld | 32 +++ Source/Library/Makefile | 12 +- Source/Library/Userland/Binding/Process.class.h | 3 + Source/Library/Userland/Start.cpp | 27 +++ Source/Library/Userland/common.h | 16 ++ 25 files changed, 551 insertions(+), 407 deletions(-) delete mode 100644 Source/Kernel/MemoryManager/Heap-index.class.cpp delete mode 100644 Source/Kernel/MemoryManager/Heap.class.cpp delete mode 100644 Source/Kernel/MemoryManager/Heap.class.h delete mode 100644 Source/Kernel/TaskManager/Mutex.class.cpp delete mode 100644 Source/Kernel/TaskManager/Mutex.class.h create mode 100644 Source/Library/Common/Heap-index.class.cpp create mode 100644 Source/Library/Common/Heap.class.cpp create mode 100644 Source/Library/Common/Heap.class.h create mode 100644 Source/Library/Common/Mutex.class.cpp create mode 100644 Source/Library/Common/Mutex.class.h create mode 100644 Source/Library/Link.ld diff --git a/.gitignore b/.gitignore index 2cf7152..4246a36 100644 --- a/.gitignore +++ b/.gitignore @@ -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 -#include +#include #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/Heap-index.class.cpp b/Source/Kernel/MemoryManager/Heap-index.class.cpp deleted file mode 100644 index 3280736..0000000 --- a/Source/Kernel/MemoryManager/Heap-index.class.cpp +++ /dev/null @@ -1,51 +0,0 @@ -#include "Heap.class.h" - -/* - * Implementation of the functions for managing heap index - */ - -void Heap::insertIntoIndex(heap_header_t *e) { - //If index is full, return - if ((m_index.size * sizeof(heap_header_t*) + (u32int)m_index.data) >= m_start) return; - - u32int iterator = 0; - while (iterator < m_index.size && m_index.data[iterator]->size < e->size) { - if (m_index.data[iterator] == e) return; - iterator++; - } - if (iterator == m_index.size) { - m_index.data[m_index.size++] = e; - } else { - u32int pos = iterator; - iterator = m_index.size; - while (iterator > pos) { - m_index.data[iterator] = m_index.data[iterator - 1]; - iterator--; - } - m_index.size++; - m_index.data[pos] = e; - } -} - -u32int Heap::findIndexEntry(heap_header_t *e) { - for (u32int i = 0; i < m_index.size; i++) { - if (m_index.data[i] == e) - return i; - } - return (u32int) - 1; -} - -void Heap::removeFromIndex(u32int idx) { - m_index.size--; - while (idx < m_index.size) { - m_index.data[idx] = m_index.data[idx + 1]; - idx++; - } -} - -void Heap::removeFromIndex(heap_header_t *e) { - u32int i = findIndexEntry(e); - if (i != (u32int) - 1) { - removeFromIndex(i); - } -} diff --git a/Source/Kernel/MemoryManager/Heap.class.cpp b/Source/Kernel/MemoryManager/Heap.class.cpp deleted file mode 100644 index 365b4f0..0000000 --- a/Source/Kernel/MemoryManager/Heap.class.cpp +++ /dev/null @@ -1,212 +0,0 @@ -#include "Heap.class.h" -#include - -Heap::Heap() : m_mutex(MUTEX_FALSE) { - m_usable = false; - m_index.data = 0; - m_index.size = 0; -} - -Heap::~Heap() { - //TODO (optionnal) : free pages. -} - -void Heap::create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw) { - if (m_usable) return; - - if (start & 0x0FFF) start = (start & 0xFFFFF000) + 0x1000; - if (size & 0x0FFF) size = (size & 0xFFFFF000) + 0x1000; - m_start = start + idxsize; //m_start is start of real data, start is start of index. - m_end = start + size; - - m_pagedir = pagedir; - m_user = user; - m_rw = rw; - - //Allocate frames for heap - for (u32int i = start ; i < m_end; i += 0x1000) { - m_pagedir->allocFrame(i, m_user, m_rw); - } - m_pagedir->switchTo(); - - m_index.data = (heap_header_t **)start; //Set index start. start == start of all heap - m_index.size = 0; - - heap_header_t *hole = (heap_header_t*) m_start; //m_start == start of data - hole->size = (m_end - m_start); - hole->magic = HEAP_MAGIC; - hole->is_hole = true; - - heap_footer_t *hole_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t)); - hole_footer->header = hole; - hole_footer->magic = HEAP_MAGIC; - - insertIntoIndex(hole); - - m_usable = true; - m_free = (m_end - m_start); - - m_mutex.unlock(); -} - -void Heap::expand(u32int quantity) { - if (quantity & 0x00000FFF) - quantity = (quantity & 0xFFFFF000) + 0x1000; - - u32int newEnd = m_end + quantity; - - for (u32int i = m_end; i < newEnd; i++) { - m_pagedir->allocFrame(i, m_user, m_rw); - } - - heap_footer_t *last_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t)); - heap_header_t *last_header = last_footer->header; - if (last_header->is_hole) { //Last block of heap is a hole, update its size - removeFromIndex(last_header); - last_header->size += quantity; - - last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t)); - - last_footer->magic = HEAP_MAGIC; - last_footer->header = last_header; - - insertIntoIndex(last_header); - } else { //Last block is not a hole. Just add a new hole at the end - last_header = (heap_header_t*)m_end; - last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t)); - - last_header->is_hole = true; - last_header->magic = HEAP_MAGIC; - last_header->size = quantity; - - last_footer->magic = HEAP_MAGIC; - last_footer->header = last_header; - - insertIntoIndex(last_header); - } - - m_end = newEnd; - m_free += quantity; -} - -void Heap::contract() { //Automatically work out how much we can contract - heap_footer_t *last_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t)); - heap_header_t *last_header = last_footer->header; - if (last_header->is_hole == false) return; //We need a hole at end of heap - - u32int quantity = 0; - while ((m_end - m_start) - quantity > HEAP_MIN_SIZE and - (last_header->size - quantity) > 0x1000) //Always keep at least 0x1000 free at end - quantity += 0x1000; - if (quantity == 0) return; - - u32int newEnd = m_end - quantity; - m_free -= quantity; - - removeFromIndex(last_header); - last_header->size -= quantity; - last_footer = (heap_footer_t*)((u32int)last_footer - quantity); - last_footer->magic = HEAP_MAGIC; - last_footer->header = last_header; - insertIntoIndex(last_header); - - for (u32int i = newEnd; i < m_end; i += 0x1000) { - m_pagedir->freeFrame(i); - } - - m_end = newEnd; -} - -void *Heap::alloc(u32int sz, bool no_expand) { - m_mutex.waitLock(); - - u32int newsize = sz + sizeof(heap_header_t) + sizeof(heap_footer_t); - u32int iterator = 0; - while (iterator < m_index.size) { - if (m_index.data[iterator]->size >= newsize) break; - iterator++; - } - if (iterator == m_index.size) { //No hole is big enough - if (no_expand) { - m_mutex.unlock(); - return 0; - } - expand((sz & 0xFFFFF000) + 0x1000); - m_mutex.unlock(); - return alloc(sz, true); //Recurse call - } - - heap_header_t *loc = m_index.data[iterator]; - heap_footer_t *footer = (heap_footer_t*)((u32int)loc + loc->size - sizeof(heap_footer_t)); - loc->is_hole = false; //Update current header - - removeFromIndex(loc); - - //Here we create a new hole after currently allocated block, but only if we have enough space. If we don't, we simply allocate a bigger block so that we don't loose space - if (loc->size > (newsize + sizeof(heap_header_t) + sizeof(heap_footer_t))) { - loc->size = newsize; //Update header for return block - - heap_footer_t *newfooter = (heap_footer_t*)((u32int)loc + newsize - sizeof(heap_footer_t)); //Write footer for return block - newfooter->header = loc; - newfooter->magic = HEAP_MAGIC; - - heap_header_t *nextloc = (heap_header_t*)((u32int)loc + newsize); //Write header for new hole - nextloc->is_hole = true; - nextloc->magic = HEAP_MAGIC; - nextloc->size = ((u32int)footer - (u32int)nextloc + sizeof(heap_footer_t)); - - footer->header = nextloc; //Write footer for new hole - footer->magic = HEAP_MAGIC; - - insertIntoIndex(nextloc); - } - - m_free -= loc->size; - - m_mutex.unlock(); - - return (void*)((u32int)loc + sizeof(heap_header_t)); -} - -void Heap::free(void *ptr) { - if (ptr == 0) return; - - heap_header_t *header = (heap_header_t*) ((u32int)ptr - sizeof(heap_header_t)); - heap_footer_t *footer = (heap_footer_t*)((u32int)header + header->size - sizeof(heap_footer_t)); - if (header->magic != HEAP_MAGIC or footer->magic != HEAP_MAGIC) return; - - m_mutex.waitLock(); - - m_free += header->size; - - //Unify left - heap_footer_t *prev_footer = (heap_footer_t*)((u32int)header - sizeof(heap_footer_t)); - if (prev_footer->magic == HEAP_MAGIC && prev_footer->header->is_hole) { - header = prev_footer->header; - removeFromIndex(header); - - footer->header = header; - header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t)); - } - - //Unify right - heap_header_t *next_header = (heap_header_t*)((u32int)footer + sizeof(heap_footer_t)); - if (next_header->magic == HEAP_MAGIC && next_header->is_hole) { - removeFromIndex(next_header); - footer = (heap_footer_t*)((u32int)footer + next_header->size); - - footer->header = header; - header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t)); - } - - header->is_hole = true; - - insertIntoIndex(header); - - if ((u32int)footer == (m_end - sizeof(heap_footer_t)) and - header->size >= 0x2000 and (m_end - m_start > HEAP_MIN_SIZE)) { - contract(); - } - - m_mutex.unlock(); -} diff --git a/Source/Kernel/MemoryManager/Heap.class.h b/Source/Kernel/MemoryManager/Heap.class.h deleted file mode 100644 index 291c9ce..0000000 --- a/Source/Kernel/MemoryManager/Heap.class.h +++ /dev/null @@ -1,79 +0,0 @@ -#ifndef DEF_HEAP_CLASS_H -#define DEF_HEAP_CLASS_H - -#include -#include - -//Heap minimum size : 2M -#define HEAP_MIN_SIZE 0x00200000 -//Heap magic number, for verifications -#define HEAP_MAGIC 0xBEEF1337 - -struct heap_header_t { - u32int magic; - bool is_hole; - u32int size; -}; - -struct heap_footer_t { - u32int magic; - heap_header_t *header; -}; - -struct heap_index_t { - heap_header_t **data; - u32int size; -}; - -class PageDirectory; - -class Heap { - private: - bool m_usable, m_user, m_rw; - u32int m_free, m_start, m_end; - heap_index_t m_index; - PageDirectory* m_pagedir; - - Mutex m_mutex; - - void insertIntoIndex(heap_header_t *e); - u32int findIndexEntry(heap_header_t *e); - void removeFromIndex(u32int idx); - void removeFromIndex(heap_header_t *e); - - void expand(u32int quantity); - void contract(); //Quantity is automatically calculated - - public: - Heap(); - ~Heap(); - - void create(u32int start, u32int size, u32int idxsize, PageDirectory* pagedir, bool user, bool rw); - - void* alloc(u32int sz, bool no_expand = false); - void free(void* ptr); - - bool usable() { - m_mutex.waitLock(); - bool ret = m_usable; - m_mutex.unlock(); - return ret; - } - - u32int size() { - m_mutex.waitLock(); - u32int ret = m_end - m_start; - m_mutex.unlock(); - return ret; - } - - u32int free() { - m_mutex.waitLock(); - u32int ret = m_free; - m_mutex.unlock(); - return ret; - } -}; - - -#endif 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 #include -#include +#include namespace Mem { diff --git a/Source/Kernel/TaskManager/Mutex.class.cpp b/Source/Kernel/TaskManager/Mutex.class.cpp deleted file mode 100644 index 8ba274f..0000000 --- a/Source/Kernel/TaskManager/Mutex.class.cpp +++ /dev/null @@ -1,28 +0,0 @@ -#include "Mutex.class.h" -#include - -extern "C" u32int atomic_exchange(u32int* ptr, u32int newval); - -Mutex::Mutex(u32int locked) { - m_locked = locked; -} - -bool Mutex::lock() { - if (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) return false; //The lock was already locked - return true; -} - -void Mutex::waitLock() { - while (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) { - if (Task::currThread() != 0) Task::currThread()->sleep(10); //Wait 10ms - else return; - } -} - -void Mutex::unlock() { - m_locked = MUTEX_FALSE; -} - -bool Mutex::locked() { - return m_locked; -} diff --git a/Source/Kernel/TaskManager/Mutex.class.h b/Source/Kernel/TaskManager/Mutex.class.h deleted file mode 100644 index 1e3f63d..0000000 --- a/Source/Kernel/TaskManager/Mutex.class.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef DEF_MUTEX_CLASS_H -#define DEF_MUTEX_CLASS_H - -#include - -#define MUTEX_FALSE 0 -#define MUTEX_TRUE 1 - -class Mutex { - private: - u32int m_locked; - - public: - Mutex(u32int locked = MUTEX_FALSE); - bool lock(); //Locks the mutex if it is not locked. Returns true if mutex could be locked, false if already locked - void waitLock(); //Locks the mutex, waiting for it to be unlocked before if necessary - void unlock(); - bool locked(); -}; - -#endif 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 #include #include -#include +#include #include #include @@ -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 #include -#include +#include #include #include diff --git a/Source/Library/Common/Heap-index.class.cpp b/Source/Library/Common/Heap-index.class.cpp new file mode 100644 index 0000000..3280736 --- /dev/null +++ b/Source/Library/Common/Heap-index.class.cpp @@ -0,0 +1,51 @@ +#include "Heap.class.h" + +/* + * Implementation of the functions for managing heap index + */ + +void Heap::insertIntoIndex(heap_header_t *e) { + //If index is full, return + if ((m_index.size * sizeof(heap_header_t*) + (u32int)m_index.data) >= m_start) return; + + u32int iterator = 0; + while (iterator < m_index.size && m_index.data[iterator]->size < e->size) { + if (m_index.data[iterator] == e) return; + iterator++; + } + if (iterator == m_index.size) { + m_index.data[m_index.size++] = e; + } else { + u32int pos = iterator; + iterator = m_index.size; + while (iterator > pos) { + m_index.data[iterator] = m_index.data[iterator - 1]; + iterator--; + } + m_index.size++; + m_index.data[pos] = e; + } +} + +u32int Heap::findIndexEntry(heap_header_t *e) { + for (u32int i = 0; i < m_index.size; i++) { + if (m_index.data[i] == e) + return i; + } + return (u32int) - 1; +} + +void Heap::removeFromIndex(u32int idx) { + m_index.size--; + while (idx < m_index.size) { + m_index.data[idx] = m_index.data[idx + 1]; + idx++; + } +} + +void Heap::removeFromIndex(heap_header_t *e) { + u32int i = findIndexEntry(e); + if (i != (u32int) - 1) { + removeFromIndex(i); + } +} diff --git a/Source/Library/Common/Heap.class.cpp b/Source/Library/Common/Heap.class.cpp new file mode 100644 index 0000000..34e4dc4 --- /dev/null +++ b/Source/Library/Common/Heap.class.cpp @@ -0,0 +1,232 @@ +#include "Heap.class.h" + +#ifdef THIS_IS_MELON_KERNEL +#include +#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; +} + +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; + if (size & 0x0FFF) size = (size & 0xFFFFF000) + 0x1000; + 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) { + 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; + + heap_header_t *hole = (heap_header_t*) m_start; //m_start == start of data + hole->size = (m_end - m_start); + hole->magic = HEAP_MAGIC; + hole->is_hole = true; + + heap_footer_t *hole_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t)); + hole_footer->header = hole; + hole_footer->magic = HEAP_MAGIC; + + insertIntoIndex(hole); + + m_usable = true; + m_free = (m_end - m_start); + + m_mutex.unlock(); +} + +void Heap::expand(u32int quantity) { + if (quantity & 0x00000FFF) + quantity = (quantity & 0xFFFFF000) + 0x1000; + + u32int newEnd = m_end + quantity; + + for (u32int i = m_end; i < newEnd; i++) { + ALLOC(i); + } + + heap_footer_t *last_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t)); + heap_header_t *last_header = last_footer->header; + if (last_header->is_hole) { //Last block of heap is a hole, update its size + removeFromIndex(last_header); + last_header->size += quantity; + + last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t)); + + last_footer->magic = HEAP_MAGIC; + last_footer->header = last_header; + + insertIntoIndex(last_header); + } else { //Last block is not a hole. Just add a new hole at the end + last_header = (heap_header_t*)m_end; + last_footer = (heap_footer_t*) (newEnd - sizeof(heap_footer_t)); + + last_header->is_hole = true; + last_header->magic = HEAP_MAGIC; + last_header->size = quantity; + + last_footer->magic = HEAP_MAGIC; + last_footer->header = last_header; + + insertIntoIndex(last_header); + } + + m_end = newEnd; + m_free += quantity; +} + +void Heap::contract() { //Automatically work out how much we can contract + heap_footer_t *last_footer = (heap_footer_t*) (m_end - sizeof(heap_footer_t)); + heap_header_t *last_header = last_footer->header; + if (last_header->is_hole == false) return; //We need a hole at end of heap + + u32int quantity = 0; + while ((m_end - m_start) - quantity > HEAP_MIN_SIZE and + (last_header->size - quantity) > 0x1000) //Always keep at least 0x1000 free at end + quantity += 0x1000; + if (quantity == 0) return; + + u32int newEnd = m_end - quantity; + m_free -= quantity; + + removeFromIndex(last_header); + last_header->size -= quantity; + last_footer = (heap_footer_t*)((u32int)last_footer - quantity); + last_footer->magic = HEAP_MAGIC; + last_footer->header = last_header; + insertIntoIndex(last_header); + + for (u32int i = newEnd; i < m_end; i += 0x1000) { + FREE(i); + } + + m_end = newEnd; +} + +void *Heap::alloc(u32int sz, bool no_expand) { + m_mutex.waitLock(); + + u32int newsize = sz + sizeof(heap_header_t) + sizeof(heap_footer_t); + u32int iterator = 0; + while (iterator < m_index.size) { + if (m_index.data[iterator]->size >= newsize) break; + iterator++; + } + if (iterator == m_index.size) { //No hole is big enough + if (no_expand) { + m_mutex.unlock(); + return 0; + } + expand((sz & 0xFFFFF000) + 0x1000); + m_mutex.unlock(); + return alloc(sz, true); //Recurse call + } + + heap_header_t *loc = m_index.data[iterator]; + heap_footer_t *footer = (heap_footer_t*)((u32int)loc + loc->size - sizeof(heap_footer_t)); + loc->is_hole = false; //Update current header + + removeFromIndex(loc); + + //Here we create a new hole after currently allocated block, but only if we have enough space. If we don't, we simply allocate a bigger block so that we don't loose space + if (loc->size > (newsize + sizeof(heap_header_t) + sizeof(heap_footer_t))) { + loc->size = newsize; //Update header for return block + + heap_footer_t *newfooter = (heap_footer_t*)((u32int)loc + newsize - sizeof(heap_footer_t)); //Write footer for return block + newfooter->header = loc; + newfooter->magic = HEAP_MAGIC; + + heap_header_t *nextloc = (heap_header_t*)((u32int)loc + newsize); //Write header for new hole + nextloc->is_hole = true; + nextloc->magic = HEAP_MAGIC; + nextloc->size = ((u32int)footer - (u32int)nextloc + sizeof(heap_footer_t)); + + footer->header = nextloc; //Write footer for new hole + footer->magic = HEAP_MAGIC; + + insertIntoIndex(nextloc); + } + + m_free -= loc->size; + + m_mutex.unlock(); + + return (void*)((u32int)loc + sizeof(heap_header_t)); +} + +void Heap::free(void *ptr) { + if (ptr == 0) return; + + heap_header_t *header = (heap_header_t*) ((u32int)ptr - sizeof(heap_header_t)); + heap_footer_t *footer = (heap_footer_t*)((u32int)header + header->size - sizeof(heap_footer_t)); + if (header->magic != HEAP_MAGIC or footer->magic != HEAP_MAGIC) return; + + m_mutex.waitLock(); + + m_free += header->size; + + //Unify left + heap_footer_t *prev_footer = (heap_footer_t*)((u32int)header - sizeof(heap_footer_t)); + if (prev_footer->magic == HEAP_MAGIC && prev_footer->header->is_hole) { + header = prev_footer->header; + removeFromIndex(header); + + footer->header = header; + header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t)); + } + + //Unify right + heap_header_t *next_header = (heap_header_t*)((u32int)footer + sizeof(heap_footer_t)); + if (next_header->magic == HEAP_MAGIC && next_header->is_hole) { + removeFromIndex(next_header); + footer = (heap_footer_t*)((u32int)footer + next_header->size); + + footer->header = header; + header->size = ((u32int)footer - (u32int)header + sizeof(heap_footer_t)); + } + + header->is_hole = true; + + insertIntoIndex(header); + + if ((u32int)footer == (m_end - sizeof(heap_footer_t)) and + header->size >= 0x2000 and (m_end - m_start > HEAP_MIN_SIZE)) { + contract(); + } + + m_mutex.unlock(); +} diff --git a/Source/Library/Common/Heap.class.h b/Source/Library/Common/Heap.class.h new file mode 100644 index 0000000..f5895c7 --- /dev/null +++ b/Source/Library/Common/Heap.class.h @@ -0,0 +1,92 @@ +#ifndef DEF_HEAP_CLASS_H +#define DEF_HEAP_CLASS_H + +#include +#include + +//Heap minimum size : 2M +#define HEAP_MIN_SIZE 0x00200000 +//Heap magic number, for verifications +#define HEAP_MAGIC 0xBEEF1337 + +struct heap_header_t { + u32int magic; + bool is_hole; + u32int size; +}; + +struct heap_footer_t { + u32int magic; + heap_header_t *header; +}; + +struct heap_index_t { + heap_header_t **data; + u32int size; +}; + +#ifdef THIS_IS_MELON_KERNEL +class PageDirectory; +#else +#include +#endif + +class Heap { + private: + 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; + + void insertIntoIndex(heap_header_t *e); + u32int findIndexEntry(heap_header_t *e); + void removeFromIndex(u32int idx); + void removeFromIndex(heap_header_t *e); + + void expand(u32int quantity); + void contract(); //Quantity is automatically calculated + + public: + 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); + + bool usable() { + m_mutex.waitLock(); + bool ret = m_usable; + m_mutex.unlock(); + return ret; + } + + u32int size() { + m_mutex.waitLock(); + u32int ret = m_end - m_start; + m_mutex.unlock(); + return ret; + } + + u32int free() { + m_mutex.waitLock(); + u32int ret = m_free; + m_mutex.unlock(); + return ret; + } +}; + + +#endif diff --git a/Source/Library/Common/Mutex.class.cpp b/Source/Library/Common/Mutex.class.cpp new file mode 100644 index 0000000..2e9a63c --- /dev/null +++ b/Source/Library/Common/Mutex.class.cpp @@ -0,0 +1,45 @@ +#include "Mutex.class.h" + +#ifdef THIS_IS_MELON_KERNEL +#include +#endif + +#ifdef THIS_IS_MELON_USERLAND +#include +#endif + +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; +} + +bool Mutex::lock() { + if (atomic_exchange(&m_locked, MUTEX_TRUE) == MUTEX_TRUE) return false; //The lock was already locked + return true; +} + +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 + } +} + +void Mutex::unlock() { + m_locked = MUTEX_FALSE; +} + +bool Mutex::locked() { + return m_locked; +} diff --git a/Source/Library/Common/Mutex.class.h b/Source/Library/Common/Mutex.class.h new file mode 100644 index 0000000..1e3f63d --- /dev/null +++ b/Source/Library/Common/Mutex.class.h @@ -0,0 +1,21 @@ +#ifndef DEF_MUTEX_CLASS_H +#define DEF_MUTEX_CLASS_H + +#include + +#define MUTEX_FALSE 0 +#define MUTEX_TRUE 1 + +class Mutex { + private: + u32int m_locked; + + public: + Mutex(u32int locked = MUTEX_FALSE); + bool lock(); //Locks the mutex if it is not locked. Returns true if mutex could be locked, false if already locked + void waitLock(); //Locks the mutex, waiting for it to be unlocked before if necessary + void unlock(); + bool locked(); +}; + +#endif 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 +#include + +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 +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 -- cgit v1.2.3 From 776753bfa0c411f4b1a5680409104904961fcbeb Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 18:46:59 +0200 Subject: Mem::kalloc and Mem::kfree renamed to Mem::alloc and Mem::kfree I renamed them so that they could have the same name in userland and in kernel space. We'll just know that if we're writing kernel code then we are allocating stuff in kernel memory, and if we're writing user code then we're allocating userland memory. --- Source/Kernel/FileSystems/RamFS/RamFS.class.cpp | 8 ++++---- Source/Kernel/Linker/ElfBinary.class.cpp | 2 +- Source/Kernel/Linker/MelonBinary.class.cpp | 2 +- Source/Kernel/MemoryManager/Mem.ns.cpp | 4 ++-- Source/Kernel/MemoryManager/Mem.ns.h | 4 ++-- Source/Kernel/MemoryManager/PageAlloc.ns.cpp | 4 ++-- Source/Kernel/MemoryManager/PhysMem.ns.cpp | 2 +- Source/Kernel/Shell/KernelShell-fs.class.cpp | 4 ++-- Source/Kernel/SyscallManager/Res.ns.cpp | 6 +++--- Source/Kernel/TaskManager/Thread.class.cpp | 4 ++-- Source/Kernel/common.h | 8 ++++---- Source/Library/Common/Bitset.class.cpp | 4 ++-- Source/Library/Common/SimpleList.class.h | 4 ++-- Source/Library/Common/Vector.class.cpp | 16 ++++++++-------- Source/Library/Makefile | 1 + 15 files changed, 37 insertions(+), 36 deletions(-) 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/ElfBinary.class.cpp b/Source/Kernel/Linker/ElfBinary.class.cpp index 450053f..27e5474 100644 --- a/Source/Kernel/Linker/ElfBinary.class.cpp +++ b/Source/Kernel/Linker/ElfBinary.class.cpp @@ -26,7 +26,7 @@ Binary* ElfBinary::load(File& file) { } //Load data for (SimpleList *iter = b->m_phdr; iter != 0; iter = iter->next()) { - iter->v().data = (u8int*)Mem::kalloc(iter->v().h.p_filesz); + 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); } diff --git a/Source/Kernel/Linker/MelonBinary.class.cpp b/Source/Kernel/Linker/MelonBinary.class.cpp index d6074de..0737b71 100644 --- a/Source/Kernel/Linker/MelonBinary.class.cpp +++ b/Source/Kernel/Linker/MelonBinary.class.cpp @@ -7,7 +7,7 @@ Binary* MelonBinary::load(File& file) { MelonBinary* r = new MelonBinary; file.read(&r->m_size); file.read(&r->m_org); - r->m_data = (u8int*)Mem::kalloc(r->m_size); + r->m_data = (u8int*)Mem::alloc(r->m_size); file.read(r->m_size, r->m_data); return r; } else { diff --git a/Source/Kernel/MemoryManager/Mem.ns.cpp b/Source/Kernel/MemoryManager/Mem.ns.cpp index c705b3b..c7f07f0 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.cpp +++ b/Source/Kernel/MemoryManager/Mem.ns.cpp @@ -39,14 +39,14 @@ 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); } diff --git a/Source/Kernel/MemoryManager/Mem.ns.h b/Source/Kernel/MemoryManager/Mem.ns.h index 15935c0..0d2b1da 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.h +++ b/Source/Kernel/MemoryManager/Mem.ns.h @@ -8,8 +8,8 @@ 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); 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/PhysMem.ns.cpp b/Source/Kernel/MemoryManager/PhysMem.ns.cpp index 25869f1..1b40e88 100644 --- a/Source/Kernel/MemoryManager/PhysMem.ns.cpp +++ b/Source/Kernel/MemoryManager/PhysMem.ns.cpp @@ -14,7 +14,7 @@ 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) { diff --git a/Source/Kernel/Shell/KernelShell-fs.class.cpp b/Source/Kernel/Shell/KernelShell-fs.class.cpp index fe1ecbf..cd52810 100644 --- a/Source/Kernel/Shell/KernelShell-fs.class.cpp +++ b/Source/Kernel/Shell/KernelShell-fs.class.cpp @@ -55,11 +55,11 @@ void KernelShell::cat(Vector& 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"; } diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp index 274f6f1..1779a00 100644 --- a/Source/Kernel/SyscallManager/Res.ns.cpp +++ b/Source/Kernel/SyscallManager/Res.ns.cpp @@ -12,18 +12,18 @@ u32int size = 0; void expand() { //Expands size of ressources array of 20 entries size += 20; - Ressource** tmp = (Ressource**)Mem::kalloc(size * sizeof(Ressource*)); + 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::kfree(ressources); + Mem::free(ressources); ressources = tmp; } u32int registerRes(Ressource* r) { if (ressources == 0 or size == 0) { - ressources = (Ressource**)Mem::kalloc(20 * sizeof(Ressource*)); + ressources = (Ressource**)Mem::alloc(20 * sizeof(Ressource*)); size = 20; for (u32int i = 0; i < 20; i++) ressources[i] = 0; } diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 2237457..315eae2 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -68,7 +68,7 @@ Thread::Thread(Process* process, thread_entry_t entry_point, void* data) : Resso Thread::~Thread() { Task::unregisterThread(this); - Mem::kfree(m_kernelStack.addr); + Mem::free(m_kernelStack.addr); if (m_userStack.addr != 0) { m_process->getPagedir()->switchTo(); m_process->heap().free(m_userStack.addr); @@ -82,7 +82,7 @@ void Thread::setup(Process* process, thread_entry_t entry_point, void* data, boo 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) { diff --git a/Source/Kernel/common.h b/Source/Kernel/common.h index c6da25e..86d76cd 100644 --- a/Source/Kernel/common.h +++ b/Source/Kernel/common.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/Library/Common/Bitset.class.cpp b/Source/Library/Common/Bitset.class.cpp index ec4e62c..a8d7ec8 100644 --- a/Source/Library/Common/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/Library/Common/SimpleList.class.h b/Source/Library/Common/SimpleList.class.h index 3e0f968..7b731db 100644 --- a/Source/Library/Common/SimpleList.class.h +++ b/Source/Library/Common/SimpleList.class.h @@ -36,7 +36,7 @@ class SimpleList { SimpleList* delThis() { SimpleList* ret = m_next; - Mem::kfree(this); + Mem::free(this); return ret; } @@ -44,7 +44,7 @@ class SimpleList { if (m_next == 0) return; SimpleList* temp = m_next; m_next = m_next->m_next; - Mem::kfree(temp); + Mem::free(temp); } SimpleList* removeOnce(const T& value) { diff --git a/Source/Library/Common/Vector.class.cpp b/Source/Library/Common/Vector.class.cpp index 02ae9be..c546a42 100644 --- a/Source/Library/Common/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 @@ -25,7 +25,7 @@ Vector::Vector(u32int size) { template Vector::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 Vector::Vector(const Vector &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& Vector::operator= (const Vector &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::operator[] (u32int index) const { template void Vector::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::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/Library/Makefile b/Source/Library/Makefile index 028e7a4..a4b9b6a 100644 --- a/Source/Library/Makefile +++ b/Source/Library/Makefile @@ -15,6 +15,7 @@ Objects = Common/WChar.class.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 -- cgit v1.2.3 From 0cca2d68451849b5ea96a3620566fd0b42dde3c0 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 21:56:26 +0200 Subject: More work on syscalls --- Source/Applications/SampleApps/cxxdemo.cpp | 3 +++ Source/Kernel/MemoryManager/Mem.ns.cpp | 5 +++++ Source/Kernel/MemoryManager/Mem.ns.h | 2 ++ Source/Kernel/TaskManager/Thread.class.cpp | 13 ++++++++++++- Source/Kernel/TaskManager/Thread.class.h | 4 ++++ Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp | 15 +++++++++++++++ Source/Kernel/VTManager/VirtualTerminal.proto.cpp | 3 +++ Source/Kernel/VTManager/VirtualTerminal.proto.h | 3 +++ Source/Library/Common/String.class.cpp | 20 ++++++++++++++++++++ Source/Library/Common/String.class.h | 5 ++++- Source/Library/Interface/VirtualTerminal.iface.h | 4 ++++ .../Library/Userland/Binding/VirtualTerminal.class.h | 11 +++++++++++ Source/Library/Userland/Start.cpp | 3 ++- .../Library/Userland/Syscall/RessourceCaller.class.h | 11 +++++++++++ Source/Library/Userland/common.h | 1 + 15 files changed, 100 insertions(+), 3 deletions(-) diff --git a/Source/Applications/SampleApps/cxxdemo.cpp b/Source/Applications/SampleApps/cxxdemo.cpp index 8da475a..01644a8 100644 --- a/Source/Applications/SampleApps/cxxdemo.cpp +++ b/Source/Applications/SampleApps/cxxdemo.cpp @@ -5,12 +5,15 @@ 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/Kernel/MemoryManager/Mem.ns.cpp b/Source/Kernel/MemoryManager/Mem.ns.cpp index c7f07f0..144b9f3 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.cpp +++ b/Source/Kernel/MemoryManager/Mem.ns.cpp @@ -1,5 +1,6 @@ #include #include +#include #include namespace Mem { @@ -50,6 +51,10 @@ 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 0d2b1da..b06ab79 100644 --- a/Source/Kernel/MemoryManager/Mem.ns.h +++ b/Source/Kernel/MemoryManager/Mem.ns.h @@ -11,6 +11,8 @@ namespace Mem { 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/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 315eae2..98fa32d 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -52,6 +52,7 @@ void runThread(Thread* thread, void* data, thread_entry_t entry_point) { } Thread::Thread() : Ressource(TH_IFACE_OBJTYPE) { //Private constructor, does nothing + m_xchgspace = 0; } Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) : Ressource(TH_IFACE_OBJTYPE) { @@ -69,10 +70,13 @@ Thread::Thread(Process* process, thread_entry_t entry_point, void* data) : Resso Thread::~Thread() { Task::unregisterThread(this); Mem::free(m_kernelStack.addr); + m_process->getPagedir()->switchTo(); if (m_userStack.addr != 0) { - m_process->getPagedir()->switchTo(); 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 } @@ -80,6 +84,7 @@ void Thread::setup(Process* process, thread_entry_t entry_point, void* data, boo addCall1(TH_IFACE_SLEEP, (call1)&Thread::sleepSC); addCall1(TH_IFACE_FINISH, (call1)&Thread::finishSC); + m_xchgspace = 0; m_isKernel = isKernel; m_process = process; m_kernelStack.addr = Mem::alloc(STACKSIZE); @@ -181,6 +186,12 @@ 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; diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h index 8a7d45e..42baa86 100644 --- a/Source/Kernel/TaskManager/Thread.class.h +++ b/Source/Kernel/TaskManager/Thread.class.h @@ -22,6 +22,8 @@ class Thread : public Ressource { 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 @@ -49,6 +51,8 @@ class Thread : public Ressource { 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/VTManager/VirtualTerminal-sc.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp index 8948657..e0c6e8d 100644 --- a/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp @@ -5,7 +5,22 @@ u32int VirtualTerminal::writeHexSC(u32int number) { return 0; } +u32int VirtualTerminal::writeSC(u32int wat) { + write(String::unserialize(wat)); + 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::putSC(u32int code) { put(WChar(code)); return 0; } + +u32int VirtualTerminal::readLineSC() { + return readLine().serialize(); +} diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp index b7c7340..dfd8f84 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp @@ -7,7 +7,10 @@ VirtualTerminal::VirtualTerminal() : Ressource(VT_IFACE_OBJTYPE), m_kbdMutex(false), m_kbdbuffMutex(false), m_kbdbuff() { addCall1(VT_IFACE_WRITEHEX, (call1)&VirtualTerminal::writeHexSC); + addCall2(VT_IFACE_WRITEDEC, (call2)&VirtualTerminal::writeDecSC); + addCall1(VT_IFACE_WRITE, (call1)&VirtualTerminal::writeSC); addCall1(VT_IFACE_PUT, (call1)&VirtualTerminal::putSC); + addCall0(VT_IFACE_READLINE, (call0)&VirtualTerminal::readLineSC); } VirtualTerminal::~VirtualTerminal() { diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.h b/Source/Kernel/VTManager/VirtualTerminal.proto.h index b9d0eb8..b0cd224 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.h +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h @@ -21,7 +21,10 @@ class VirtualTerminal : public Ressource { //SYSCALLS : u32int writeHexSC(u32int); + u32int writeDecSC(u32int, u32int); + u32int writeSC(u32int); u32int putSC(u32int); + u32int readLineSC(); public: VirtualTerminal(); diff --git a/Source/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp index d8913d9..c217807 100644 --- a/Source/Library/Common/String.class.cpp +++ b/Source/Library/Common/String.class.cpp @@ -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() { + 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/Library/Common/String.class.h b/Source/Library/Common/String.class.h index 3e50d35..5db9858 100644 --- a/Source/Library/Common/String.class.h +++ b/Source/Library/Common/String.class.h @@ -9,6 +9,9 @@ class String : public BasicString { static String hex(u32int number); static String number(s32int number); + static String unserialize(u32int w); + u32int serialize(); + String(const char* string, u8int encoding = UE_UTF8); String() : BasicString() {} String(const String &other) : BasicString (other) {} @@ -34,7 +37,7 @@ class String : public BasicString { 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/Library/Interface/VirtualTerminal.iface.h b/Source/Library/Interface/VirtualTerminal.iface.h index 661162f..1525b6c 100644 --- a/Source/Library/Interface/VirtualTerminal.iface.h +++ b/Source/Library/Interface/VirtualTerminal.iface.h @@ -4,5 +4,9 @@ #define VT_IFACE_OBJTYPE 0x10 #define VT_IFACE_PUT 0x01 #define VT_IFACE_WRITEHEX 0x02 +#define VT_IFACE_WRITEDEC 0x03 +#define VT_IFACE_WRITE 0x04 + +#define VT_IFACE_READLINE 0x05 #endif diff --git a/Source/Library/Userland/Binding/VirtualTerminal.class.h b/Source/Library/Userland/Binding/VirtualTerminal.class.h index a7bb4c2..67683b8 100644 --- a/Source/Library/Userland/Binding/VirtualTerminal.class.h +++ b/Source/Library/Userland/Binding/VirtualTerminal.class.h @@ -2,6 +2,7 @@ #include +#include #include class VirtualTerminal : public RessourceCaller { @@ -15,6 +16,16 @@ class VirtualTerminal : public RessourceCaller { void writeHex(u32int number) { doCall(VT_IFACE_WRITEHEX, number); } + void writeDec(s64int number) { + doCall(VT_IFACE_WRITEDEC, (number >> 32), number); + } + void write(String s) { + Serialized a = s.serialize(); + doCall(VT_IFACE_WRITE, a); + } + String readLine() { + return String::unserialize(doCall(VT_IFACE_READLINE)); + } void put(WChar c) { doCall(VT_IFACE_PUT, c); diff --git a/Source/Library/Userland/Start.cpp b/Source/Library/Userland/Start.cpp index e185189..639210f 100644 --- a/Source/Library/Userland/Start.cpp +++ b/Source/Library/Userland/Start.cpp @@ -18,7 +18,7 @@ extern "C" void start() { ((void (*)(void))*call)(); } - heap.create(0x40000000, 0x00100000, 0x00003000); //Initially create a 1M heap with 12ko index + heap.create(0x40000000, 0x00100000, 0x00004000); //Initially create a 1M heap with 16ko index u32int r = main(); //Call static destructors @@ -32,4 +32,5 @@ extern "C" void start() { 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.h b/Source/Library/Userland/Syscall/RessourceCaller.class.h index 3ad8900..3602ef0 100644 --- a/Source/Library/Userland/Syscall/RessourceCaller.class.h +++ b/Source/Library/Userland/Syscall/RessourceCaller.class.h @@ -2,6 +2,17 @@ #define DEF_RESSOURCECALLER_CLASS_H #include +#include + +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: diff --git a/Source/Library/Userland/common.h b/Source/Library/Userland/common.h index 3508513..6257841 100644 --- a/Source/Library/Userland/common.h +++ b/Source/Library/Userland/common.h @@ -10,6 +10,7 @@ namespace Mem { void* alloc(u32int); void free(void*); + void* mkXchgSpace(u32int sz); } //Standard implemenations of operator new/delete -- cgit v1.2.3 From 866580161b826443bed3862b8315cefd505de37c Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Tue, 20 Oct 2009 18:10:29 +0200 Subject: We now have call tables for ressources. instead of adding calls to ressource in the constructor. --- Source/Kernel/SyscallManager/Res.ns.cpp | 6 +- Source/Kernel/SyscallManager/Ressource.class.cpp | 68 +++++++--------------- Source/Kernel/SyscallManager/Ressource.class.h | 18 +++--- Source/Kernel/TaskManager/Process.class.cpp | 14 +++-- Source/Kernel/TaskManager/Process.class.h | 9 +-- Source/Kernel/TaskManager/Thread.class.cpp | 15 +++-- Source/Kernel/TaskManager/Thread.class.h | 9 +-- .../Kernel/VTManager/VirtualTerminal-sc.proto.cpp | 30 ++++++++-- Source/Kernel/VTManager/VirtualTerminal.proto.cpp | 20 +++++-- Source/Kernel/VTManager/VirtualTerminal.proto.h | 5 ++ Source/Library/Interface/Process.iface.h | 8 +-- Source/Library/Interface/Thread.iface.h | 6 +- Source/Library/Interface/VirtualTerminal.iface.h | 17 ++++-- Source/Library/Userland/Binding/Process.class.h | 10 ++-- Source/Library/Userland/Binding/Thread.class.h | 8 +-- .../Userland/Binding/VirtualTerminal.class.h | 27 ++++++--- 16 files changed, 153 insertions(+), 117 deletions(-) diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp index 1779a00..7902f2d 100644 --- a/Source/Kernel/SyscallManager/Res.ns.cpp +++ b/Source/Kernel/SyscallManager/Res.ns.cpp @@ -43,9 +43,9 @@ void unregisterRes(u32int id) { 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 - if (a == VT_IFACE_OBJTYPE) return Task::currProcess()->getVirtualTerminal()->resId(); - if (a == PR_IFACE_OBJTYPE) return Task::currProcess()->resId(); - if (a == TH_IFACE_OBJTYPE) return Task::currThread()->resId(); + if (a == VTIF_OBJTYPE) return Task::currProcess()->getVirtualTerminal()->resId(); + if (a == PRIF_OBJTYPE) return Task::currProcess()->resId(); + if (a == THIF_OBJTYPE) return Task::currThread()->resId(); return 0; } else { if (ressource > size or ressources[ressource] == 0) { diff --git a/Source/Kernel/SyscallManager/Ressource.class.cpp b/Source/Kernel/SyscallManager/Ressource.class.cpp index 4e62d79..f2aaccb 100644 --- a/Source/Kernel/SyscallManager/Ressource.class.cpp +++ b/Source/Kernel/SyscallManager/Ressource.class.cpp @@ -1,64 +1,40 @@ #include "Ressource.class.h" #include -Ressource::Ressource(u8int type) { +Ressource::Ressource(u8int type, call_t* callTable) { m_id = Res::registerRes(this); m_type = type; - m_calls = 0; + m_callTables = 0; - addCall0(0, (call0)&Ressource::resType); + addCallTable(callTable); } Ressource::~Ressource() { Res::unregisterRes(m_id); - delete m_calls; + delete m_callTables; } -void Ressource::addCall0(u8int id, call0 c) { - call_t e = {0, id, {c}}; - m_calls = m_calls->cons(e); -} - -void Ressource::addCall1(u8int id, call1 c) { - call_t e = {1, id, {0}}; - e.c1 = c; - m_calls = m_calls->cons(e); -} - -void Ressource::addCall2(u8int id, call2 c) { - call_t e = {2, id, {0}}; - e.c2 = c; - m_calls = m_calls->cons(e); -} - -void Ressource::addCall3(u8int id, call3 c) { - call_t e = {3, id, {0}}; - e.c3 = c; - m_calls = m_calls->cons(e); -} - -void Ressource::addCall4(u8int id, call4 c) { - call_t e = {4, id, {0}}; - e.c4 = c; - m_calls = m_calls->cons(e); -} - -void Ressource::addCall5(u8int id, call5 c) { - call_t e = {5, id, {0}}; - e.c5 = c; - m_calls = m_calls->cons(e); +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) { - for (SimpleList *iter = m_calls; iter != 0; iter = iter->next()) { - call_t &ce = iter->v(); - 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); + if (id == 0) return m_type; + + for (SimpleList *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 index 5f4e6bf..f58276b 100644 --- a/Source/Kernel/SyscallManager/Ressource.class.h +++ b/Source/Kernel/SyscallManager/Ressource.class.h @@ -12,6 +12,13 @@ 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; @@ -32,18 +39,13 @@ class Ressource { u32int m_id; u32int m_type; - SimpleList *m_calls; + SimpleList *m_callTables; protected: - Ressource(u8int type); + Ressource(u8int type, call_t* callTable = 0); ~Ressource(); - void addCall0(u8int id, call0 c); - void addCall1(u8int id, call1 c); - void addCall2(u8int id, call2 c); - void addCall3(u8int id, call3 c); - void addCall4(u8int id, call4 c); - void addCall5(u8int id, call5 c); + void addCallTable(call_t* callTable); public: u32int doCall(u8int id, u32int a, u32int b, u32int c, u32int d, u32int e); diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index aae8fce..7ebac72 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -9,7 +9,14 @@ namespace Mem { extern Heap kheap; } -Process::Process() : Ressource(PR_IFACE_OBJTYPE) { //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) +}; + +Process::Process() : Ressource(PRIF_OBJTYPE, m_callTable) { //Private constructor, does nothing } Process* Process::createKernel(String cmdline, VirtualTerminal *vt) { @@ -54,10 +61,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); +Process::Process(String cmdline, u32int uid) : Ressource(PRIF_OBJTYPE, m_callTable) { m_pid = Task::nextPid(); m_cmdline = cmdline; m_retval = 0; diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h index afdfe20..0013dfb 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -46,6 +46,11 @@ class Process : public Ressource { Vector m_threads; SimpleList *m_fileDescriptors; + + //System calls + static call_t m_callTable[]; + u32int exitSC(); + u32int allocPageSC(u32int); public: static Process* createKernel(String cmdline, VirtualTerminal *vt); //Also creates a Thread for what's curently happening @@ -68,10 +73,6 @@ class Process : public Ressource { VirtualTerminal* getVirtualTerminal(); void setVirtualTerminal(VirtualTerminal* vt); u32int getState() { return m_state; } - - //System calls - u32int exitSC(); - u32int allocPageSC(u32int); u32int freePageSC(u32int); }; diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index 98fa32d..d846630 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -6,6 +6,12 @@ #include +call_t Thread::m_callTable[] = { + CALL1(THIF_SLEEP, &Thread::sleepSC), + CALL1(THIF_FINISH, &Thread::finishSC), + CALL0(0, 0) +}; + void runThread(Thread* thread, void* data, thread_entry_t entry_point) { if (thread->m_isKernel) { asm volatile("sti"); @@ -51,11 +57,11 @@ void runThread(Thread* thread, void* data, thread_entry_t entry_point) { } } -Thread::Thread() : Ressource(TH_IFACE_OBJTYPE) { //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) : Ressource(TH_IFACE_OBJTYPE) { +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 { @@ -63,7 +69,7 @@ Thread::Thread(thread_entry_t entry_point, void* data, bool iskernel) : Ressourc } } -Thread::Thread(Process* process, thread_entry_t entry_point, void* data) : Ressource(TH_IFACE_OBJTYPE) { +Thread::Thread(Process* process, thread_entry_t entry_point, void* data) : Ressource(THIF_OBJTYPE, m_callTable) { setup(process, entry_point, data, false); } @@ -81,9 +87,6 @@ Thread::~Thread() { } void Thread::setup(Process* process, thread_entry_t entry_point, void* data, bool isKernel) { - addCall1(TH_IFACE_SLEEP, (call1)&Thread::sleepSC); - addCall1(TH_IFACE_FINISH, (call1)&Thread::finishSC); - m_xchgspace = 0; m_isKernel = isKernel; m_process = process; diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h index 42baa86..5938e2e 100644 --- a/Source/Kernel/TaskManager/Thread.class.h +++ b/Source/Kernel/TaskManager/Thread.class.h @@ -37,6 +37,11 @@ class Thread : public Ressource { 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: 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); @@ -63,10 +68,6 @@ class Thread : public Ressource { } return false; } - - //Syscalls - u32int sleepSC(u32int msecs); - u32int finishSC(u32int errcode); }; #endif diff --git a/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp index e0c6e8d..0a4e14b 100644 --- a/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal-sc.proto.cpp @@ -5,17 +5,18 @@ u32int VirtualTerminal::writeHexSC(u32int number) { return 0; } -u32int VirtualTerminal::writeSC(u32int wat) { - write(String::unserialize(wat)); - 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; @@ -24,3 +25,22 @@ u32int VirtualTerminal::putSC(u32int code) { 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 dfd8f84..348113d 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp @@ -4,13 +4,21 @@ #include +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) +}; + VirtualTerminal::VirtualTerminal() : - Ressource(VT_IFACE_OBJTYPE), m_kbdMutex(false), m_kbdbuffMutex(false), m_kbdbuff() { - addCall1(VT_IFACE_WRITEHEX, (call1)&VirtualTerminal::writeHexSC); - addCall2(VT_IFACE_WRITEDEC, (call2)&VirtualTerminal::writeDecSC); - addCall1(VT_IFACE_WRITE, (call1)&VirtualTerminal::writeSC); - addCall1(VT_IFACE_PUT, (call1)&VirtualTerminal::putSC); - addCall0(VT_IFACE_READLINE, (call0)&VirtualTerminal::readLineSC); + 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 b0cd224..c81cf1a 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.h +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h @@ -20,11 +20,16 @@ class VirtualTerminal : public Ressource { Vector 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: VirtualTerminal(); diff --git a/Source/Library/Interface/Process.iface.h b/Source/Library/Interface/Process.iface.h index 0956679..fe70833 100644 --- a/Source/Library/Interface/Process.iface.h +++ b/Source/Library/Interface/Process.iface.h @@ -1,9 +1,9 @@ #ifndef DEF_PROCESS_IFACE_H #define DEF_PROCESS_IFACE_H -#define PR_IFACE_OBJTYPE 0x20 -#define PR_IFACE_EXIT 0x01 -#define PR_IFACE_ALLOCPAGE 0x02 -#define PR_IFACE_FREEPAGE 0x03 +#define PRIF_OBJTYPE 0x20 +#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 index 2a64924..ac572b4 100644 --- a/Source/Library/Interface/Thread.iface.h +++ b/Source/Library/Interface/Thread.iface.h @@ -1,8 +1,8 @@ #ifndef DEF_THREAD_IFACE_H #define DEF_THREAD_IFACE_H -#define TH_IFACE_OBJTYPE 0x21 -#define TH_IFACE_SLEEP 0x01 -#define TH_IFACE_FINISH 0x02 +#define THIF_OBJTYPE 0x21 +#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 index 1525b6c..528e9e5 100644 --- a/Source/Library/Interface/VirtualTerminal.iface.h +++ b/Source/Library/Interface/VirtualTerminal.iface.h @@ -1,12 +1,17 @@ #ifndef DEF_VITRUALTERMINAL_IFACE_H #define DEF_VITRUALTERMINAL_IFACE_H -#define VT_IFACE_OBJTYPE 0x10 -#define VT_IFACE_PUT 0x01 -#define VT_IFACE_WRITEHEX 0x02 -#define VT_IFACE_WRITEDEC 0x03 -#define VT_IFACE_WRITE 0x04 +#define VTIF_OBJTYPE 0x10 +#define VTIF_PUT 0x01 +#define VTIF_WRITEHEX 0x02 +#define VTIF_WRITEDEC 0x03 +#define VTIF_WRITE 0x04 -#define VT_IFACE_READLINE 0x05 +#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/Userland/Binding/Process.class.h b/Source/Library/Userland/Binding/Process.class.h index 88af9d6..e532ad3 100644 --- a/Source/Library/Userland/Binding/Process.class.h +++ b/Source/Library/Userland/Binding/Process.class.h @@ -5,18 +5,18 @@ class Process : public RessourceCaller { public: static Process get() { - u32int id = RessourceCaller::getObjId(PR_IFACE_OBJTYPE); + u32int id = RessourceCaller::getObjId(PRIF_OBJTYPE); return Process(id); } - Process(u32int id) : RessourceCaller(id, PR_IFACE_OBJTYPE) {} + Process(u32int id) : RessourceCaller(id, PRIF_OBJTYPE) {} void exit() { - doCall(PR_IFACE_EXIT); + doCall(PRIF_EXIT); } void allocPage(u32int pos) { - doCall(PR_IFACE_ALLOCPAGE, pos); + doCall(PRIF_ALLOCPAGE, pos); } void freePage(u32int pos) { - doCall(PR_IFACE_FREEPAGE, pos); + doCall(PRIF_FREEPAGE, pos); } }; diff --git a/Source/Library/Userland/Binding/Thread.class.h b/Source/Library/Userland/Binding/Thread.class.h index beef9c5..1a354d3 100644 --- a/Source/Library/Userland/Binding/Thread.class.h +++ b/Source/Library/Userland/Binding/Thread.class.h @@ -5,15 +5,15 @@ class Thread : public RessourceCaller { public: static Thread get() { - u32int id = RessourceCaller::getObjId(TH_IFACE_OBJTYPE); + u32int id = RessourceCaller::getObjId(THIF_OBJTYPE); return Thread(id); } - Thread(u32int id) : RessourceCaller(id, TH_IFACE_OBJTYPE) {} + Thread(u32int id) : RessourceCaller(id, THIF_OBJTYPE) {} void sleep(u32int msecs) { - doCall(TH_IFACE_SLEEP, msecs); + doCall(THIF_SLEEP, msecs); } void finish(u32int errcode) { - doCall(TH_IFACE_FINISH, errcode); + doCall(THIF_FINISH, errcode); } }; diff --git a/Source/Library/Userland/Binding/VirtualTerminal.class.h b/Source/Library/Userland/Binding/VirtualTerminal.class.h index 67683b8..4329c86 100644 --- a/Source/Library/Userland/Binding/VirtualTerminal.class.h +++ b/Source/Library/Userland/Binding/VirtualTerminal.class.h @@ -8,26 +8,37 @@ class VirtualTerminal : public RessourceCaller { public: static VirtualTerminal get() { - u32int id = RessourceCaller::getObjId(VT_IFACE_OBJTYPE); + u32int id = RessourceCaller::getObjId(VTIF_OBJTYPE); return VirtualTerminal(id); } - VirtualTerminal(u32int id) : RessourceCaller(id, VT_IFACE_OBJTYPE) {} + VirtualTerminal(u32int id) : RessourceCaller(id, VTIF_OBJTYPE) {} void writeHex(u32int number) { - doCall(VT_IFACE_WRITEHEX, number); + doCall(VTIF_WRITEHEX, number); } void writeDec(s64int number) { - doCall(VT_IFACE_WRITEDEC, (number >> 32), number); + doCall(VTIF_WRITEDEC, (number >> 32), number); } void write(String s) { - Serialized a = s.serialize(); - doCall(VT_IFACE_WRITE, a); + doCall(VTIF_WRITE, (u32int)&s); } String readLine() { - return String::unserialize(doCall(VT_IFACE_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(VT_IFACE_PUT, c); + doCall(VTIF_PUT, c); } }; -- cgit v1.2.3 From 90b49b6f171108f272ff529f7546bd9625ca7d17 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Tue, 20 Oct 2009 18:30:50 +0200 Subject: Implemented static syscalls, specific to a class and not an object. --- Source/Kernel/SyscallManager/Res.ns.cpp | 20 +++++++++++++++++--- Source/Kernel/TaskManager/Process.class.cpp | 5 +++++ Source/Kernel/TaskManager/Process.class.h | 2 ++ Source/Kernel/TaskManager/Thread.class.cpp | 5 +++++ Source/Kernel/TaskManager/Thread.class.h | 2 ++ Source/Kernel/VTManager/VirtualTerminal.proto.cpp | 6 ++++++ Source/Kernel/VTManager/VirtualTerminal.proto.h | 2 ++ Source/Library/Interface/Process.iface.h | 4 ++++ Source/Library/Interface/Thread.iface.h | 4 ++++ Source/Library/Interface/VirtualTerminal.iface.h | 4 ++++ Source/Library/Userland/Binding/Process.class.h | 2 +- Source/Library/Userland/Binding/Thread.class.h | 2 +- .../Library/Userland/Binding/VirtualTerminal.class.h | 2 +- .../Userland/Syscall/RessourceCaller.class.cpp | 4 ++-- .../Library/Userland/Syscall/RessourceCaller.class.h | 5 ++++- 15 files changed, 60 insertions(+), 9 deletions(-) diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp index 7902f2d..98d3ac3 100644 --- a/Source/Kernel/SyscallManager/Res.ns.cpp +++ b/Source/Kernel/SyscallManager/Res.ns.cpp @@ -7,6 +7,20 @@ 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}, + {0, 0} +}; + Ressource** ressources = 0; u32int size = 0; @@ -43,9 +57,9 @@ void unregisterRes(u32int id) { 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 - if (a == VTIF_OBJTYPE) return Task::currProcess()->getVirtualTerminal()->resId(); - if (a == PRIF_OBJTYPE) return Task::currProcess()->resId(); - if (a == THIF_OBJTYPE) return Task::currThread()->resId(); + 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) { diff --git a/Source/Kernel/TaskManager/Process.class.cpp b/Source/Kernel/TaskManager/Process.class.cpp index 7ebac72..a2bbfb4 100644 --- a/Source/Kernel/TaskManager/Process.class.cpp +++ b/Source/Kernel/TaskManager/Process.class.cpp @@ -16,6 +16,11 @@ call_t Process::m_callTable[] = { 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 } diff --git a/Source/Kernel/TaskManager/Process.class.h b/Source/Kernel/TaskManager/Process.class.h index 0013dfb..89efd0c 100644 --- a/Source/Kernel/TaskManager/Process.class.h +++ b/Source/Kernel/TaskManager/Process.class.h @@ -53,6 +53,8 @@ class Process : public Ressource { 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); diff --git a/Source/Kernel/TaskManager/Thread.class.cpp b/Source/Kernel/TaskManager/Thread.class.cpp index d846630..21ef954 100644 --- a/Source/Kernel/TaskManager/Thread.class.cpp +++ b/Source/Kernel/TaskManager/Thread.class.cpp @@ -12,6 +12,11 @@ call_t Thread::m_callTable[] = { 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) { if (thread->m_isKernel) { asm volatile("sti"); diff --git a/Source/Kernel/TaskManager/Thread.class.h b/Source/Kernel/TaskManager/Thread.class.h index 5938e2e..35a9fd6 100644 --- a/Source/Kernel/TaskManager/Thread.class.h +++ b/Source/Kernel/TaskManager/Thread.class.h @@ -43,6 +43,8 @@ class Thread : public Ressource { 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(); diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp index 348113d..9b0b862 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.cpp +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.cpp @@ -1,6 +1,7 @@ #include "VirtualTerminal.proto.h" #include #include +#include #include @@ -17,6 +18,11 @@ call_t VirtualTerminal::m_callTable[] = { 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() { } diff --git a/Source/Kernel/VTManager/VirtualTerminal.proto.h b/Source/Kernel/VTManager/VirtualTerminal.proto.h index c81cf1a..936e4d4 100644 --- a/Source/Kernel/VTManager/VirtualTerminal.proto.h +++ b/Source/Kernel/VTManager/VirtualTerminal.proto.h @@ -32,6 +32,8 @@ class VirtualTerminal : public Ressource { u32int isBoxedSC(); public: + static u32int scall(u8int, u32int, u32int, u32int, u32int); + VirtualTerminal(); virtual ~VirtualTerminal(); diff --git a/Source/Library/Interface/Process.iface.h b/Source/Library/Interface/Process.iface.h index fe70833..2126dc6 100644 --- a/Source/Library/Interface/Process.iface.h +++ b/Source/Library/Interface/Process.iface.h @@ -2,6 +2,10 @@ #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 diff --git a/Source/Library/Interface/Thread.iface.h b/Source/Library/Interface/Thread.iface.h index ac572b4..0dac2e1 100644 --- a/Source/Library/Interface/Thread.iface.h +++ b/Source/Library/Interface/Thread.iface.h @@ -2,6 +2,10 @@ #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 diff --git a/Source/Library/Interface/VirtualTerminal.iface.h b/Source/Library/Interface/VirtualTerminal.iface.h index 528e9e5..412cf8f 100644 --- a/Source/Library/Interface/VirtualTerminal.iface.h +++ b/Source/Library/Interface/VirtualTerminal.iface.h @@ -2,6 +2,10 @@ #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 diff --git a/Source/Library/Userland/Binding/Process.class.h b/Source/Library/Userland/Binding/Process.class.h index e532ad3..00afe27 100644 --- a/Source/Library/Userland/Binding/Process.class.h +++ b/Source/Library/Userland/Binding/Process.class.h @@ -5,7 +5,7 @@ class Process : public RessourceCaller { public: static Process get() { - u32int id = RessourceCaller::getObjId(PRIF_OBJTYPE); + u32int id = RessourceCaller::sCall(PRIF_OBJTYPE, PRIF_SGETCPR); return Process(id); } Process(u32int id) : RessourceCaller(id, PRIF_OBJTYPE) {} diff --git a/Source/Library/Userland/Binding/Thread.class.h b/Source/Library/Userland/Binding/Thread.class.h index 1a354d3..a19c256 100644 --- a/Source/Library/Userland/Binding/Thread.class.h +++ b/Source/Library/Userland/Binding/Thread.class.h @@ -5,7 +5,7 @@ class Thread : public RessourceCaller { public: static Thread get() { - u32int id = RessourceCaller::getObjId(THIF_OBJTYPE); + u32int id = RessourceCaller::sCall(THIF_OBJTYPE, THIF_SGETCTH); return Thread(id); } Thread(u32int id) : RessourceCaller(id, THIF_OBJTYPE) {} diff --git a/Source/Library/Userland/Binding/VirtualTerminal.class.h b/Source/Library/Userland/Binding/VirtualTerminal.class.h index 4329c86..0da1be4 100644 --- a/Source/Library/Userland/Binding/VirtualTerminal.class.h +++ b/Source/Library/Userland/Binding/VirtualTerminal.class.h @@ -8,7 +8,7 @@ class VirtualTerminal : public RessourceCaller { public: static VirtualTerminal get() { - u32int id = RessourceCaller::getObjId(VTIF_OBJTYPE); + u32int id = RessourceCaller::sCall(VTIF_OBJTYPE, VTIF_SGETPRVT); return VirtualTerminal(id); } VirtualTerminal(u32int id) : RessourceCaller(id, VTIF_OBJTYPE) {} diff --git a/Source/Library/Userland/Syscall/RessourceCaller.class.cpp b/Source/Library/Userland/Syscall/RessourceCaller.class.cpp index 2d7b6ba..f3b61a8 100644 --- a/Source/Library/Userland/Syscall/RessourceCaller.class.cpp +++ b/Source/Library/Userland/Syscall/RessourceCaller.class.cpp @@ -7,8 +7,8 @@ RessourceCaller::RessourceCaller(u32int id, u32int type) { if (m_type != type) m_type = 0; } -u32int RessourceCaller::getObjId(u32int type) { - return syscall(0xFFFFFE00, type); +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) { diff --git a/Source/Library/Userland/Syscall/RessourceCaller.class.h b/Source/Library/Userland/Syscall/RessourceCaller.class.h index 3602ef0..85beacf 100644 --- a/Source/Library/Userland/Syscall/RessourceCaller.class.h +++ b/Source/Library/Userland/Syscall/RessourceCaller.class.h @@ -21,7 +21,10 @@ class RessourceCaller { protected: RessourceCaller(u32int id, u32int type); - static u32int getObjId(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: -- cgit v1.2.3 From 9836acd720988af30250c2c1ec18d618664dea4e Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Tue, 20 Oct 2009 19:21:34 +0200 Subject: Started working on a userland shell This means I'll have to do syscalls for everything I need. --- Makefile | 3 +- Source/Applications/Shell/Makefile | 31 ++++++++++++++++++++ Source/Applications/Shell/main.cpp | 13 +++++++++ Source/Kernel/Makefile | 1 + Source/Kernel/SyscallManager/Res.ns.cpp | 2 ++ Source/Kernel/VFS/FSNode-sc.proto.cpp | 34 ++++++++++++++++++++++ Source/Kernel/VFS/FSNode.proto.h | 16 ++++++++-- Source/Library/Common/String.class.cpp | 2 +- Source/Library/Common/String.class.h | 2 +- Source/Library/Interface/FSNode.iface.h | 14 +++++++++ Source/Library/Userland/Binding/FSNode.class.h | 23 +++++++++++++++ .../Userland/Binding/VirtualTerminal.class.h | 6 +++- 12 files changed, 141 insertions(+), 6 deletions(-) create mode 100644 Source/Applications/Shell/Makefile create mode 100644 Source/Applications/Shell/main.cpp create mode 100644 Source/Kernel/VFS/FSNode-sc.proto.cpp create mode 100644 Source/Library/Interface/FSNode.iface.h create mode 100644 Source/Library/Userland/Binding/FSNode.class.h diff --git a/Makefile b/Makefile index 9bb7f84..1237ef8 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ .PHONY: clean, mrproper, Init.rfs -Projects = Kernel Library Tools/MakeRamFS Applications/SampleApps +Projects = Kernel Library Tools/MakeRamFS Applications/Shell Applications/SampleApps Kernel = Source/Kernel/Melon.ke RamFS = Init.rfs @@ -9,6 +9,7 @@ RamFSFiles = :/System :/System/Applications :/System/Configuration :/System/Keym 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 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 +#include +#include + +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/Makefile b/Source/Kernel/Makefile index 1c83e5a..55c5fb0 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -55,6 +55,7 @@ Objects = Core/loader.wtf.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 \ diff --git a/Source/Kernel/SyscallManager/Res.ns.cpp b/Source/Kernel/SyscallManager/Res.ns.cpp index 98d3ac3..048d17a 100644 --- a/Source/Kernel/SyscallManager/Res.ns.cpp +++ b/Source/Kernel/SyscallManager/Res.ns.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include namespace Res { @@ -18,6 +19,7 @@ static_call_t staticCalls[] = { {VTIF_OBJTYPE, VirtualTerminal::scall}, {PRIF_OBJTYPE, Process::scall}, {THIF_OBJTYPE, Thread::scall}, + {FNIF_OBJTYPE, FSNode::scall}, {0, 0} }; 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 + +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 c3cd1c1..b648141 100644 --- a/Source/Kernel/VFS/FSNode.proto.h +++ b/Source/Kernel/VFS/FSNode.proto.h @@ -5,6 +5,9 @@ #include class FSNode; #include +#include + +#include 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/Library/Common/String.class.cpp b/Source/Library/Common/String.class.cpp index c217807..ac0eba0 100644 --- a/Source/Library/Common/String.class.cpp +++ b/Source/Library/Common/String.class.cpp @@ -60,7 +60,7 @@ String String::unserialize(u32int w) { return ret; } -u32int String::serialize() { +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++) { diff --git a/Source/Library/Common/String.class.h b/Source/Library/Common/String.class.h index 5db9858..0d48ce6 100644 --- a/Source/Library/Common/String.class.h +++ b/Source/Library/Common/String.class.h @@ -10,7 +10,7 @@ class String : public BasicString { static String number(s32int number); static String unserialize(u32int w); - u32int serialize(); + u32int serialize() const; String(const char* string, u8int encoding = UE_UTF8); String() : BasicString() {} 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/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 +#include + +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/VirtualTerminal.class.h b/Source/Library/Userland/Binding/VirtualTerminal.class.h index 0da1be4..9d438c6 100644 --- a/Source/Library/Userland/Binding/VirtualTerminal.class.h +++ b/Source/Library/Userland/Binding/VirtualTerminal.class.h @@ -37,8 +37,12 @@ class VirtualTerminal : public RessourceCaller { 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; } }; -- cgit v1.2.3