Hi, I’m new to seL4 (and OS development in general) and have been going through the tutorial.
In the second tutorial, untyped, the goal is to retype some initially untyped capabilities. I’m confused about the size of the untyped capabilities and how retyping works.
The tutorial starts off like this:
// list of general seL4 objects
seL4_Word objects[] = {seL4_TCBObject, seL4_EndpointObject,
seL4_NotificationObject};
// list of general seL4 object size_bits
seL4_Word sizes[] = {seL4_TCBBits, seL4_EndpointBits, seL4_NotificationBits};
// TODO work out what size object we need to create to be able to create all
// of the objects listed above
seL4_Word untyped_size_bits = 0;
I would expect:
untyped_size_bits = seL4_TCBBits + seL4_EndpointBits + seL4_NotificationBits;
However, the solution suggests:
untyped_size_bits = seL4_TCBBits + 1;
seL4_TCBBits
is the largest, which I think is important, but I’m not sure why the solution is correct.
The tutorial then follows:
seL4_CPtr parent_untyped = 0;
seL4_CPtr child_untyped = info->empty.start;
// First, find an untyped big enough to fit all of our objects
for (int i = 0; i < (info->untyped.end - info->untyped.start); i++) {
if (info->untypedList[i].sizeBits >= untyped_size_bits &&
!info->untypedList[i].isDevice) {
parent_untyped = info->untyped.start + i;
break;
}
}
// create an untyped big enough to retype all of the above objects from
error =
seL4_Untyped_Retype(parent_untyped, // the untyped capability to retype
seL4_UntypedObject, // type
untyped_size_bits, // size
seL4_CapInitThreadCNode, // root
0, // node_index
0, // node_depth
child_untyped, // node_offset
1 // num_caps
);
I’m trying not to copy-paste the entire tutorial but also provide enough context to convey the problem.
If I understand correctly, this code breaks off a chunk of bytes (size untyped_size_bits
) and creates a new untyped capability from it at the child_untyped
location.
The next part of the tutorial tasks you with creating child TCB, Endpoint, and Notification objects.
The solution is as follows (without the test cases):
seL4_CPtr child_tcb = child_untyped + 1;
seL4_Untyped_Retype(child_untyped, seL4_TCBObject, 0, seL4_CapInitThreadCNode,
0, 0, child_tcb, 1);
seL4_CPtr child_ep = child_tcb + 1;
seL4_Untyped_Retype(child_untyped, seL4_EndpointObject, 0,
seL4_CapInitThreadCNode, 0, 0, child_ep, 1);
seL4_CPtr child_ntfn = child_ep + 1;
seL4_Untyped_Retype(child_untyped, seL4_NotificationObject, 0,
seL4_CapInitThreadCNode, 0, 0, child_ntfn, 1);
What I don’t understand about this is that it seems to be writing past child_untyped
, and so its length seems irrelevant. Does child_tcb = child_untyped + 1
mean that child_tcb
is pointing to the capability slot after child_untyped
?
I think I am confusing capabilities with the actual memory that the child_untyped
capability is referring to.
While writing this, I feel like I’ve completely missed the point of the tutorial. I have a basic understanding of memory and threads, but I’m still in high school and feel like I am in way over my head. Would you suggest that I learn more about OS development and try out seL4 with more experience and some formal CS education?