# HG changeset patch # User tobaru # Date 1581142010 -32400 # Node ID 98cee2f6c9198fe1163ab05773e45810cb767baf # Parent afc36230cf4f79cb2ddbbaad8d37a2825fcefd8c slide diff -r afc36230cf4f -r 98cee2f6c919 paper/cbc_interface.tex --- a/paper/cbc_interface.tex Fri Feb 07 20:06:13 2020 +0900 +++ b/paper/cbc_interface.tex Sat Feb 08 15:06:50 2020 +0900 @@ -29,7 +29,7 @@ \lstinputlisting[label=interface, caption={\footnotesize vm のインターフェースの定義(vm.h)}]{./src/vm.h} -1行目ので実装名を定義している。 +1行目で実装名を定義している。 typedef struct の直後に実装名(vm)を書く。 @@ -45,6 +45,7 @@ \_\_code next(...) の引数 ... は複数の Input Data Gear を持つという意味である。 後述する実装によって条件分岐によって複数の継続先が設定されることがある。 +それぞれの Code Gear の引数の1つに設定する。引数の最後に設定しているが遷移先で引数を受け取る順番が正しければよい。 Code Gaer は 20行目から33行目のように "\_\_code [Code Gear名]([引数])"で定義する。 @@ -64,13 +65,13 @@ \lstinputlisting[frame=lrbt,label=impl_vm,caption={\footnotesize vm インターフェースの実装}]{./src/vm_impl.cbc} -2行目のようにインターフェースのヘッダーファイルは \#interface で呼び出す。 +2行目のようにインターフェースのヘッダーファイルは \#include ではなく \#interface で呼び出す。 -create\_impl の関数内で、インターフェースを vm で定義し、23行目の vm-$>$void\_ret のようにそれぞれのインターフェースに対応させていく。 +create\_impl の関数内で、インターフェースを vm で定義し、23行目の vm-$>$void\_ret のようにそれぞれの Code Gear 名に対応させていく。 -CbCは1つ1つの関数の信頼性を保障させるために細かくする必要があるので、for文やif文がある場合はさらに実装を分ける。vm と同じように vm\_impl を定義し、遷移する関数名に対応させていく。分けた実装はさらに別で実装する(vm\_impl\_private.cbc)。 +CbCは1つ1つの Code Gear の信頼性を保障させるために細かくする必要があるので、for文やif文がある場合はさらに実装を分ける。vm と同じように vm\_impl を定義し、遷移する関数名に対応させていく。分けた実装はさらに別で実装する(vm\_impl\_private.cbc)。 % インターフェースを呼び出す場合は、struct vm* vm = createvm_impl(cbc_context); @@ -89,7 +90,6 @@ この Code Gear は基本的にインターフェースで指定された Code Gear 内からのみ継続されるため、 Java の private メソッドのように扱われる。 - インターフェースと同じようにヘッダーファイルをソースコード \ref{impl_vm_privateh} で定義する。 @@ -279,8 +279,10 @@ \end{lstlisting} +for文から末尾再起の変換について +static なものに関しては後々実装する \section{インターフェースの呼び出し} @@ -295,9 +297,9 @@ ソースコードの説明 +- dummy を使って解決する - diff -r afc36230cf4f -r 98cee2f6c919 paper/master_paper.log --- a/paper/master_paper.log Fri Feb 07 20:06:13 2020 +0900 +++ b/paper/master_paper.log Sat Feb 08 15:06:50 2020 +0900 @@ -1,4 +1,4 @@ -This is e-pTeX, Version 3.14159265-p3.8.2-190131-2.6 (utf8.euc) (TeX Live 2019) (preloaded format=platex 2020.1.16) 7 FEB 2020 20:05 +This is e-pTeX, Version 3.14159265-p3.8.2-190131-2.6 (utf8.euc) (TeX Live 2019) (preloaded format=platex 2020.1.16) 8 FEB 2020 10:31 entering extended mode restricted \write18 enabled. file:line:error style messages enabled. @@ -489,4 +489,4 @@ 107 hyphenation exceptions out of 8191 33i,11n,36p,410b,1835s stack positions out of 5000i,500n,10000p,200000b,80000s -Output written on master_paper.dvi (56 pages, 243800 bytes). +Output written on master_paper.dvi (56 pages, 243796 bytes). diff -r afc36230cf4f -r 98cee2f6c919 paper/master_paper.pdf Binary file paper/master_paper.pdf has changed diff -r afc36230cf4f -r 98cee2f6c919 paper/master_paper.synctex.gz Binary file paper/master_paper.synctex.gz has changed diff -r afc36230cf4f -r 98cee2f6c919 slide/CbCXv6.html --- a/slide/CbCXv6.html Fri Feb 07 20:06:13 2020 +0900 +++ b/slide/CbCXv6.html Sat Feb 08 15:06:50 2020 +0900 @@ -34,10 +34,10 @@ -

