L4Re/departure

Annotated docs/wiki/Program_Loading

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