1 = Program Loading = 2 3 The provision of [[Paging|paging]] of file content leads to the possibility of 4 demand paging for programs, enabling them to be loaded into memory dynamically 5 and to have only the active portions of those programs resident. To achieve 6 this, programs must be appropriately initialised in new tasks, with a page 7 fault handler configured to provide program file content whenever a region of 8 the program payload is encountered that is not currently resident in memory. 9 10 == Internal Page Fault Handlers == 11 12 When satisfying page faults for a task, one approach involves situating the 13 page fault handler within the task itself, this managing the available memory 14 regions and employing receive windows when requesting memory pages. 15 16 The general arrangement involving such internal page fault handlers for a 17 program in a task is as follows: 18 19 ######## A graph showing the internal paging mechanism 20 21 {{{#!graphviz 22 #format svg 23 #transform notugly 24 digraph internal_paging { 25 node [fontsize="12.0",fontname="sans-serif",shape=box]; 26 edge [fontsize="12.0",fontname="sans-serif"]; 27 rankdir=LR; 28 29 TaskMemory [shape=record,label="Task Memory |<s> stack | ... |<d> data | ... |<c> code"]; 30 31 subgraph { 32 rank=same; 33 34 InternalPager; 35 InternalPager_note [shape=note,style=filled,fillcolor=gold,label="Resides in\nsame task and\ndefines scope of\nfault resolution"]; 36 37 InternalPager -> InternalPager_note [dir=none,style=dotted]; 38 } 39 40 subgraph { 41 rank=same; 42 43 Regions [shape=record,label="Regions | 44 {<s> stack |<sd> stack-dataspace } | 45 {<d> data | <dd> data-dataspace } | 46 {<c> code |<cd> code-dataspace } |..."]; 47 48 ReceiveFlexpage [shape=note,label="Flexpage\n(receive window)"]; 49 50 Flexpage [shape=note]; 51 Flexpage_note [shape=note,style=filled,fillcolor=gold,label="Satisfies\nmemory\naccess"]; 52 53 Flexpage -> Flexpage_note [dir=none,style=dotted]; 54 } 55 56 subgraph { 57 rank=same; 58 59 ResourceD [label="Resource\n(Pager)"]; 60 ResourceD_note [shape=note,style=filled,fillcolor=gold,label="Provides access\nto file content"]; 61 62 ResourceD -> ResourceD_note [dir=none,style=dotted]; 63 } 64 65 ProgramFile [shape=record,label="Program File | ... |<d> data |<c> code | ..."]; 66 67 /* Page fault handling. */ 68 69 TaskMemory:d -> InternalPager [label="page fault"]; 70 71 InternalPager -> Regions:d [label="find region"]; 72 73 Regions:dd -> ResourceD [style=dashed]; 74 75 InternalPager -> ReceiveFlexpage [dir=none]; 76 ReceiveFlexpage -> ResourceD [label="map"]; 77 78 ResourceD -> ProgramFile:d [style=dashed]; 79 80 ResourceD -> Flexpage [dir=none]; 81 Flexpage -> InternalPager; 82 } 83 }}} 84 85 ######## 86 87 == External Page Fault Handlers == 88 89 Another approach that may be used to support an internal page fault handler 90 deployed in a task is to employ an external page fault handler in the creating 91 task. When a page fault occurs, the external handler ensures that the 92 appropriate content has been brought into its own memory space. It then 93 returns a flexpage from the handler routine to resolve the fault. 94 95 ######## A graph showing the external paging mechanism 96 97 {{{#!graphviz 98 #format svg 99 #transform notugly 100 digraph external_paging { 101 node [fontsize="12.0",fontname="sans-serif",shape=box]; 102 edge [fontsize="12.0",fontname="sans-serif"]; 103 rankdir=LR; 104 105 TaskMemory [shape=record,label="Task Memory |<s> stack | ... |<d> data | ... |<c> code"]; 106 107 subgraph { 108 rank=same; 109 110 ExternalPager_note [shape=note,style=filled,fillcolor=gold,label="Resides in\nseparate task"]; 111 ExternalPager; 112 113 ExternalPager_note -> ExternalPager [dir=none,style=dotted]; 114 115 MappedFlexpage [shape=note,label="Flexpage\n(positioned)"]; 116 MappedFlexpage_note [shape=note,style=filled,fillcolor=gold,label="Satisfies\nmemory\naccess"]; 117 118 MappedFlexpage -> MappedFlexpage_note [dir=none,style=dotted]; 119 } 120 121 subgraph { 122 rank=same; 123 124 Regions [shape=record,label="Regions | 125 {<s> stack |<sd> stack-dataspace } | 126 {<d> data | <dd> data-dataspace } | 127 {<c> code |<cd> code-dataspace } |..."]; 128 129 L4Re [shape=ellipse,label="L4Re paging\nfunctionality"]; 130 L4Re_note [shape=note,style=filled,fillcolor=gold,label="Supports normal\naccess to file content"]; 131 132 L4Re -> L4Re_note [dir=none,style=dotted]; 133 134 Flexpage [shape=note]; 135 } 136 137 subgraph { 138 rank=same; 139 140 ResourceD [label="Resource\n(Pager)"]; 141 ResourceD_note [shape=note,style=filled,fillcolor=gold,label="Provides access\nto file content"]; 142 143 ResourceD -> ResourceD_note [dir=none,style=dotted]; 144 } 145 146 ProgramFile [shape=record,label="Program File | ... |<d> data |<c> code | ..."]; 147 148 /* Page fault handling. */ 149 150 TaskMemory:d -> ExternalPager [label="page fault"]; 151 152 ExternalPager -> Regions:d [label="find region"]; 153 154 Regions:dd -> ResourceD [style=dashed]; 155 156 ExternalPager -> L4Re; 157 L4Re -> ResourceD [label="map"]; 158 159 ResourceD -> ProgramFile:d [style=dashed]; 160 161 ResourceD -> Flexpage [dir=none]; 162 Flexpage -> ExternalPager; 163 164 ExternalPager -> MappedFlexpage [dir=none]; 165 MappedFlexpage -> TaskMemory:d; 166 } 167 }}} 168 169 ######## 170 171 == Configuring Programs == 172 173 To provide an internal page fault handler alongside an actual program to be 174 run, the following arrangement is used: 175 176 ######## A graph showing the configuration arrangement 177 178 {{{#!graphviz 179 #format svg 180 #transform notugly 181 digraph program_configuration { 182 node [fontsize="12.0",fontname="sans-serif",shape=box]; 183 edge [fontsize="12.0",fontname="sans-serif"]; 184 rankdir=LR; 185 186 subgraph { 187 rank=min; 188 189 CreatingTask_note [shape=note,style=filled,fillcolor=gold,label="Responsible for\ncreating the\nnew task"]; 190 CreatingTask [label="Creating task"]; 191 192 CreatingTask_note -> CreatingTask [dir=none,style=dotted]; 193 } 194 195 subgraph { 196 rank=max; 197 198 IPCGate_note [shape=note,style=filled,fillcolor=gold,label="Created for sharing\nbetween the tasks"]; 199 IPCGate [shape=octagon,label="IPC gate"]; 200 201 IPCGate_note -> IPCGate [dir=none,style=dotted]; 202 } 203 204 InitCaps [shape=record,label="<head> Initial capabilities | {<s> \"server\" |<c> capability }"]; 205 206 subgraph { 207 rank=same; 208 209 InternalPager; 210 InternalPager_note [shape=note,style=filled,fillcolor=gold,label="Starts and binds\nto IPC gate"]; 211 212 InternalPager -> InternalPager_note [dir=none,style=dotted]; 213 214 Program; 215 Program_note [shape=note,style=filled,fillcolor=gold,label="Starts and references\npager via IPC gate"]; 216 217 Program -> Program_note [dir=none,style=dotted]; 218 } 219 220 /* Create and transfer IPC gate for binding. */ 221 222 CreatingTask -> IPCGate [label="create"]; 223 CreatingTask -> InitCaps:head [label="define"]; 224 InitCaps:c -> IPCGate; 225 226 /* Thread initiation. */ 227 228 CreatingTask -> InternalPager [label="start"]; 229 InternalPager -> InitCaps:s [label="bind"]; 230 231 CreatingTask -> Program [label="start"]; 232 Program -> IPCGate -> InternalPager [style=dashed]; 233 } 234 }}} 235 236 ########