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.
You have to implement the following system calls (which are quite similar to their Unix equivalents):
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.
User space applications sometimes require dynamic memory allocation. Extend your kernel to provide new system calls to fulfill this demand:
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
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.
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.