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):
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 receive
Retrieve the process ID of the calling process. The PID has to be a unique thread identifier in the whole system.
Retrieve the parent process ID of the calling process. If it was not created by
fork, it will return
All page frames belonging to the calling process have to be copied in
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 for
sizebytes is mapped into the calling threads address space at
addr. In case the requested address is
NULL, 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 return
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
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.