8
|
1 \chapter{CbC インターフェース}
|
|
2
|
|
3 構造図書く(今のcbcxv6と同じか確認してから)
|
|
4 \par
|
|
5
|
|
6
|
|
7 Gears OS では Meta Code Gear で Context から値を取り出し、ノーマルレベルの Code Gear に値を渡す。
|
|
8 しかし、Code Gaer がどの Data Gear の番号に対応するかを指定する必要があったり、 % ぱるすさんコード必要?
|
|
9 ノーマルレベルとメタレベルで見え方が異なる Data Gear を Meta Code Gear によって 調整する必要があったりと、 % みつきさん
|
|
10 メタレベルからノーマルレベルの継続の記述が煩雑になるため、Interface 化をしている。
|
|
11 Interface は Data Gear に対しての操作を行う Code Gear であり、実装は別で定義する。
|
|
12 % Interface で定義した Code Gear に
|
|
13
|
|
14
|
|
15 % Xv6 の書き換えは Interface を用いてモジュール化する。
|
|
16 そうすることで Gears OS の機能を置き換えることできるようになる。
|
|
17
|
|
18
|
|
19
|
|
20 \section{インターフェースの定義}
|
|
21 インターフェースはある Data Gear の定義と、
|
|
22 それに対する操作を行う Code Gear の集合を表現する Meta Data Gear である。
|
|
23 Context では全ての Code Gaer と Data Gear の集合を表現していることに対し、
|
|
24 インターフェースは一部の Code Gear と一部の Data Gear の集合を表現する。
|
|
25 \par
|
|
26 インターフェースを記述することによってノーマルレベルとメタレベルの分離が可能となる。
|
|
27
|
|
28 Paging のインターフェースを記述したコードを \ref{interface} に示す。
|
|
29
|
|
30
|
|
31 \begin{lstlisting}[frame=lrbt,label=interface,caption={\footnotesize vm のインターフェース}]
|
|
32 typedef struct vm<Type,Impl> {
|
|
33 union Data* vm;
|
|
34 uint low;
|
|
35 uint hi;
|
|
36 struct proc* p;
|
|
37 pde_t* pgdir;
|
|
38 char* init;
|
|
39 uint sz;
|
|
40 char* addr;
|
|
41 struct inode* ip;
|
|
42 uint offset;
|
|
43 uint oldsz;
|
|
44 uint newsz;
|
|
45 char* uva;
|
|
46 uint va;
|
|
47 void* pp;
|
|
48 uint len;
|
|
49 uint phy_low;
|
|
50 uint phy_hi;
|
|
51 __code init_vmm(Impl* vm, __code next(...));
|
|
52 __code kpt_freerange(Impl* vm, uint low, uint hi, __code next(...));
|
|
53 __code kpt_alloc(Impl* vm ,__code next(...));
|
|
54 __code switchuvm(Impl* vm ,struct proc* p, __code next(...));
|
|
55 __code init_inituvm(Impl* vm, pde_t* pgdir, char* init, uint sz, __code next(...));
|
|
56 __code loaduvm(Impl* vm,pde_t* pgdir, char* addr, struct inode* ip, uint offset, uint sz, __code next(...));
|
|
57 __code allocuvm(Impl* vm, pde_t* pgdir, uint oldsz, uint newsz, __code next(...));
|
|
58 __code clearpteu(Impl* vm, pde_t* pgdir, char* uva, __code next(...));
|
|
59 __code copyuvm(Impl* vm, pde_t* pgdir, uint sz, __code next(...));
|
|
60 __code uva2ka(Impl* vm, pde_t* pgdir, char* uva, __code next(...));
|
|
61 __code copyout(Impl* vm, pde_t* pgdir, uint va, void* pp, uint len, __code next(...));
|
|
62 __code paging_int(Impl* vm, uint phy_low, uint phy_hi, __code next(...));
|
|
63 __code void_ret(Impl* vm);
|
|
64 __code next(...);
|
|
65 } vm;
|
|
66 \end{lstlisting}
|
|
67
|
|
68
|
|
69 \par
|
|
70 2行目から19行目で引数の Data Gear 郡を定義している。
|
|
71 初期化された Data Gear が Code Gear の引数として扱われる。
|
|
72 例として、2行目で定義された vm が21行目から32行目までの引数と対応している。
|
|
73 \par
|
|
74 % インターフェースの Code Gear の goto による継続先は基本的に不定となっており、継続元から渡される。
|
|
75 \_\_code next(...) の引数 ... は複数の Input Data Gear を持つという意味である。
|
|
76 後述する実装によって条件分岐によって複数の継続先が設定されることがある。
|
|
77 \par
|
|
78 Code Gaer は 20行目から33行目のように "\_\_code [Code Gear名]([引数])"で定義する。
|
|
79 この引数が input Data Gear になる。
|
|
80
|
|
81
|
|
82 % 実装側に書く
|
|
83 % 引数の Data Gear はその Code Gear の Input Data Gear になり、引数の Code Gear の中の引 数が Output Data Gear になる。Code Gear の第一引数には Interface を実装した Data Gear を渡す。これは、Code Gear の操作の対象となる Data Gear を設定し ており、後述する継続構文では引数として記述を行わない。
|
|
84
|
|
85
|
|
86 \section{インターフェースの実装}
|
|
87 インターフェースは Data Gear に対しての Code Gear とその Code Gear で扱われている Data Gear の集合を抽象化した Meta Data Gear で、vm.c に対応する実装は別で定義する。
|
|
88 \par
|
|
89
|
|
90
|
|
91
|
|
92
|
|
93 \begin{lstlisting}[frame=lrbt,label=impl_vm,caption={\footnotesize vm インターフェースの実装}]
|
|
94 #include "../../context.h"
|
|
95 #interface "vm.h"
|
|
96
|
|
97 vm* createvm_impl(struct Context* cbc_context) {
|
|
98 struct vm* vm = new vm();
|
|
99 struct vm_impl* vm_impl = new vm_impl();
|
|
100 vm->vm = (union Data*)vm_impl;
|
|
101 vm_impl->vm_impl = NULL;
|
|
102 vm_impl->i = 0;
|
|
103 vm_impl->pte = NULL;
|
|
104 vm_impl->sz = 0;
|
|
105 vm_impl->loaduvm_ptesize_check = C_loaduvm_ptesize_checkvm_impl;
|
|
106 vm_impl->loaduvm_loop = C_loaduvm_loopvm_impl;
|
|
107 vm_impl->allocuvm_check_newsz = C_allocuvm_check_newszvm_impl;
|
|
108 vm_impl->allocuvm_loop = C_allocuvm_loopvm_impl;
|
|
109 vm_impl->copyuvm_check_null = C_copyuvm_check_nullvm_impl;
|
|
110 vm_impl->copyuvm_loop = C_copyuvm_loopvm_impl;
|
|
111 vm_impl->uva2ka_check_pe_types = C_uva2ka_check_pe_types;
|
|
112 vm_impl->paging_intvm_impl = C_paging_intvmvm_impl;
|
|
113 vm_impl->copyout_loopvm_impl = C_copyout_loopvm_impl;
|
|
114 vm_impl->switchuvm_check_pgdirvm_impl = C_switchuvm_check_pgdirvm_impl;
|
|
115 vm_impl->init_inituvm_check_sz = C_init_inituvm_check_sz;
|
|
116 vm->void_ret = C_vm_void_ret;
|
|
117 vm->init_vmm = C_init_vmmvm_impl;
|
|
118 vm->kpt_freerange = C_kpt_freerangevm_impl;
|
|
119 vm->kpt_alloc = C_kpt_allocvm_impl;
|
|
120 vm->switchuvm = C_switchuvmvm_impl;
|
|
121 vm->init_inituvm = C_init_inituvmvm_impl;
|
|
122 vm->loaduvm = C_loaduvmvm_impl;
|
|
123 vm->allocuvm = C_allocuvmvm_impl;
|
|
124 vm->clearpteu = C_clearpteuvm_impl;
|
|
125 vm->copyuvm = C_copyuvmvm_impl;
|
|
126 vm->uva2ka = C_uva2kavm_impl;
|
|
127 vm->copyout = C_copyoutvm_impl;
|
|
128 vm->paging_int = C_paging_intvm_impl;
|
|
129 return vm;
|
|
130 }
|
|
131 extern struct {
|
|
132 struct spinlock lock;
|
|
133 struct run *freelist;
|
|
134 } kpt_mem;
|
|
135
|
|
136 __code init_vmmvm_impl(struct vm_impl* vm,__code next(...)) {
|
|
137 initlock(&kpt_mem.lock, "vm");
|
|
138 kpt_mem.freelist = NULL;
|
|
139
|
|
140 goto next(...);
|
|
141 }
|
|
142
|
|
143 extern struct run {
|
|
144 struct run *next;
|
|
145 };
|
|
146
|
|
147 static void _kpt_free (char *v)
|
|
148 {
|
|
149 struct run *r;
|
|
150
|
|
151 r = (struct run*) v;
|
|
152 r->next = kpt_mem.freelist;
|
|
153 kpt_mem.freelist = r;
|
|
154 }
|
|
155
|
|
156 __code kpt_freerangevm_impl(struct vm_impl* vm, uint low, uint hi, __code next(...)) {
|
|
157
|
|
158 if (low < hi) {
|
|
159 _kpt_free((char*)low);
|
|
160 goto kpt_freerangevm_impl(vm, low + PT_SZ, hi, next(...));
|
|
161
|
|
162 }
|
|
163 goto next(...);
|
|
164 }
|
|
165
|
|
166 __code kpt_allocvm_impl(struct vm_impl* vm, __code next(...)) {
|
|
167 acquire(&kpt_mem.lock);
|
|
168
|
|
169 goto kpt_alloc_check_impl(vm_impl, next(...));
|
|
170 }
|
|
171
|
|
172 typedef struct proc proc;
|
|
173 __code switchuvmvm_impl(struct vm_impl* vm , struct proc* p, __code next(...)) { //:skip
|
|
174
|
|
175 goto switchuvm_check_pgdirvm_impl(...);
|
|
176 }
|
|
177
|
|
178 __code init_inituvmvm_impl(struct vm_impl* vm, pde_t* pgdir, char* init, uint sz, __code next(...)) {
|
|
179
|
|
180 Gearef(cbc_context, vm_impl)->pgdir = pgdir;
|
|
181 Gearef(cbc_context, vm_impl)->init = init;
|
|
182 Gearef(cbc_context, vm_impl)->sz = sz;
|
|
183 Gearef(cbc_context, vm_impl)->next = next;
|
|
184 goto init_inituvm_check_sz(vm, pgdir, init, sz, next(...));
|
|
185 }
|
|
186
|
|
187 __code loaduvmvm_impl(struct vm_impl* vm, pde_t* pgdir, char* addr, struct inode* ip, uint offset, uint sz, __code next(...)) {
|
|
188 Gearef(cbc_context, vm_impl)->pgdir = pgdir;
|
|
189 Gearef(cbc_context, vm_impl)->addr = addr;
|
|
190 Gearef(cbc_context, vm_impl)->ip = ip;
|
|
191 Gearef(cbc_context, vm_impl)->offset = offset;
|
|
192 Gearef(cbc_context, vm_impl)->sz = sz;
|
|
193 Gearef(cbc_context, vm_impl)->next = next;
|
|
194
|
|
195 goto loaduvm_ptesize_checkvm_impl(vm, next(...));
|
|
196 }
|
|
197
|
|
198 __code allocuvmvm_impl(struct vm_impl* vm, pde_t* pgdir, uint oldsz, uint newsz, __code next(...)) {
|
|
199
|
|
200 goto allocuvm_check_newszvm_impl(vm, pgdir, oldsz, newsz, next(...));
|
|
201 }
|
|
202
|
|
203 __code clearpteuvm_impl(struct vm_impl* vm, pde_t* pgdir, char* uva, __code next(...)) {
|
|
204
|
|
205 goto clearpteu_check_ptevm_impl(vm, pgdir, uva, next(...));
|
|
206 }
|
|
207
|
|
208 __code copyuvmvm_impl(struct vm_impl* vm, pde_t* pgdir, uint sz, __code next(...)) {
|
|
209
|
|
210 goto copyuvm_check_nullvm_impl(vm, pgdir, sz, __code next(...));
|
|
211 }
|
|
212
|
|
213 __code uva2kavm_impl(struct vm_impl* vm, pde_t* pgdir, char* uva, __code next(...)) {
|
|
214
|
|
215 goto uva2ka_check_pe_types(vm, pgdir, uva, next(...));
|
|
216 }
|
|
217
|
|
218 __code copyoutvm_impl(struct vm_impl* vm, pde_t* pgdir, uint va, void* pp, uint len, __code next(...)) {
|
|
219
|
|
220 vm->buf = (char*) pp;
|
|
221
|
|
222 goto copyout_loopvm_impl(vm, pgdir, va, pp, len, va0, pa0, next(...));
|
|
223 }
|
|
224
|
|
225 __code paging_intvm_impl(struct vm_impl* vm, uint phy_low, uint phy_hi, __code next(...)) {
|
|
226
|
|
227 goto paging_intvmvm_impl(vm, phy_low, phy_hi, next(...));
|
|
228 }
|
|
229
|
|
230 __code vm_void_ret(struct vm_impl* vm) {
|
|
231 return;
|
|
232 }
|
|
233
|
|
234
|
|
235 \end{lstlisting}
|
|
236
|
|
237
|
|
238 \section{インターフェース内の private メソッド}
|
|
239 インターフェースで定義した Code Gear 以外の Code Gaer も記述することができる。
|
|
240 この Code Gear は基本的にインターフェースで指定された Code Gear 内からのみ継続されるため、
|
|
241 Java の private メソッドのように扱われる。
|
|
242
|
|
243
|
|
244
|
|
245 \begin{lstlisting}[frame=lrbt,label=impl_vm_privateh,caption={\footnotesize vm private のヘッダーファイル}]
|
|
246
|
|
247 typedef struct vm_impl<Impl, Isa> impl vm{
|
|
248 union Data* vm_impl;
|
|
249 uint i;
|
|
250 pte_t* pte;
|
|
251 uint sz;
|
|
252 pde_t* pgdir;
|
|
253 char* addr;
|
|
254 struct inode* ip;
|
|
255 uint offset;
|
|
256 uint pa;
|
|
257 uint n;
|
|
258 uint oldsz;
|
|
259 uint newsz;
|
|
260 uint a;
|
|
261 int ret;
|
|
262 char* mem;
|
|
263 char* uva;
|
|
264 pde_t* d;
|
|
265 uint ap;
|
|
266 uint phy_low;
|
|
267 uint phy_hi;
|
|
268 uint va;
|
|
269 void* pp;
|
|
270 uint len;
|
|
271 char* buf;
|
|
272 char* pa0;
|
|
273 uint va0;
|
|
274 proc_struct* p;
|
|
275 char* init;
|
|
276
|
|
277 __code kpt_alloc_check_impl(Type* vm_impl, __code next(...));
|
|
278 __code loaduvm_ptesize_check(Type* vm_impl, __code next(int ret, ...));
|
|
279 __code loaduvm_loop(Type* vm_impl, uint i, pte_t* pte, uint sz, __code next(int ret, ...));
|
|
280 __code allocuvm_check_newsz(Type* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, __code next(...));
|
|
281 __code allocuvm_loop(Type* vm_impl, pde_t* pgdir, uint oldsz, uint newsz, uint a, __code next(...));
|
|
282 __code copyuvm_check_null(Type* vm_impl, pde_t* pgdir, uint sz, __code next(...));
|
|
283 __code copyuvm_loop(Type* vm_impl,pde_t* pgdir, uint sz, pde_t* d, pte_t* pte, uint pa, uint i, uint ap, char* mem, __code next(int ret, ...));
|
|
284 __code clearpteu_check_ptevm_impl(Type* vm_impl, pde_t* pgdir, char* uva, __code next(...));
|
|
285 __code uva2ka_check_pe_types(Type* vm_impl, pde_t* pgdir, char* uva, __code next(...));
|
|
286 __code paging_intvm_impl(Type* vm_impl, uint phy_low, uint phy_hi, __code next(...));
|
|
287 __code copyout_loopvm_impl(Type* vm_impl, pde_t* pgdir, uint va, void* pp, uint len, __code next(...));
|
|
288 __code switchuvm_check_pgdirvm_impl(struct vm_impl* vm_impl, struct proc* p, __code next(...));
|
|
289 __code init_inituvm_check_sz(struct vm_impl* vm_impl, pde_t* pgdir, char* init, uint sz, __code next(...));
|
|
290 __code void_ret(Type* vm_impl);
|
|
291 __code next(...);
|
|
292 } vm_impl;
|
|
293
|
|
294 \end{lstlisting}
|
|
295
|
|
296 \begin{lstlisting}[frame=lrbt,label=impl_vm_private,caption={\footnotesize vm private の実装}]
|
|
297 #include "../../context.h"
|
|
298 #interface "vm.h"
|
|
299
|
|
300 vm* createvm_impl(struct Context* cbc_context) {
|
|
301 struct vm* vm = new vm();
|
|
302 struct vm_impl* vm_impl = new vm_impl();
|
|
303 vm->vm = (union Data*)vm_impl;
|
|
304 vm_impl->vm_impl = NULL;
|
|
305 vm_impl->i = 0;
|
|
306 vm_impl->pte = NULL;
|
|
307 vm_impl->sz = 0;
|
|
308 vm_impl->loaduvm_ptesize_check = C_loaduvm_ptesize_checkvm_impl;
|
|
309 vm_impl->loaduvm_loop = C_loaduvm_loopvm_impl;
|
|
310 vm_impl->allocuvm_check_newsz = C_allocuvm_check_newszvm_impl;
|
|
311 vm_impl->allocuvm_loop = C_allocuvm_loopvm_impl;
|
|
312 vm_impl->copyuvm_check_null = C_copyuvm_check_nullvm_impl;
|
|
313 vm_impl->copyuvm_loop = C_copyuvm_loopvm_impl;
|
|
314 vm_impl->uva2ka_check_pe_types = C_uva2ka_check_pe_types;
|
|
315 vm_impl->paging_intvm_impl = C_paging_intvmvm_impl;
|
|
316 vm_impl->copyout_loopvm_impl = C_copyout_loopvm_impl;
|
|
317 vm_impl->switchuvm_check_pgdirvm_impl = C_switchuvm_check_pgdirvm_impl;
|
|
318 vm_impl->init_inituvm_check_sz = C_init_inituvm_check_sz;
|
|
319 vm->void_ret = C_vm_void_ret;
|
|
320 vm->init_vmm = C_init_vmmvm_impl;
|
|
321 vm->kpt_freerange = C_kpt_freerangevm_impl;
|
|
322 vm->kpt_alloc = C_kpt_allocvm_impl;
|
|
323 vm->switchuvm = C_switchuvmvm_impl;
|
|
324 vm->init_inituvm = C_init_inituvmvm_impl;
|
|
325 vm->loaduvm = C_loaduvmvm_impl;
|
|
326 vm->allocuvm = C_allocuvmvm_impl;
|
|
327 vm->clearpteu = C_clearpteuvm_impl;
|
|
328 vm->copyuvm = C_copyuvmvm_impl;
|
|
329 vm->uva2ka = C_uva2kavm_impl;
|
|
330 vm->copyout = C_copyoutvm_impl;
|
|
331 vm->paging_int = C_paging_intvm_impl;
|
|
332 return vm;
|
|
333 }
|
|
334
|
|
335 extern struct {
|
|
336 struct spinlock lock;
|
|
337 struct run *freelist;
|
|
338 } kpt_mem;
|
|
339
|
|
340 __code init_vmmvm_impl(struct vm_impl* vm,__code next(...)) {
|
|
341 initlock(&kpt_mem.lock, "vm");
|
|
342 kpt_mem.freelist = NULL;
|
|
343
|
|
344 goto next(...);
|
|
345 }
|
|
346
|
|
347 extern struct run {
|
|
348 struct run *next;
|
|
349 };
|
|
350
|
|
351 static void _kpt_free (char *v)
|
|
352 {
|
|
353 struct run *r;
|
|
354
|
|
355 r = (struct run*) v;
|
|
356 r->next = kpt_mem.freelist;
|
|
357 kpt_mem.freelist = r;
|
|
358 }
|
|
359
|
|
360 __code kpt_freerangevm_impl(struct vm_impl* vm, uint low, uint hi, __code next(...)) {
|
|
361
|
|
362 if (low < hi) {
|
|
363 _kpt_free((char*)low);
|
|
364 goto kpt_freerangevm_impl(vm, low + PT_SZ, hi, next(...));
|
|
365
|
|
366 }
|
|
367 goto next(...);
|
|
368 }
|
|
369 __code kpt_allocvm_impl(struct vm_impl* vm, __code next(...)) {
|
|
370 acquire(&kpt_mem.lock);
|
|
371
|
|
372 goto kpt_alloc_check_impl(vm_impl, next(...));
|
|
373 }
|
|
374
|
|
375 typedef struct proc proc;
|
|
376 __code switchuvmvm_impl(struct vm_impl* vm , struct proc* p, __code next(...)) { //:skip
|
|
377
|
|
378 goto switchuvm_check_pgdirvm_impl(...);
|
|
379 }
|
|
380
|
|
381 __code init_inituvmvm_impl(struct vm_impl* vm, pde_t* pgdir, char* init, uint sz, __code next(...)) {
|
|
382
|
|
383 Gearef(cbc_context, vm_impl)->pgdir = pgdir;
|
|
384 Gearef(cbc_context, vm_impl)->init = init;
|
|
385 Gearef(cbc_context, vm_impl)->sz = sz;
|
|
386 Gearef(cbc_context, vm_impl)->next = next;
|
|
387 goto init_inituvm_check_sz(vm, pgdir, init, sz, next(...));
|
|
388 }
|
|
389
|
|
390 __code loaduvmvm_impl(struct vm_impl* vm, pde_t* pgdir, char* addr, struct inode* ip, uint offset, uint sz, __code next(...)) {
|
|
391 Gearef(cbc_context, vm_impl)->pgdir = pgdir;
|
|
392 Gearef(cbc_context, vm_impl)->addr = addr;
|
|
393 Gearef(cbc_context, vm_impl)->ip = ip;
|
|
394 Gearef(cbc_context, vm_impl)->offset = offset;
|
|
395 Gearef(cbc_context, vm_impl)->sz = sz;
|
|
396 Gearef(cbc_context, vm_impl)->next = next;
|
|
397
|
|
398 goto loaduvm_ptesize_checkvm_impl(vm, next(...));
|
|
399 }
|
|
400
|
|
401 __code allocuvmvm_impl(struct vm_impl* vm, pde_t* pgdir, uint oldsz, uint newsz, __code next(...)) {
|
|
402
|
|
403 goto allocuvm_check_newszvm_impl(vm, pgdir, oldsz, newsz, next(...));
|
|
404 }
|
|
405
|
|
406 __code clearpteuvm_impl(struct vm_impl* vm, pde_t* pgdir, char* uva, __code next(...)) {
|
|
407
|
|
408 goto clearpteu_check_ptevm_impl(vm, pgdir, uva, next(...));
|
|
409 }
|
|
410
|
|
411 __code copyuvmvm_impl(struct vm_impl* vm, pde_t* pgdir, uint sz, __code next(...)) {
|
|
412
|
|
413 goto copyuvm_check_nullvm_impl(vm, pgdir, sz, __code next(...));
|
|
414 }
|
|
415
|
|
416 __code uva2kavm_impl(struct vm_impl* vm, pde_t* pgdir, char* uva, __code next(...)) {
|
|
417
|
|
418 goto uva2ka_check_pe_types(vm, pgdir, uva, next(...));
|
|
419 }
|
|
420
|
|
421 __code copyoutvm_impl(struct vm_impl* vm, pde_t* pgdir, uint va, void* pp, uint len, __code next(...)) {
|
|
422
|
|
423 vm->buf = (char*) pp;
|
|
424
|
|
425 goto copyout_loopvm_impl(vm, pgdir, va, pp, len, va0, pa0, next(...));
|
|
426 }
|
|
427
|
|
428 __code paging_intvm_impl(struct vm_impl* vm, uint phy_low, uint phy_hi, __code next(...)) {
|
|
429
|
|
430 goto paging_intvmvm_impl(vm, phy_low, phy_hi, next(...));
|
|
431 }
|
|
432
|
|
433 __code vm_void_ret(struct vm_impl* vm) {
|
|
434 return;
|
|
435 }
|
|
436
|
|
437 \end{lstlisting}
|
|
438
|
|
439
|
10
|
440 \section{インターフェースの呼び出し}
|
|
441 CbC の場合 goto による遷移を行うので、関数呼び出しのように goto 以降のコードを実行できない。
|
|
442 例として、\ref{cbc_goto} の16行目のように goto によってインターフェースで定義した命令を行うと、戻ってこれないため17行目以降が実行されなくなる。
|
|
443
|
|
444
|
|
445 \begin{lstlisting}[frame=lrbt,label=cbc_goto,caption={\footnotesize cbc インターフェースのgoto}]
|
|
446
|
|
447 void userinit(void)
|
|
448 {
|
|
449 struct proc* p;
|
|
450 extern char _binary_initcode_start[], _binary_initcode_size[];
|
|
451
|
|
452 p = allocproc();
|
|
453 initContext(&p->cbc_context);
|
|
454
|
|
455 initproc = p;
|
|
456
|
|
457 if((p->pgdir = kpt_alloc()) == NULL) {
|
|
458 panic("userinit: out of memory?");
|
|
459 }
|
|
460
|
|
461 goto cbc_init_vmm_dummy(&p->cbc_context, p, p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
|
|
462 p->sz = PTE_SZ;
|
|
463
|
|
464 // craft the trapframe as if
|
|
465 memset(p->tf, 0, sizeof(*p->tf));
|
|
466
|
|
467
|
|
468 \end{lstlisting}
|
|
469
|
|
470
|
|
471
|
|
472
|
|
473 \begin{lstlisting}[frame=lrbt,label=impl_vm_private,caption={\footnotesize vm private の実装}]
|
|
474
|
|
475
|
|
476 void dummy(struct proc *p, char _binary_initcode_start[], char _binary_initcode_size[])
|
|
477 {
|
|
478 // inituvm(p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
|
|
479 goto cbc_init_vmm_dummy(&p->cbc_context, p, p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
|
|
480
|
|
481 }
|
|
482
|
|
483
|
|
484
|
|
485 __ncode cbc_init_vmm_dummy(struct Context* cbc_context, struct proc* p, pde_t* pgdir, char* init, uint sz){//:skip
|
|
486
|
|
487 struct vm* vm = createvm_impl(cbc_context);
|
|
488 // goto vm->init_vmm(vm, pgdir, init, sz , vm->void_ret);
|
|
489 Gearef(cbc_context, vm)->vm = (union Data*) vm;
|
|
490 Gearef(cbc_context, vm)->pgdir = pgdir;
|
|
491 Gearef(cbc_context, vm)->init = init;
|
|
492 Gearef(cbc_context, vm)->sz = sz ;
|
|
493 Gearef(cbc_context, vm)->next = C_vm_void_ret ;
|
|
494 goto meta(cbc_context, vm->init_inituvm);
|
|
495 }
|
|
496
|
|
497
|
|
498 void userinit(void)
|
|
499 {
|
|
500 struct proc* p;
|
|
501 extern char _binary_initcode_start[], _binary_initcode_size[];
|
|
502
|
|
503 p = allocproc();
|
|
504 initContext(&p->cbc_context);
|
|
505
|
|
506 initproc = p;
|
|
507
|
|
508 if((p->pgdir = kpt_alloc()) == NULL) {
|
|
509 panic("userinit: out of memory?");
|
|
510 }
|
|
511
|
|
512 dummy(p, _binary_initcode_start, _binary_initcode_size);
|
|
513
|
|
514
|
|
515
|
|
516 \end{lstlisting}
|