Modifying the Address Space

This chapter will focus on using the seL4 virtual address space (VSpace) APIs to manipulate the root task's own address space. Start by navigating to and running this chapter's example, which, so far, is empty.

cd workspaces/root-task/address-space
make simulate

In seL4, each thread is associated with a virtual address space (VSpace). A VSpace is comprised of a tree of translation tables mapping virtual addresses into physical frames of memory. VSpaces are represented by their root translation structures. While the high-level virtual address space API concepts are architecture-independent, the specific kernel object types for a given architecture mirror that architecture's paging structures. That said, all architectures share two object types:

The root task is provided with capabilites for the objects comprising its own virtual address space. The locations of these capabilities in the root task's CSpace is provided in the BootInfo struct. Our goal for this chapter will be to create a frame object and experiment with mapping it into the root task's own address space.

Step 4.A (exercise)       

Exercise: Using code snippets from Chapter 3 (Allocating Kernel Objects), create a frame object. We seek a value frame: sel4::cap::Granule (which can also be written as frame: sel4::Cap<sel4::cap_type::Granule>).

Note that, after importing the sel4::CapTypeForObjectOfFixedSize trait, you can express the appropriate sel4::ObjectBlueprint as sel4::cap_type::Granule::object_blueprint().

Step 4.B       

In order to avoid interacting with intermediate translation structures, let's reserve an aligned granule-sized region in the root task's program image that we can use for our experiment:

This reservation covers exactly one page in the root task's virtual address space.

Step 4.C       

Let's unmap the page in the root task image that initially backs our reserved region. This will give us a hole in the root task VSpace, which we can use for our experiment.

This function determines the slot in the root task's CSpace of the page capability corresponding to the page in the root task's VSpace which contains the given address:

__executable_start is defined by the linker. We can use it, along with addr, to identify the offset into bootinfo.user_image_frames() of the capability we are after.

Use the get_user_image_frame_slot() function to find the capability corresponding to the frame backing our reserved region, and unmap that frame, leaving a hole in the root task's virtual address space. Try to access that region, and observe a page fault:

Step 4.D (exercise)       

Exercise: Map new_frame at page_a_addr using new_frame.frame_map(), which corresponds to seL4_ARM_Page_Map.

Here are some hints for the parameters of .frame_map():

  • vspace: A capability for the root task's VSpace can be expressed using sel4::init_thread::slot::VSPACE.cap().
  • rights: sel4::CapRights::read_write() are the most permissive rights, and will work for our purposes.
  • attrs: sel4::VmAttributes::default() will work here.