Dokumentation
In Unix-like operating systems, fork
is used by a process to create a new child process. The child process is a duplicate of its parent, but runs in a different address space, with its own context.
Process Management System Calls
You have to implement the following system calls (which are quite similar to their Unix equivalents):
int fork();
Create a new process duplicating the calling process, including the process state: On activation, the new child process shall start at the same point its parent will resume. The only difference is the return value of the call – the parent will get the process ID (PID) of its child, while the child will receive0
.int getpid();
Retrieve the process ID of the calling process. The PID has to be a unique thread identifier in the whole system.int getppid();
Retrieve the parent process ID of the calling process. If it was not created byfork
, it will return0
.
Implementation Details
All page frames belonging to the calling process have to be copied in fork
. The fork
system call's stub in user space is allowed to contain additional code to save and restore the contents of the non-scratch registers. This way you have the ability to re-use your existing infrastructure for launching a user space thread.
Extended Memory Management (7.5 ECTS)
User space applications sometimes require dynamic memory allocation. Extend your kernel to provide new system calls to fulfill this demand:
void* map(void* addr, size_t size);
Zeroed user memory with at least enough space forsize
bytes is mapped into the calling threads address space ataddr
. In case the requested address isNULL
, the kernel has to find a suitable place in the user space. On successful execution, the system call will return the allocated address. If allocation is not possible (or not allowed) it shall returnNULL
.void exit();
This call will quit the current thread and free all resources associated with it. Under no circumstances is this system call allowed to return to the calling thread.
Validate the correctness of your system call implementations using a suitable test program: The exit
system call, for example, can be tested by reporting the current state of the page frame allocator before loading a thread and after exit()
– the number of unused pages should be the same.
Dynamic Allocator for User Space
Once the map
system call works correctly, it is quite easy to port the buddy allocator from the kernel to your user space library (libsys
). The following example allows a dynamic allocation of up to 64 MiB in each application (as long as there is enough continuous memory mappable):
This in turn allows not only the usage of additional functionality like strdup but also implementing operator new
and operator delete
in the init.cc
to dynamically create objects in user space.