From bc2eccdd11c27029096fb3e891073503eb269e27 Mon Sep 17 00:00:00 2001 From: Alexis211 Date: Sun, 18 Oct 2009 12:35:07 +0200 Subject: We can now load ELF binaries !!! --- Makefile | 4 +- Source/Applications/ASMApps/Makefile | 20 ------- Source/Applications/ASMApps/syscalls.asm | 18 ------- Source/Applications/ASMApps/test | Bin 92 -> 0 bytes Source/Applications/ASMApps/test.asm | 30 ----------- Source/Applications/SampleApps/Makefile | 29 ++++++++++ Source/Applications/SampleApps/asmdemo | Bin 0 -> 4725 bytes Source/Applications/SampleApps/asmdemo.asm | 30 +++++++++++ Source/Applications/SampleApps/lib-melonasm.asm | 24 +++++++++ Source/Kernel/Linker/Binary.proto.cpp | 4 +- Source/Kernel/Linker/ElfBinary.class.cpp | 55 +++++++++++++++++++ Source/Kernel/Linker/ElfBinary.class.h | 68 ++++++++++++++++++++++++ Source/Kernel/Makefile | 1 + Source/Kernel/Shell/KernelShell.class.cpp | 1 + 14 files changed, 213 insertions(+), 71 deletions(-) delete mode 100644 Source/Applications/ASMApps/Makefile delete mode 100644 Source/Applications/ASMApps/syscalls.asm delete mode 100644 Source/Applications/ASMApps/test delete mode 100644 Source/Applications/ASMApps/test.asm create mode 100644 Source/Applications/SampleApps/Makefile create mode 100755 Source/Applications/SampleApps/asmdemo create mode 100644 Source/Applications/SampleApps/asmdemo.asm create mode 100644 Source/Applications/SampleApps/lib-melonasm.asm create mode 100644 Source/Kernel/Linker/ElfBinary.class.cpp create mode 100644 Source/Kernel/Linker/ElfBinary.class.h diff --git a/Makefile b/Makefile index 508aa76..324deb7 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,13 @@ .PHONY: clean, mrproper, Init.rfs -Projects = Kernel Tools/MakeRamFS Applications/ASMApps +Projects = Kernel Tools/MakeRamFS Applications/SampleApps Kernel = Source/Kernel/Melon.ke RamFS = Init.rfs RamFSFiles = :/System :/System/Applications :/System/Configuration :/System/Keymaps \ Source/Kernel/Ressources/Keymaps/fr.mkm:/System/Keymaps/fr.mkm \ Source/Kernel/Ressources/Texts/Welcome.txt:/Welcome.txt \ - Source/Applications/ASMApps/test:/System/Applications/Test \ + Source/Applications/SampleApps/asmdemo:/ASMDemo.app \ :/Useless \ Source/Kernel/Ressources/Texts/Info.txt:/Useless/Info.txt \ Source/Kernel/Ressources/Graphics/logo.text.cxd:/Useless/Melon-logo diff --git a/Source/Applications/ASMApps/Makefile b/Source/Applications/ASMApps/Makefile deleted file mode 100644 index 8cc8bfd..0000000 --- a/Source/Applications/ASMApps/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -.PHONY: clean, mrproper - -ASM = nasm - -Applications = test - -all: $(Applications) - echo "* Done with ASM applications : $(Applications)" - -rebuild: mrproper all - -%: %.asm - echo "* Compiling $<..." - $(ASM) -o $@ $< - -clean: - echo "* Removing files..." - rm -rf $(Applications) - -mrproper: clean diff --git a/Source/Applications/ASMApps/syscalls.asm b/Source/Applications/ASMApps/syscalls.asm deleted file mode 100644 index 1a634d7..0000000 --- a/Source/Applications/ASMApps/syscalls.asm +++ /dev/null @@ -1,18 +0,0 @@ -[bits 32] - -%ifidn __OUTPUT_FORMAT__, bin - -%define MEM_ORIGIN 0x10000000 - -dd 0xFEEDBEEF ; magic number ^^ -dd end - start -dd MEM_ORIGIN - -; the ($-$$) permits not taking into account the header above -[org MEM_ORIGIN - ($-$$)] - -%endif - -%define SC_PUTCH 0xFFFFFF01 -%define SC_SLEEP 0xFFFFFF02 -%define SC_WHEX 0xFFFFFF03 diff --git a/Source/Applications/ASMApps/test b/Source/Applications/ASMApps/test deleted file mode 100644 index 781a4b6..0000000 Binary files a/Source/Applications/ASMApps/test and /dev/null differ diff --git a/Source/Applications/ASMApps/test.asm b/Source/Applications/ASMApps/test.asm deleted file mode 100644 index a79d4a3..0000000 --- a/Source/Applications/ASMApps/test.asm +++ /dev/null @@ -1,30 +0,0 @@ -%include "syscalls.asm" - -start: ; label used for calculating app size - mov ecx, [data] - mov ebx, ecx - mov eax, SC_WHEX - int 64 - mov eax, SC_PUTCH - mov ebx, 10 - int 64 - loop: - inc ecx - mov eax, SC_PUTCH ;temporarily defined for writing one char to screen - mov ebx, ecx - int 64 - mov eax, SC_SLEEP ;temporary syscall for sleeping - mov ebx, 30 ;20ms - int 64 - cmp ecx, 127 - jnz loop - mov eax, 0 - mov eax, SC_PUTCH - mov ebx, 10 ;newline - int 64 - int 66 ;finish task - -data: -dd 0x00000020 - -end: ; label used for calculating app size diff --git a/Source/Applications/SampleApps/Makefile b/Source/Applications/SampleApps/Makefile new file mode 100644 index 0000000..28dad49 --- /dev/null +++ b/Source/Applications/SampleApps/Makefile @@ -0,0 +1,29 @@ +.PHONY: clean, mrproper + +ASM = nasm +ASMFLAGS = -f elf +LD = ld +LDFLAGS = --entry=start -Ttext=40000000 + +Applications = asmdemo + +all: $(Applications) + echo "* Done with applications : $(Applications)" + +rebuild: mrproper all + +%: %.o + echo "* Linking $<..." + $(LD) $(LDFLAGS) $< -o $@ + +%.o: %.asm + echo "* Compiling $<..." + $(ASM) $(ASMFLAGS) -o $@ $< + +clean: + echo "* Removing object files..." + rm -rf *.o + +mrproper: clean + echo "* Removing applications..." + rm -rf $(Applications) diff --git a/Source/Applications/SampleApps/asmdemo b/Source/Applications/SampleApps/asmdemo new file mode 100755 index 0000000..9e6822d Binary files /dev/null and b/Source/Applications/SampleApps/asmdemo differ diff --git a/Source/Applications/SampleApps/asmdemo.asm b/Source/Applications/SampleApps/asmdemo.asm new file mode 100644 index 0000000..3037897 --- /dev/null +++ b/Source/Applications/SampleApps/asmdemo.asm @@ -0,0 +1,30 @@ +%include "lib-melonasm.asm" + +start: ; label used for calculating app size + mov ecx, [data] + mov ebx, ecx + mov eax, SC_WHEX + int 64 + mov eax, SC_PUTCH + mov ebx, 10 + int 64 + loop: + inc ecx + mov eax, SC_PUTCH ;temporarily defined for writing one char to screen + mov ebx, ecx + int 64 + mov eax, SC_SLEEP ;temporary syscall for sleeping + mov ebx, 30 ;20ms + int 64 + cmp ecx, 127 + jnz loop + mov eax, 0 + mov eax, SC_PUTCH + mov ebx, 10 ;newline + int 64 + int 66 ;finish task + +data: +dd 0x00000020 + +end: ; label used for calculating app size diff --git a/Source/Applications/SampleApps/lib-melonasm.asm b/Source/Applications/SampleApps/lib-melonasm.asm new file mode 100644 index 0000000..0845770 --- /dev/null +++ b/Source/Applications/SampleApps/lib-melonasm.asm @@ -0,0 +1,24 @@ +[bits 32] + +%ifidn __OUTPUT_FORMAT__, bin +; create a MelonBinary output + +%define MEM_ORIGIN 0x10000000 + +dd 0xFEEDBEEF ; magic number ^^ +dd end - start +dd MEM_ORIGIN + +; the ($-$$) permits not taking into account the header above +[org MEM_ORIGIN - ($-$$)] + +%elifidn __OUTPUT_FORMAT__, elf +; create an elf object + +[global start] + +%endif + +%define SC_PUTCH 0xFFFFFF01 +%define SC_SLEEP 0xFFFFFF02 +%define SC_WHEX 0xFFFFFF03 diff --git a/Source/Kernel/Linker/Binary.proto.cpp b/Source/Kernel/Linker/Binary.proto.cpp index 6053f22..c0345da 100644 --- a/Source/Kernel/Linker/Binary.proto.cpp +++ b/Source/Kernel/Linker/Binary.proto.cpp @@ -1,16 +1,18 @@ #include "Binary.proto.h" #include +#include Binary* (*loaders[])(File& file) = { &MelonBinary::load, - + &ElfBinary::load, 0 }; Binary* Binary::load(File& file) { Binary* r = 0; u32int i = 0; while (loaders[i] != 0) { + file.seek(0, SM_BEGINNING); r = loaders[i](file); //Call loader if (r != 0) break; i++; diff --git a/Source/Kernel/Linker/ElfBinary.class.cpp b/Source/Kernel/Linker/ElfBinary.class.cpp new file mode 100644 index 0000000..450053f --- /dev/null +++ b/Source/Kernel/Linker/ElfBinary.class.cpp @@ -0,0 +1,55 @@ +#include "ElfBinary.class.h" +#include + +ElfBinary::~ElfBinary() { + for (SimpleList *iter = m_phdr; iter != 0; iter = iter->next()) { + delete iter->v().data; + } +} + +Binary* ElfBinary::load(File& file) { + elf_ehdr_t hdr; + file.read (&hdr); + //Verify we have an elf file + if (hdr.e_ident[0] != 0x7F or hdr.e_ident[1] != 'E' or hdr.e_ident[2] != 'L' or hdr.e_ident[3] != 'F') return 0; + + //Store elf header into a new ElfBinary + ElfBinary* b = new ElfBinary(); + memcpy((u8int*)&b->m_ehdr, (const u8int*) &hdr, sizeof(elf_ehdr_t)); + b->m_phdr = 0; + + //Load program headers + file.seek(hdr.e_phoff, SM_BEGINNING); + for (u32int i = 0; i < hdr.e_phnum; i++) { + b->m_phdr = b->m_phdr->cons(phdr_t()); + file.read(&b->m_phdr->v().h); //Load current entry from file + } + //Load data + for (SimpleList *iter = b->m_phdr; iter != 0; iter = iter->next()) { + iter->v().data = (u8int*)Mem::kalloc(iter->v().h.p_filesz); + file.seek(iter->v().h.p_offset, SM_BEGINNING); + file.read(iter->v().h.p_filesz, iter->v().data); + } + + return b; +} + +thread_entry_t ElfBinary::toProcess(Process* p) { + for (SimpleList *iter = m_phdr; iter != 0; iter = iter->next()) { + phdr_t &e = iter->v(); + if (e.h.p_type == PT_LOAD) { + for (u32int i = e.h.p_vaddr; i < e.h.p_vaddr + e.h.p_memsz; i += 0x1000) { + p->getPagedir()->allocFrame(i, true, true); + } + p->getPagedir()->switchTo(); + memcpy((u8int*)e.h.p_vaddr, (const u8int*)e.data, e.h.p_filesz); + if (e.h.p_memsz > e.h.p_filesz) { //set to zero all the remaining space + u8int* x = (u8int*)e.h.p_vaddr; + for (u32int i = e.h.p_vaddr + e.h.p_filesz; i < e.h.p_filesz; i++) { + x[i] = 0; + } + } + } + } + return (thread_entry_t)m_ehdr.e_entry; +} diff --git a/Source/Kernel/Linker/ElfBinary.class.h b/Source/Kernel/Linker/ElfBinary.class.h new file mode 100644 index 0000000..311e2e6 --- /dev/null +++ b/Source/Kernel/Linker/ElfBinary.class.h @@ -0,0 +1,68 @@ +#ifndef DEF_ELFBINARY_CLASS_H +#define DEF_ELFBINARY_CLASS_H + +#include +#include + +/* p_type */ +#define PT_NULL 0 +#define PT_LOAD 1 +#define PT_DYNAMIC 2 +#define PT_INTERP 3 +#define PT_NOTE 4 +#define PT_SHLIB 5 +#define PT_PHDR 6 +#define PT_LOPROC 0x70000000 +#define PT_HIPROC 0x7fffffff + +struct elf_ehdr_t { + u8int e_ident[16]; /* ELF identification */ + u16int e_type; /* 2 (exec file) */ + u16int e_machine; /* 3 (intel architecture) */ + u32int e_version; /* 1 */ + u32int e_entry; /* starting point */ + u32int e_phoff; /* program header table offset */ + u32int e_shoff; /* section header table offset */ + u32int e_flags; /* various flags */ + u16int e_ehsize; /* ELF header (this) size */ + + u16int e_phentsize; /* program header table entry size */ + u16int e_phnum; /* number of entries */ + + u16int e_shentsize; /* section header table entry size */ + u16int e_shnum; /* number of entries */ + + u16int e_shstrndx; /* index of the section name string table */ +}; + +struct elf_phdr_t { + u32int p_type; /* type of segment */ + u32int p_offset; + u32int p_vaddr; + u32int p_paddr; + u32int p_filesz; + u32int p_memsz; + u32int p_flags; + u32int p_align; +}; + +struct phdr_t { + elf_phdr_t h; + u8int* data; +}; + +class ElfBinary : public Binary { + private: + elf_ehdr_t m_ehdr; + SimpleList *m_phdr; + + ElfBinary() {} + + public: + virtual ~ElfBinary(); + static Binary* load(File& file); + + thread_entry_t toProcess(Process* p); +}; + +#endif diff --git a/Source/Kernel/Makefile b/Source/Kernel/Makefile index 521e32a..af1f9db 100644 --- a/Source/Kernel/Makefile +++ b/Source/Kernel/Makefile @@ -45,6 +45,7 @@ Objects = Core/loader.wtf.o \ Shell/KernelShell-sys.class.o \ Linker/Binary.proto.o \ Linker/MelonBinary.class.o \ + Linker/ElfBinary.class.o \ Library/Bitset.class.o \ Library/String.class.o \ Library/ByteArray.class.o \ diff --git a/Source/Kernel/Shell/KernelShell.class.cpp b/Source/Kernel/Shell/KernelShell.class.cpp index ac89b68..cb6246d 100644 --- a/Source/Kernel/Shell/KernelShell.class.cpp +++ b/Source/Kernel/Shell/KernelShell.class.cpp @@ -20,6 +20,7 @@ u32int shellRun(void* ks) { void KernelShell::setup(DirectoryNode* cwd, VirtualTerminal *vt) { m_vt = vt; + Task::currProcess()->setVirtualTerminal(vt); ((ScrollableVT*)m_vt)->map(9); Kbd::setFocus(m_vt); m_cwd = cwd; -- cgit v1.2.3