Interprocess communication (IPC) is presumably initiated by a syscall operation.
According to the course materials, there is only one meaningful system call (invoke_object):
Microkernel-based Operating Systems - Introduction
(See page 24 in the above.)
In L4Re, syscall operations appear to occur in the following place:
In this file, the l4_ipc function employs registers as follows:
In the L4 X.2 (MIPS64) and V2/MIPS specifications, the IPC description appears to employ registers differently, with s0...s7 corresponding to virtual message registers. Here, some details of V2/MIPS are omitted:
Register | X.2 (LIPC) | V2/MIPS (IPC) |
a0 | send descriptor | send descriptor |
a1 | receive descriptor | receive descriptor |
a2 | timeouts | timeouts |
a4 | destination id | |
s0 | MR0 | MR0 |
s1 | MR1 | MR1 |
s2 | MR2 | MR2 |
s3 | MR3 | MR3 |
s4 | MR4 | MR4 |
s5 | MR5 | MR5 |
s6 | MR6 | MR6 |
s7 | MR7 | MR7 |
Here, the X.2 register usage for a0 and a1 has been interpreted and hopefully translated correctly to some common terminology. See Kernel for more details regarding Fiasco.OC.
There are also syscall operations in other places within the following location:
Within this location, the following files appear interesting:
However, it doesn't seem clear if they are actually used, especially in the light of the assertion about system call usage.
The following file seems to list symbols provided by uclibc for L4:
l4_ipc is wrapped by a family of other functions:
A simple example of IPC is provided by l4_usleep and l4_sleep:
The l4_sleep function just calls l4_ipc_receive with a timeout. Similarly, the l4_usleep function calls l4_ipc_sleep whose definition is provided elsewhere:
l4_ipc_sleep then calls l4_ipc_receive with a timeout.
Such functions are exposed by C library functions such as usleep:
So, such C library functions call into the l4-prefixed functions which in turn ultimately call the l4_ipc function.
IPC syscalls enter the kernel in the following place:
Specifically, the syscall entry point is involved. It invokes the sys_ipc_wrapper function, which is found here:
This function dereferences the object reference (capability), and on the object supporting the appropriate interface (Kobject_iface), the invoke method is called:
The portion of the saved registers referencing s0 is reinterpreted as a Syscall_frame instance:
Thus, an abstraction for the s0...s4 registers is employed, being presented to invoke and used in an invocation of a kinvoke method. For IPCs this is presumably supported in the Ipc_gate_ctl class:
Thus resulting in an invocation of kobject_invoke and, within this, commit_result:
With a L4_msg_tag instance being created and returned:
Back in the invoke method, this new tag is set in the Syscall_frame instance.
pkg/l4re-core/l4sys/include/types.h
There presumably has to be the registration of a kernel object to accept IPC calls. A reference to such an object - a capability - must be presented to any caller. Then, any IPC call, directed via the capability, will be conveyed by the kernel mechanisms and presented to the recipient.
pkg/l4re-core/l4sys/include/factory.h