CbCインターフェースによる CbCXv6 の書き換え


目次

  1. OS の信頼性の保証
  2. CbC による Gears OS の開発
  3. Xv6
  4. @@ -132,7 +132,7 @@

    Geas OS


    メモリ管理


    メモリ管理


    目次

      +

      目次

      1. OS の信頼性の保証
      2. CbC による Gears OS の開発
      3. Xv6
      4. @@ -161,7 +161,7 @@
      5. a

      6. Context

        • a
        • -

        目次

          +

          目次

          1. OS の信頼性の保証
          2. CbC による Gears OS の開発
          3. Xv6
          4. @@ -169,7 +169,7 @@
          5. CbC インターフェース
          6. 評価
          7. まとめ
          8. -

          Xv6

            +

        Xv6

        • MIT の講義用教材として作られたOS
          • 企画課される前のCで書かれたUNIX V6 を書き換えた
          • @@ -203,12 +203,12 @@
          • ハードウェアが一時的に特権レベルをあげ、カーネルのプログラムが実行される
        • -

        system call

          +

        system call

        • system call 呼び出し
        • トラップ の発生
        • ユーザープログラムの中断
        • 処理がカーネルに切り替わる
        • -

        system call

          +

        system call

        • ソースコード載せる

        Xv6-rpi

        • Xv6 は Arm のバイナリを出力するので様々なハードウェアで動かすことができる @@ -222,7 +222,7 @@
        • CbCxv6 とは別
        -

        目次

          +

          目次

          1. OS の信頼性の保証
          2. CbC による Gears OS の開発
          3. Xv6
          4. @@ -230,7 +230,7 @@
          5. CbC インターフェース
          6. 評価
          7. まとめ
          8. -

          CbCXv6 での Paging

            +

        CbCXv6 での Paging

        • OS の信頼性の1つであるメモリ管理部分の書き換えについて説明

        実メモリの直接操作

        • 実メモリを直接扱うと様々な問題が生じる @@ -243,7 +243,7 @@
        -

        Paging

          +

        Paging

        • メモリ管理の手法
        • Page と呼ばれる固定長のブロックに分割して、メモリとスワップ領域で Page を入れ替えて管理
        • 仮想メモリとして扱うことでフラグメンテーションの解消と空き番地を探す必要がなくなる
        • @@ -262,15 +262,318 @@

        Paging の書き換え

        • Xv6 では実メモリから仮想メモリの変換をvm.cで行なっている。
        • 次の章で書き換えについて説明する
        • -

        目次

          +

          目次

          1. OS の信頼性の保証
          2. CbC による Gears OS の開発
          3. Xv6
          4. -
          5. CbCXv6 での Paging**
          6. +
          7. CbCXv6 での Paging
          8. CbC インターフェース
          9. 評価
          10. まとめ
          11. -

+

CbC インターフェースの導入


CbC インターフェース


インターフェースの定義


インターフェースのソースコード


実装名の定義

