System calls are like normal BSD-type system calls where the user traps
into the kernel with an indication of what call to perform, etc. A system
primitive in Mach uses IPC to get the call into the kernel. An interrupt
comes from a device and is serviced by an interrupt handler, although traps
and interrupts are sort of the same kind of architectural thing, they are
very different in software, and so it's not usually helpful to think about
them as being similar. The addition of a new system primitive is described
in the next section. The addition of a new system call involves the following:
-
Edit src/mk/kernel/kern/syscall_sw.c in your RT-Mach source tree. Change
an unused kern_invalid entry to have the name of your syscall function,
and the number of integer-sized (e.g. register size pmax = 32, alpha =
64, i386=32) arguments it takes. Also add a function prototype that looks
like
extern kern_return_t your_new_system_call();
(as is done towards the top of the file after the definitions of null_port()
and kern_invalid() .
-
Add an entry to src/mk/kernel/mach/syscall_sw.h in your RT-Mach source
tree. It should have the same function name, the number of the trap you
added (it's in the comment in syscall_sw.c and the number of integer-sized
arguments it takes.
-
If your syscall does not require a library wrapper add it's name to RT_TRAPS
in src/mk/user/libmach_rt/Makefile in the source tree. If a library wrapper
is required add the name of your syscall function to RT_SYSCALLS. The wrapper
itself must be in ms_{syscall name}.c Since syscalls use IPC to communicate
with user programs you need to add mig specification of your syscall to
src/mk/kernel/rt/rt.defs
-
Add your syscall to the kernel (the code for the system call) - it should
return a kern_return_t. Be sure to remember that memory transfers must
be done with copyin (no pointer stuff, other lower level mechanism with
suffix _copy[in/out] ) and copyout (or even lower-level memory primitives)
-
Rebuild the kernel. Remember to install your new kernel using odemake install_all
and copy the updated kernel to the boot directory /.
Note : On an Alpha, the size of an integer is not equal to the size of
a CPU register.