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