typedef struct vm<Type,Impl> {
+

Data Gear の定義

typedef struct vm<Type,Impl> {
+    union Data* vm;
+    uint low;
+    uint hi;
+    struct proc* p;
+....
+

Code Gear の定義

    __code init_vmm(Impl* vm, __code next(...));
+    __code kpt_freerange(Impl* vm, uint low, uint hi, __code next(...));
+    __code kpt_alloc(Impl* vm ,__code next(...));
+    __code switchuvm(Impl* vm ,struct proc* p, __code next(...));
+    __code init_inituvm(Impl* vm, pde_t* pgdir, char* init, uint sz, __code next(...));
+    __code loaduvm(Impl* vm,pde_t* pgdir, char* addr, struct inode* ip, uint offset, uint sz,  __code next(...));
+    __code allocuvm(Impl* vm, pde_t* pgdir, uint oldsz, uint newsz, __code next(...));
+
+....
+
+

next(…)

    __code kpt_freerange(Impl* vm, uint low, uint hi, __code next(...));
+....
+    __code next(...);
+} vm;
+

インターフェースの実装

#include "../../context.h"
+#interface "vm.h"
+
+

create_impl


+vm* createvm_impl(struct Context* cbc_context) {
+    struct vm* vm  = new vm();
+....
+    vm->void_ret  = C_vm_void_ret;
+    vm->init_vmm = C_init_vmmvm_impl;
+    vm->kpt_freerange = C_kpt_freerangevm_impl;
+    vm->kpt_alloc = C_kpt_allocvm_impl;
+...
+__code init_vmmvm_impl(struct vm_impl* vm,__code next(...)) {
+    initlock(&kpt_mem.lock, "vm");
+    kpt_mem.freelist = NULL;
+
+    goto next(...);
+}
+

private

int loaduvm (pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz)
+{
+    uint i, pa, n;
+    pte_t *pte;
+
+    if ((uint) addr % PTE_SZ != 0) {
+        panic("loaduvm: addr must be page aligned");
+    }
+
+    for (i = 0; i < sz; i += PTE_SZ) {
+        if ((pte = walkpgdir(pgdir, addr + i, 0)) == 0) {
+            panic("loaduvm: address should exist");
+        }
+
+        pa = PTE_ADDR(*pte);
+
+        if (sz - i < PTE_SZ) {
+            n = sz - i;
+        } else {
+            n = PTE_SZ;
+        }
+
+        if (readi(ip, p2v(pa), offset + i, n) != n) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+

goto private

vm* createvm_impl(struct Context* cbc_context) {
+...
+    struct vm_impl* vm_impl = new vm_impl();
+...
+    vm_impl->loaduvm_ptesize_check = C_loaduvm_ptesize_checkvm_impl;
+....
+    vm->loaduvm = C_loaduvmvm_impl;
+....
+}
+
+__code loaduvmvm_impl(struct vm_impl* vm, pde_t* pgdir, char* addr, struct inode* ip, uint offset, uint sz,  __code next(...)) {
+    Gearef(cbc_context, vm_impl)->pgdir = pgdir;
+    Gearef(cbc_context, vm_impl)->addr = addr;
+    Gearef(cbc_context, vm_impl)->ip = ip;
+    Gearef(cbc_context, vm_impl)->offset = offset;
+    Gearef(cbc_context, vm_impl)->sz = sz;
+    Gearef(cbc_context, vm_impl)->next = next;
+
+    goto loaduvm_ptesize_checkvm_impl(vm, next(...));
+}
+

private のヘッダー

typedef struct vm_impl<Impl, Isa> impl vm{
+...
+    __code loaduvm_ptesize_check(Type* vm_impl, uint i, pte_t* pte, uint sz,
+__code next(int ret, ...));
+

private の記述

#interface "vm_impl.h"
+
+__code loaduvm_ptesize_checkvm_impl(struct vm_impl* vm_impl, __code next(int ret, ...)) {
+    char* addr = vm_impl->addr;
+
+    if ((uint) addr %PTE_SZ != 0) {
+       // goto panic
+    }
+
+    goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
+}
+

__code loaduvm_loopvm_impl(struct vm_impl* vm_impl, __code next(int ret, ...)) {
+    uint i = vm_impl->i;
+    uint sz = vm_impl->sz;
+
+    if (i < sz) {
+        goto loaduvm_check_pgdir(vm_impl, next(ret, ...));
+    }
+
+    goto loaduvm_exit(vm_impl, next(ret, ...));
+}
+
+
+__code loaduvm_check_pgdir(struct vm_impl* vm_impl, __code next(int ret, ...)) {
+    pte_t* pte = vm_impl->pte;
+    pde_t* pgdir = vm_impl->pgdir;
+    uint i = vm_impl->i;
+    char* addr = vm_impl->addr;
+    uint pa = vm_impl->pa;
+
+    if ((pte = walkpgdir(pgdir, addr + i, 0)) == 0) {
+        // goto panic
+    }
+    pa = PTE_ADDR(*pte);
+
+    vm_impl->pte = pte;
+    vm_impl->pgdir = pgdir;
+    vm_impl->addr = addr;
+    vm_impl->pa = pa;
+
+    goto loaduvm_check_PTE_SZ(vm_impl, next(ret, ...));
+}
+
+__code loaduvm_check_PTE_SZ(struct vm_impl* vm_impl, __code next(int ret, ...)) {
+    uint sz = vm_impl->sz;
+    uint i = vm_impl->i;
+    uint n = vm_impl->n;
+    struct inode* ip = vm_impl->ip;
+    uint pa = vm_impl->pa;
+    uint offset = vm_impl->offset;
+
+    if (sz - i < PTE_SZ) {
+        n = sz - i;
+    } else {
+        n = PTE_SZ;
+    }
+
+    if (readi(ip, p2v(pa), offset + i, n) != n) {
+        ret = -1;
+        goto next(ret, ...);
+    }
+
+    vm_impl->n = n;
+
+    goto loaduvm_loopvm_impl(vm_impl, next(ret, ...));
+}
+
+__code loaduvm_exit(struct vm_impl* vm_impl, __code next(int ret, ...)) {
+    ret = 0;
+    goto next(ret, ...);
+}
+

+int loaduvm (pde_t *pgdir, char *addr, struct inode *ip, uint offset, uint sz)
+{
+    uint i, pa, n;
+    pte_t *pte;
+
+    if ((uint) addr % PTE_SZ != 0) {
+        panic("loaduvm: addr must be page aligned");
+    }
+
+    for (i = 0; i < sz; i += PTE_SZ) {
+        if ((pte = walkpgdir(pgdir, addr + i, 0)) == 0) {
+            panic("loaduvm: address should exist");
+        }
+
+        pa = PTE_ADDR(*pte);
+
+        if (sz - i < PTE_SZ) {
+            n = sz - i;
+        } else {
+            n = PTE_SZ;
+        }
+
+        if (readi(ip, p2v(pa), offset + i, n) != n) {
+            return -1;
+        }
+    }
+
+    return 0;
+}
+

インターフェースの呼び出し

void userinit(void)
+{ 
+    struct proc* p;
+    extern char _binary_initcode_start[], _binary_initcode_size[];
+
+    p = allocproc();
+    initContext(&p->cbc_context);
+
+    initproc = p;
+
+    if((p->pgdir = kpt_alloc()) == NULL) {
+        panic("userinit: out of memory?");
+    }
+
+    goto cbc_init_vmm_dummy(&p->cbc_context, p, p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
+    p->sz = PTE_SZ;
+
+    // craft the trapframe as if
+    memset(p->tf, 0, sizeof(*p->tf));
+~                                          
+

呼び出しの解決

void dummy(struct proc *p, char _binary_initcode_start[], char _binary_initcode_size[])
+{ 
+    // inituvm(p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
+    goto cbc_init_vmm_dummy(&p->cbc_context, p, p->pgdir, _binary_initcode_start, (int)_binary_initcode_size);
+
+}
+
+
+
+__ncode cbc_init_vmm_dummy(struct Context* cbc_context, struct proc* p, pde_t* pgdir, char* init, uint sz){//:skip
+
+    struct vm* vm = createvm_impl(cbc_context);
+    // goto vm->init_vmm(vm, pgdir, init, sz , vm->void_ret);
+        Gearef(cbc_context, vm)->vm = (union Data*) vm;
+        Gearef(cbc_context, vm)->pgdir = pgdir;
+        Gearef(cbc_context, vm)->init = init;
+        Gearef(cbc_context, vm)->sz = sz ;
+        Gearef(cbc_context, vm)->next = C_vm_void_ret ;
+    goto meta(cbc_context, vm->init_inituvm);
+}
+
+
+void userinit(void)
+{
+    struct proc* p;
+    extern char _binary_initcode_start[], _binary_initcode_size[];
+
+    p = allocproc();
+    initContext(&p->cbc_context);
+
+    initproc = p;
+
+    if((p->pgdir = kpt_alloc()) == NULL) {
+        panic("userinit: out of memory?");
+    }
+
+    dummy(p, _binary_initcode_start, _binary_initcode_size);
+~                                                            
+
+