# HG changeset patch # User Paul Boddie # Date 1656616702 -7200 # Node ID bde6edfa486599da68a6f42cd1e99064ad41e6c1 # Parent bc65615a8fed09cb6f9a3831b2cb61dce22c913e Added a page describing program loading techniques. diff -r bc65615a8fed -r bde6edfa4865 docs/wiki/Filesystems --- a/docs/wiki/Filesystems Thu Jun 30 21:17:42 2022 +0200 +++ b/docs/wiki/Filesystems Thu Jun 30 21:18:22 2022 +0200 @@ -9,10 +9,11 @@ access filesystem objects * [[Components]] - server objects exposed at the system level that support filesystem access - * [[FilesystemAccess|Filesystem Access]] - objects within filesystem servers - that manage filesystem resources and content + * [[FilesystemAccess|Filesystem Access]] - mechanisms within filesystem + servers to manage filesystem resources and content * [[Paging]] - the mechanism by which filesystem content is provided for use by client programs + * [[ProgramLoading|Program Loading]] - the mechanism by which programs are loaded * [[ServerLibrary|Server Library]] - abstractions to expose and manage access to filesystem objects * [[Users]] diff -r bc65615a8fed -r bde6edfa4865 docs/wiki/ProgramLoading --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/wiki/ProgramLoading Thu Jun 30 21:18:22 2022 +0200 @@ -0,0 +1,236 @@ += Program Loading = + +The provision of [[Paging|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. + +== 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: + +######## A graph showing the internal paging mechanism + +{{{#!graphviz +#format svg +#transform notugly +digraph internal_paging { + node [fontsize="12.0",fontname="sans-serif",shape=box]; + edge [fontsize="12.0",fontname="sans-serif"]; + rankdir=LR; + + TaskMemory [shape=record,label="Task Memory | stack | ... | data | ... | code"]; + + subgraph { + rank=same; + + InternalPager; + InternalPager_note [shape=note,style=filled,fillcolor=gold,label="Resides in\nsame task and\ndefines scope of\nfault resolution"]; + + InternalPager -> InternalPager_note [dir=none,style=dotted]; + } + + subgraph { + rank=same; + + Regions [shape=record,label="Regions | + { stack | stack-dataspace } | + { data |
data-dataspace } | + { code | code-dataspace } |..."]; + + ReceiveFlexpage [shape=note,label="Flexpage\n(receive window)"]; + + Flexpage [shape=note]; + Flexpage_note [shape=note,style=filled,fillcolor=gold,label="Satisfies\nmemory\naccess"]; + + Flexpage -> Flexpage_note [dir=none,style=dotted]; + } + + subgraph { + rank=same; + + ResourceD [label="Resource\n(Pager)"]; + ResourceD_note [shape=note,style=filled,fillcolor=gold,label="Provides access\nto file content"]; + + ResourceD -> ResourceD_note [dir=none,style=dotted]; + } + + ProgramFile [shape=record,label="Program File | ... | data | code | ..."]; + + /* Page fault handling. */ + + TaskMemory:d -> InternalPager [label="page fault"]; + + InternalPager -> Regions:d [label="find region"]; + + Regions:dd -> ResourceD [style=dashed]; + + InternalPager -> ReceiveFlexpage [dir=none]; + ReceiveFlexpage -> ResourceD [label="map"]; + + ResourceD -> ProgramFile:d [style=dashed]; + + ResourceD -> Flexpage [dir=none]; + Flexpage -> InternalPager; +} +}}} + +######## + +== External Page Fault Handlers == + +Another approach that may be used to support an internal page fault handler +deployed in a task 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. + +######## A graph showing the external paging mechanism + +{{{#!graphviz +#format svg +#transform notugly +digraph external_paging { + node [fontsize="12.0",fontname="sans-serif",shape=box]; + edge [fontsize="12.0",fontname="sans-serif"]; + rankdir=LR; + + TaskMemory [shape=record,label="Task Memory | stack | ... | data | ... | code"]; + + subgraph { + rank=same; + + ExternalPager_note [shape=note,style=filled,fillcolor=gold,label="Resides in\nseparate task"]; + ExternalPager; + + ExternalPager_note -> ExternalPager [dir=none,style=dotted]; + + MappedFlexpage [shape=note,label="Flexpage\n(positioned)"]; + MappedFlexpage_note [shape=note,style=filled,fillcolor=gold,label="Satisfies\nmemory\naccess"]; + + MappedFlexpage -> MappedFlexpage_note [dir=none,style=dotted]; + } + + subgraph { + rank=same; + + Regions [shape=record,label="Regions | + { stack | stack-dataspace } | + { data |
data-dataspace } | + { code | code-dataspace } |..."]; + + L4Re [shape=ellipse,label="L4Re paging\nfunctionality"]; + L4Re_note [shape=note,style=filled,fillcolor=gold,label="Supports normal\naccess to file content"]; + + L4Re -> L4Re_note [dir=none,style=dotted]; + + Flexpage [shape=note]; + } + + subgraph { + rank=same; + + ResourceD [label="Resource\n(Pager)"]; + ResourceD_note [shape=note,style=filled,fillcolor=gold,label="Provides access\nto file content"]; + + ResourceD -> ResourceD_note [dir=none,style=dotted]; + } + + ProgramFile [shape=record,label="Program File | ... | data | code | ..."]; + + /* Page fault handling. */ + + TaskMemory:d -> ExternalPager [label="page fault"]; + + ExternalPager -> Regions:d [label="find region"]; + + Regions:dd -> ResourceD [style=dashed]; + + ExternalPager -> L4Re; + L4Re -> ResourceD [label="map"]; + + ResourceD -> ProgramFile:d [style=dashed]; + + ResourceD -> Flexpage [dir=none]; + Flexpage -> ExternalPager; + + ExternalPager -> MappedFlexpage [dir=none]; + MappedFlexpage -> TaskMemory:d; +} +}}} + +######## + +== Configuring Programs == + +To provide an internal page fault handler alongside an actual program to be +run, the following arrangement is used: + +######## A graph showing the configuration arrangement + +{{{#!graphviz +#format svg +#transform notugly +digraph program_configuration { + node [fontsize="12.0",fontname="sans-serif",shape=box]; + edge [fontsize="12.0",fontname="sans-serif"]; + rankdir=LR; + + subgraph { + rank=min; + + CreatingTask_note [shape=note,style=filled,fillcolor=gold,label="Responsible for\ncreating the\nnew task"]; + CreatingTask [label="Creating task"]; + + CreatingTask_note -> CreatingTask [dir=none,style=dotted]; + } + + subgraph { + rank=max; + + IPCGate_note [shape=note,style=filled,fillcolor=gold,label="Created for sharing\nbetween the tasks"]; + IPCGate [shape=octagon,label="IPC gate"]; + + IPCGate_note -> IPCGate [dir=none,style=dotted]; + } + + InitCaps [shape=record,label=" Initial capabilities | { \"server\" | capability }"]; + + subgraph { + rank=same; + + InternalPager; + InternalPager_note [shape=note,style=filled,fillcolor=gold,label="Starts and binds\nto IPC gate"]; + + InternalPager -> InternalPager_note [dir=none,style=dotted]; + + Program; + Program_note [shape=note,style=filled,fillcolor=gold,label="Starts and references\npager via IPC gate"]; + + Program -> Program_note [dir=none,style=dotted]; + } + + /* Create and transfer IPC gate for binding. */ + + CreatingTask -> IPCGate [label="create"]; + CreatingTask -> InitCaps:head [label="define"]; + InitCaps:c -> IPCGate; + + /* Thread initiation. */ + + CreatingTask -> InternalPager [label="start"]; + InternalPager -> InitCaps:s [label="bind"]; + + CreatingTask -> Program [label="start"]; + Program -> IPCGate -> InternalPager [style=dashed]; +} +}}} + +########