From 5c86cb4abd19471e15dd3c612f5dc50ec54b2bd4 Mon Sep 17 00:00:00 2001 From: Jonas 'Sortie' Termansen Date: Sat, 27 Aug 2011 16:46:00 +0200 Subject: [PATCH] Processes now remember the memory segments it has loaded. --- sortix/Makefile | 2 +- sortix/elf.cpp | 38 +++++++++++++++------ sortix/elf.h | 4 ++- sortix/kernel.cpp | 2 +- sortix/process.cpp | 78 ++++++++++++++++++++++++++++++++++++++++++++ sortix/process.h | 54 +++++++++++++++++------------- sortix/scheduler.cpp | 11 ------- sortix/scheduler.h | 26 +-------------- 8 files changed, 144 insertions(+), 71 deletions(-) create mode 100644 sortix/process.cpp diff --git a/sortix/Makefile b/sortix/Makefile index 64c498bd..8a472b1d 100644 --- a/sortix/Makefile +++ b/sortix/Makefile @@ -44,7 +44,7 @@ DEFINES:=$(DEFINES) -DINITRD CPPFLAGSRELEASE=-s -O3 CPPFLAGSDEBUG= CPPFLAGS=-I.. -I. $(CPUDEFINES) $(CPUFLAGS) -std=gnu++0x -Wall -Wextra -nostdlib -fno-builtin -nostartfiles -nodefaultlibs -fno-exceptions -fno-rtti -fno-stack-protector $(DEFINES) $(CPPFLAGSRELEASE) -OBJS=$(CPUOBJS) kernel.o descriptor_tables.o isr.o time.o log.o iprintable.o panic.o keyboard.o memorymanagement.o scheduler.o syscall.o application.o pong.o sound.o pci.o uart.o conway.o test.o http.o vgaterminal.o serialterminal.o descriptors.o device.o vga.o elf.o ../libmaxsi/libmaxsi-sortix.a +OBJS=$(CPUOBJS) kernel.o descriptor_tables.o isr.o time.o log.o iprintable.o panic.o keyboard.o memorymanagement.o scheduler.o syscall.o application.o pong.o sound.o pci.o uart.o conway.o test.o http.o vgaterminal.o serialterminal.o descriptors.o device.o vga.o elf.o process.o ../libmaxsi/libmaxsi-sortix.a JSOBJS:=$(subst .o,-js.o,$(OBJS)) all: sortix.bin diff --git a/sortix/elf.cpp b/sortix/elf.cpp index 2ddd2a86..4085b8ba 100644 --- a/sortix/elf.cpp +++ b/sortix/elf.cpp @@ -27,6 +27,7 @@ #include "elf.h" #include "memorymanagement.h" #include "panic.h" +#include "process.h" using namespace Maxsi; @@ -34,7 +35,7 @@ namespace Sortix { namespace ELF { - addr_t Construct32(const void* file, size_t filelen) + addr_t Construct32(Process* process, const void* file, size_t filelen) { if ( filelen < sizeof(Header32) ) { return 0; } const Header32* header = (const Header32*) file; @@ -55,7 +56,10 @@ namespace Sortix // Validate that all program headers are present. uint16_t numprogheaders = header->numprogramheaderentries; size_t neededfilelen = phtbloffset + numprogheaders * phsize; - if ( filelen < neededfilelen ) { return 0; } + if ( filelen < neededfilelen ) { return 0; } + + // Reset the current address space. + process->ResetAddressSpace(); // Create all the segments in the final process. // TODO: Handle errors on bad/malicious input or out-of-mem! @@ -70,11 +74,28 @@ namespace Sortix ASSERT(pht->offset + pht->filesize < filelen); ASSERT(pht->filesize <= pht->memorysize); + ProcessSegment* segment = new ProcessSegment; + if ( segment == NULL ) { return 0; } + segment->position = mapto; + segment->size = Page::AlignUp(mapbytes); + + if ( segment->Intersects(process->segments) ) + { + delete segment; + return 0; + } + if ( !VirtualMemory::MapRangeUser(mapto, mapbytes) ) { - PanicF("Could not user-map at %p and %zu bytes onwards", mapto, mapbytes); + return 0; } + // Insert our newly allocated memory into the processes segment + // list such that it can be reclaimed later. + if ( process->segments ) { process->segments->prev = segment;} + segment->next = process->segments; + process->segments = segment; + // Copy as much data as possible and memset the rest to 0. byte* memdest = (byte*) virtualaddr; byte* memsource = (byte*) ( (addr_t)file + pht->offset); @@ -82,18 +103,15 @@ namespace Sortix Memory::Set(memdest + pht->filesize, 0, pht->memorysize - pht->filesize); } - // MEMORY LEAK: There is no system in place to delete the sections - // once the process has terminated. - return entry; } - addr_t Construct64(const void* /*file*/, size_t /*filelen*/) + addr_t Construct64(Process* /*process*/, const void* /*file*/, size_t /*filelen*/) { return 0; } - addr_t Construct(const void* file, size_t filelen) + addr_t Construct(Process* process, const void* file, size_t filelen) { if ( filelen < sizeof(Header) ) { return 0; } const Header* header = (const Header*) file; @@ -107,9 +125,9 @@ namespace Sortix switch ( header->fileclass ) { case CLASS32: - return Construct32(file, filelen); + return Construct32(process, file, filelen); case CLASS64: - return Construct64(file, filelen); + return Construct64(process, file, filelen); default: return 0; } diff --git a/sortix/elf.h b/sortix/elf.h index 13753bec..2236dab1 100644 --- a/sortix/elf.h +++ b/sortix/elf.h @@ -27,6 +27,8 @@ namespace Sortix { + class Process; + namespace ELF { struct Header @@ -117,7 +119,7 @@ namespace Sortix // Reads the elf file into the current address space and returns the // entry address of the program, or 0 upon failure. - addr_t Construct(const void* file, size_t filelen); + addr_t Construct(Process* process, const void* file, size_t filelen); } } diff --git a/sortix/kernel.cpp b/sortix/kernel.cpp index ee4494a4..b54b0ba0 100644 --- a/sortix/kernel.cpp +++ b/sortix/kernel.cpp @@ -252,7 +252,7 @@ namespace Sortix if ( initrd != NULL ) { - initstart = (Thread::Entry) ELF::Construct(initrd, initrdsize); + initstart = (Thread::Entry) ELF::Construct(process, initrd, initrdsize); if ( initstart == NULL ) { Panic("kernel.cpp: Could not construct ELF program"); diff --git a/sortix/process.cpp b/sortix/process.cpp new file mode 100644 index 00000000..b14274aa --- /dev/null +++ b/sortix/process.cpp @@ -0,0 +1,78 @@ +/****************************************************************************** + + COPYRIGHT(C) JONAS 'SORTIE' TERMANSEN 2011. + + This file is part of Sortix. + + Sortix is free software: you can redistribute it and/or modify it under the + terms of the GNU General Public License as published by the Free Software + Foundation, either version 3 of the License, or (at your option) any later + version. + + Sortix is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + details. + + You should have received a copy of the GNU General Public License along + with Sortix. If not, see . + + process.cpp + Describes a process belonging to a subsystem. + +******************************************************************************/ + +#include "platform.h" +#include +#include "process.h" +#include "memorymanagement.h" + +namespace Sortix +{ + bool ProcessSegment::Intersects(ProcessSegment* segments) + { + for ( ProcessSegment* tmp = segments; tmp != NULL; tmp = tmp->next ) + { + if ( tmp->position < position + size && + position < tmp->position + tmp->size ) + { + return true; + } + } + + if ( next ) { return next->Intersects(segments); } + + return false; + } + + Process::Process(addr_t addrspace) + { + _addrspace = addrspace; + _endcodesection = 0x400000UL; + segments = NULL; + } + + Process::~Process() + { + ResetAddressSpace(); + + // Avoid memory leaks. + ASSERT(segments == NULL); + + // TODO: Delete address space! + } + + void Process::ResetAddressSpace() + { + ProcessSegment* tmp = segments; + while ( tmp != NULL ) + { + VirtualMemory::UnmapRangeUser(tmp->position, tmp->size); + ProcessSegment* todelete = tmp; + tmp = tmp->next; + delete todelete; + } + + segments = NULL; + } +} diff --git a/sortix/process.h b/sortix/process.h index 9e79f5f4..471e0e0f 100644 --- a/sortix/process.h +++ b/sortix/process.h @@ -31,40 +31,50 @@ namespace Sortix { class Thread; class Process; - class MountPoint; - class User; - class System; - class DevBuffer; + struct ProcessSegment; + + struct ProcessSegment + { + public: + ProcessSegment() : prev(NULL), next(NULL) { } + + public: + ProcessSegment* prev; + ProcessSegment* next; + addr_t position; + size_t size; + + public: + bool Intersects(ProcessSegment* segments); + + }; class Process { public: - // TODO: Make this possible from an async syscall! - //bool CreateProcess(System* system, DevBuffer* image); + Process(addr_t addrspace); + ~Process(); + + private: + addr_t _addrspace; public: - DescriptorTable _descs; - - private: - MountPoint* _rootFS; - User* _user; - System* _system; + DescriptorTable descriptors; + ProcessSegment* segments; public: - MountPoint* GetRootFS() { _rootFS; } - User* GetUser() { _user; } - System* GetSystem() { _system; } + addr_t _endcodesection; // HACK - private: - Process* _parent; - Process* _child; - Process* _prevSibling; - Process* _nextSibling; + public: + addr_t GetAddressSpace() { return _addrspace; } + void ResetAddressSpace(); - private: - Thread* _firstThread; + public: + bool IsSane() { return _addrspace != 0; } }; + + Process* CurrentProcess(); } #endif diff --git a/sortix/scheduler.cpp b/sortix/scheduler.cpp index 99b2aedb..2c52b49e 100644 --- a/sortix/scheduler.cpp +++ b/sortix/scheduler.cpp @@ -38,17 +38,6 @@ namespace Sortix { const bool LOG_SWITCHING = false; - Process::Process(addr_t addrspace) - { - _addrspace = addrspace; - _endcodesection = 0x400000UL; - } - - Process::~Process() - { - // TODO: Delete address space! - } - namespace Scheduler { // This is a very small thread that does absoluting nothing! diff --git a/sortix/scheduler.h b/sortix/scheduler.h index cd46bc49..25946a0f 100644 --- a/sortix/scheduler.h +++ b/sortix/scheduler.h @@ -25,35 +25,12 @@ #ifndef SORTIX_SCHEDULER_H #define SORTIX_SCHEDULER_H +#include "process.h" #include "descriptors.h" namespace Sortix { class Thread; - class Process; - - class Process - { - public: - Process(addr_t addrspace); - ~Process(); - - private: - addr_t _addrspace; - - public: - DescriptorTable descriptors; - - public: - addr_t _endcodesection; // HACK - - public: - addr_t GetAddressSpace() { return _addrspace; } - - public: - bool IsSane() { return _addrspace != 0; } - - }; class Thread { @@ -138,7 +115,6 @@ namespace Sortix // Scheduling Thread* CurrentThread(); - Process* CurrentProcess(); } #endif