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