let me start with the questions raised at the end of your posting:
> I also have some general questions about Genode capabilities in
> Fiasco.OC: In the Genode Foundations book, on page 37, there is a
> figure (figure 2) with an RPC object and its object identity. What is
> an object identity in Fiasco.OC?
> * How is it called there?
Note that the book is focused on NOVA and base-hw, which resemble the
presented capability model quite closely. On other kernels like seL4 and
Fiasco.OC, there is a slight mismatch between the kernel-provided
capability mechanism and Genode's notion of capabilies. You can find a
discussion of one important distinction at . Hence, on these kernels,
we need to "emulate" parts of Genode's capability model using the kernel
features at hand.
On Fiasco.OC, an object identity consists of two parts:
1. An IPC gate bound to the entrypoint thread. The IPC gate is
a Fiasco-internal kernel object. The user-level component
refers to it via a kernel-capability selector, which is
(like a file descriptor on Unix) a component-local number
understood by the kernel. In Genode's code, we use the term
"kcap" as an abbreviation of kernel capability selector.
The kcap can be used as an argument for kernel operations,
in particular as a destination for an IPC call.
Note that kcaps may refer to various kernel objects (like
threads, tasks). But - a few exceptions notwithstanding -
a Genode capability (as returned by 'Entrypoint::manage')
refers to the kcap for an IPC gate.
2. A system-globally unique object ID, which is allocated by
core's 'Pd_session::alloc_rpc_cap' operation. Unlike the
kcap, the kernel has no idea what this ID is about. It is
just a number. Within the Genode code, this number is called
"badge" or "Rpc_obj_key". The badge value is used at the server
side as a key for looking up the RPC object that belongs to an
incoming RPC request.
Each Genode capability carries both parts. When a component inserts a
new capability into its capability space, you can see both values as
arguments to 'Capability_map::insert_map' (in
When a Genode capability is transferred as RPC argument (via
'copy_msgbuf_to_utcb' and 'extract_msg_from_utcb' in
base-foc/src/lib/ipc.cc), you can see that the kcap part is passed as a
'L4_MAP_ITEM' whereas the badge is transferred as plain message word.
When a Genode capability is created for an RPC object
('Entrypoint::manage' -> 'PD_session::alloc_rpc_cap'), core imprints the
new badge value into the new IPC gate. This way, whenever an IPC is sent
to the IPC gate, the receiving thread (the server) receives the badge
value of the invoked object directly from the kernel. This way, a
misbehaving client cannot deliberately fake the badge when invoking an
Given this background, I hope that my remark about base-hw in my
previous email becomes more clear. On base-hw, we can simply use the
value of a kernel capability selector as badge value. There is no need
to system-globally unique ID values.
> * ...the owner of the RPC object?
The kcap of a Genode capability refers to an IPC gate. The IPC gate is
associated with a thread. The thread lives in a protection domain. The
owner of an RPC object is therefore implicitly the PD that created the
IPC gate (the caller of 'Entrypoint::manage') for the RPC object.
> * ...which component has the data in memory?
Each component keeps track of its local capability space using some
meta-data structures managed internally within the 'base' library. On
Fiasco.OC, this data structure is called 'cap_map'. It maintains the
association of 'kcap' values with their corresponding badges.
For the checkpointing/restarting, these data structure must be
interpreted/updated from the monitoring component. This may be tricky
because the cap_map is not designed to be easy to manipulate from the
outside. I.e., it has an AVL tree with the badges as keys. By solely
poking new badge values into the component's cap cap, the order of AVL
nodes becomes corrupted.
It may be possible to simplify the cap-map implementation, removing the
AVL tree. As far as I can see, the use cases for looking up a kcap by a
badge no longer exists except for sanity checks within the
implementation of the cap map itself. The method 'Capability_map::find'
is actually unused.
> * ...where it can be found in the address space?
The cap map is instantiated as local static variable of the function
'Genode::cap_map' in 'base-foc/src/lib/base/cap_map.cc'. Hence, it is
located somewhere in the data segment of the binary. You'd need to
somehow communicate the pointer value from the component to the monitor,
e.g. by writing it to a dataspace shared between the two.
> In particular, when the target component creates an Entrypoint object,
> then it creates a Native_capability (as Ipc_server) from a capability
> found in the utcb's thread control registers:
> The Ipc_server capability is used in two calls to
> Pd_session::alloc_rpc_cap during Entrypoint object creation. The two
> calls go to Entrypoint::manage the Exit-handler for the Rpc_entrypoint
> and for the Signal_proxy_component for the Signal-API. To recreate those
> Native_capabilities at restore time, I have to use the same Ipc_server
> capability. How can this be done?
The Ipc_server capability is the kernel capability selector for the
entrypoint thread. This selector is used to associate the new IPC gate
with this particular thread. So IPCs sent to the IPC gate will arrive at
the entrypoint thread. It is not a regular Genode capability because it
refers to a thread instead of an IPC gate. Fortunately, the monitor is
able to get hold of this capability because the component requests it by
calling 'Cpu_thread::state' when creating a new thread
Yes, the topic is really complicated. Is the confusion perfect now? ;-)
Dr.-Ing. Norman Feske
http://www.genode-labs.com · http://genode.org
Genode Labs GmbH · Amtsgericht Dresden · HRB 28424 · Sitz Dresden
Geschäftsführer: Dr.-Ing. Norman Feske, Christian Helmuth
Check out the vibrant tech community on one of the world's most
engaging tech sites, SlashDot.org! http://sdm.link/slashdot
genode-main mailing list