Program Loading

The provision of paging of file content leads to the possibility of demand paging for programs, enabling them to be loaded into memory dynamically and to have only the active portions of those programs resident. To achieve this, programs must be appropriately initialised in new tasks, with a page fault handler configured to provide program file content whenever a region of the program payload is encountered that is not currently resident in memory.

  1. Program Initialisation
    1. Program Executable File
    2. Task and Threads
    3. Thread Resources
    4. Thread Configuration
  2. Internal Page Fault Handlers
  3. External Page Fault Handlers
  4. Configuring Programs

Program Initialisation

To load and initialise a program, a new task must be created, defining a separate address space for the program and allowing it to operate independently of other programs. For a program to actually run, a thread of execution must be created so that the program's instructions can be read and processed. Once running, the program must be able to interact with the system environment and to have its memory resources made available to it upon demand.

A number of elements must be prepared to be able to run a program, these being summarised below.

Program Executable File

The program executable file is obtained and the program metadata loaded, identifying the memory regions and entry point (the location of the first instruction).

Task and Threads

A new task is created to hold the program. For this new task, new threads are created to run and support the program. One thread will run the actual program, and another will be used as the region mapper to handle page fault conditions.

Thread Resources

Memory is allocated for the new program's threads, particularly the stack for each thread.

Each stack is populated with program argument and environment information. Of particular importance are the capabilities to be made available to the threads since these permit interaction with the rest of the system.

The capabilities to be used by the threads must be mapped into the new task.

Thread Configuration

To connect the main thread of the program to its region mapper, an IPC gate must be created. This is mapped to the new task where the region mapper will bind to it, using it to expose its interface.

Thread properties such as pagers and exception handlers are defined for the threads, with the main thread employing the newly created IPC gate capability to delegate paging to the region mapper.

Internal Page Fault Handlers

When satisfying page faults for a task, one approach involves situating the page fault handler within the task itself, this managing the available memory regions and employing receive windows when requesting memory pages.

The general arrangement involving such internal page fault handlers for a program in a task is as follows:

internal_pagingTask Memorystack...data...codeInternalPagerpage faultResides insame task anddefines scope offault resolutionRegionsstackstack-dataspacedatadata-dataspacecodecode-dataspace...find regionFlexpage(receive window)Resource(Pager)mapFlexpageSatisfiesmemoryaccessProvides accessto file contentProgram File...datacode...

External Page Fault Handlers

Another approach is to employ an external page fault handler in the creating task. When a page fault occurs, the external handler ensures that the appropriate content has been brought into its own memory space. It then returns a flexpage from the handler routine to resolve the fault.

external_pagingTask Memorystack...data...codeExternalPagerpage faultResides inseparate taskFlexpage(positioned)Regionsstackstack-dataspacedatadata-dataspacecodecode-dataspace...find regionL4Re pagingfunctionalitySatisfiesmemoryaccessResource(Pager)Supports normalaccess to file contentmapFlexpageProvides accessto file contentProgram File...datacode...

This arrangement may be used to support a program deployed in a task. Since an internal page fault handler is just another kind of program, this external pager arrangement can be constrained to only supporting an internal page fault handler deployed in a task.

Configuring Programs

To provide an internal page fault handler alongside an actual program to be run, the following arrangement is used:

program_configurationResponsible forcreating thenew taskCreating taskIPC gatecreateInitial capabilitiesENV_INTERNAL_PAGER_NAMEcapabilitydefineInternalPagerstartProgramstartCreated for sharingbetween the tasksbindStarts and bindsto IPC gateStarts and referencespager via IPC gate

The creating task performs the following operations:

  1. Create an IPC gate for communication between the program and its pager.
  1. Map the IPC gate into the created task to be accessible via a given capability slot.
  1. Define the IPC gate in the pager's initial capabilities using a well-defined name, allowing the pager to look up the capability in its environment.
  1. Start the pager which itself obtains the IPC gate capability and binds to it, making itself available as the pager for the program.
  1. Set the pager of the program to the IPC gate as mapped within the task.
  1. Start the program which is already configured to send page faults via the IPC gate to the pager.

Upon starting, the program will encounter a page fault immediately, unless some additional work was done to map memory pages into the task in advance. The internal pager or page fault handler will attempt to resolve these faults as they occur, being contacted by the kernel on the program's behalf.