Dear Genode community,
I want to implement a new service (class Cr_session) residing in core
which provides an Rpc method to checkpoint the state of a specific
component (given its label string). I am using Genode 16.05 and the foc
kernel (pbxa9 build). The first step is to store the content of the
address space of the compoent. My approach is the following:
1) First a test component is created which shall be checkpointed. The
component counts an integer every second.
In base/src/test/cr_service/counter/main.cc (newly created file):
!void Component::construct(Genode::Env &env)
!{
! unsigned int n = 0;
! Timer::Connection timer(env);
!
! while(1)
! {
! Genode::log(n);
! n++;
! timer.msleep(1000);
! }
!}
2) To realize the CR service in core, I want to find the specific PD
session of the test component. Therefore a separate Sliced_heap
exclusively for Pd_session_component objects is created in core's main
function.
In base/src/core/main.cc:
!static Sliced_heap pd_sliced_heap(env()->ram_session(),
env()->rm_session());
![...]
!static Pd_root pd_root(e, e, pager_ep, &pd_sliced_heap);
2) The CR service is registered and the special Sliced_heap is passed to
the Root_component<Cr_session_component> object.
In base/src/core/main.cc:
!static Cr_root cr_root(e, &sliced_heap, &pd_sliced_heap);
![...]
!static Local_service ls[] = {
! Local_service(Cr_session::service_name(), &cr_root),
![...]
!}
3) In the implementation of the checkpoint method the Sliced_heap
(stored in _alloced_pds) is searched for a Pd_session_component with a
specific label string. The class implementing the Cr service
(Genode::Cr_session_component : Rpc_object<Cr_session>) is a friend
class in Sliced_heap and is allowed to access the _blocks member
variable containing the Pd_session_component objects.
In base/src/core/include/cr_session_component.h (newly created file):
!bool checkpoint(String<64> label)
!{
! Pd_session_component *pd = nullptr;
! bool found = false;
! Sliced_heap::Block *b = _alloced_pds->_blocks.first();
! for(; (b != 0) && !found; b = b->next())
! {
! pd = reinterpret_cast<Pd_session_component*>(b + 1);
! if(label == pd->_label.string) found = true;
! }
4) The Pd_session_component object is known and now it shall be used to
access the test component's address space content. To retrieve the
content I want to attach the Dataspace of the component's Region_map to
core's Region_map.
In base/src/core/include/cr_session_component.h (newly created file):
! Capability<Region_map> rm_cap = pd->address_space();
! Region_map_client rm_client(rm_cap);
! void* addr = core_env()->rm_session()->attach(rm_client.dataspace());
! return true;
!}
5) After invoking rm_client.dataspace() the Rpc method never returns and
the test scenario times out.
What am I doing wrong? I compared the source code of other core services
with the CR service and found no usage of classes derived from
Rpc_client belonging to other core services. Is it not possible to use
Rpc methods in core?
I tested another solution where I only use Rpc_objects directly. I used
pd_session_component::address_space_region_map() to access the
address_space directly, where I think to find the memory content of the
test component (Please correct me, if I am wrong).
The following listing replaces the listing in step 4.
In base/src/core/include/cr_session_component.h (newly created file):
! Dataspace_capability ds_cap =
pd->address_space_region_map().dataspace();
! char* addr = core_env()->rm_session()->attach(ds_cap);
! log("Attaching dataspace: Returned pointer: ", addr);
!
! Dataspace_component *ds_comp =
pd->address_space_region_map().dataspace_component();
! log("Reading dataspace component");
! log("phys_addr = ", ds_comp->phys_addr(), " size = ",
ds_comp->size(), " writable = ", ds_comp->writable() ? "true" : "false");
The output of the log function was the following:
Attaching dataspace: Returned pointer: 0x00000000
Reading dataspace component
phys_addr = 0 size = 3221221376 writable = false
Now I got a null pointer and cannot read the content of the Region_map
of the test component.
Can someone help me to answer the following questions:
* Can I use Capability invokation in core, where the Rpc_object belongs
to another core service? If yes, how? Perhaps, my problem is the correct
retrieval of the Pd_session_component, thus I can invalid Capabilities.
* Why do I get an invalid pointer from the attach method of core's
Region_map? Is it not allowed to attach dataspaces in core? Are they
already attached in core, and I only need the pointer to the memory? Is
the Dataspace_capability invalid?
Kind regards
Denis