JOS 10週目

社会にでるまでに一通り終わらなかった。あとは Lab 6 を残すだけ…

3/28

  • Lab 4 Part C
    • exercise 12,13,14
      • CPUS=2 にすると bad environment で sys_page_map が死ぬ…

3/29

  • Lab 4
    • exercise 14
      • kern/sched.c: uncomment after exercise 13 !!!!
    • exercise 15
      • やるだけ
  • xv6 book chapter 6 File System 読む
    • ファイルシステムはデータの共有、永続化のためのもの
    • must support crash recovery
    • must maintain invariants and an in-memory cache

3/30

  • Lab 5
    • JOS について読む
      • metadata を store する super block が 1つ
      • file struct は direct blocks と indirect blocks (ポインタのポインタ)
      • real file system は double-, triple-indirect blocks をサポートする
      • File System も environment (process) として動いていて RPC でアクセスする
    • exercise 5
      • fs.img をぶっ壊したが make clean を忘れて通らずにハマる
    • exercise 6, 7, 8
    • exercise 8
      • パッとよんで PTE_SHARE がわからん

3/31

  • Lab 5
    • exercise 9
      • pgdir_walk の perm をバグらせていたっぽい…
    • exercise 10
      • やるだけ

高専から東工大に編入して同院に進学して修了した

高専を卒業後に東工大に編入して、同大学院に進学し、最近修了できたのでまとめる。

学部入試〜単位認定

情報工学科に編入した。編入動機や、単位変換のつらさなどは次のエントリに書いた。 itkq.hatenablog.com

大学院入試

東工大の大学院入試には、「A日程」と「B日程」の2つ (非正式名称だが学生教員ともにこれが最も通じる) がある。 A日程とはいわゆる内部進学みたいなもので、成績が良い人から順に研究室のポストを埋めていく形である。A日程試験に筆記はなく面接のみである。 B日程とはいわゆる普通の入試である。筆記試験でボーダーを超えれば面接試験へと進める。

東工大大学院の入試を申し込むと、あなたはA日程またはB日程ですと書かれた書類とともに受験票が郵送で届く。 A日程は、成績が良い順に内部生に与えられると言われているが、ここ数年では他大学にも与えられることもあるようだ。 「成績」が何を指すかは不明瞭である。私はつまるところ専門科目の点数の平均点だと聞いていた。出願時に TOEIC または TOEFL のスコアシートの提出が必須であるが、これらの英語の成績は「成績」にほとんど影響しないという見解が学生間でなされている。

情報工学科から通常進学する先は、「情報理工学院 情報工学系」または「工学院 情報通信系」の研究室である。私の受験した2016年度は、教育改革により大学院が再編成され、「専攻」が廃止され代わりに「系」となった。過渡期であったために、志願先は複数の系 (最大3つまで) のうちの研究室 (最大5つまで) を選択することができた (なお、2018年度現在は複数志願することはできない)。私は、

  1. 情報工学
  2. 情報通信系
  3. 物理情報系 (確かそんなような名前だった)

の順で研究室を選択し出願した。

私の知る限り情報系のA日程の面接試験は形骸化しており、その実態は、成績順に希望研究室を選択する椅子取りゲームである1。 つまり受験票に書いた研究室には何も意味がなく、自分が呼ばれた時点で残っている研究室のポストから1つを選ぶのである。自分が希望した研究室が残っていなくても、他に残っている研究室に納得すればその研究室に内定する。このような受験システムにより、学部と院で所属研究室が異なる内部生が比較的多く発生する。「学部の研究室を継続したい」という希望は全く考慮されない。

私は学部で受けた講義の成績がそこそこ良かったので、A日程の権利を得られると予想していた。そして予想通りA日程の通知が届いた。しかし編入生の場合、単位認定科目は60点として記録されるため、自分が体感する自身の成績と、システム上の「成績」は異なる。これについては次のエントリに書いた。

itkq.hatenablog.com

私が受験室に呼ばれた頃には、受験票に書いた研究室はもちろん、その他ほとんどの研究室のポストがなくなっており、A日程の受験を破棄することにした。A日程で研究室のポストがすべて埋まるわけではないため、B日程での内定の可能性に賭けることにした。

B日程は、まず筆記試験を受験し、その合計点 (+英語スコアシートの点数) が「成績」となる。その「成績」でA日程と同様な面接試験が行われる。私は普通に勉強して臨んだが、頭の悪さがでてしまい出来が良くなかった。私が受験室に呼ばれた頃には第一希望の情報工学系の研究室はほぼ完売だったため、最終的に情報通信系情報通信コースの研究室を選択した。

大学院での授業

学部は編入したとはいえ、大学院に入学してしまえば周りと同じ大学院生になる。そのため授業による単位取得に苦しむことはなかった。

2016年度入学の情報通信コースの修了最低単位数は30である。そのうち8単位は指導教員が評価する研究の単位なので、実質的には授業を受けて22単位を取得すればいいことになる。教育改革により、2016年度からクォーター制となったことを考慮すると、修士1年目で必要単位を取り切るためには、22/4 = 5.5 単位/クォーター が必要で、およそ週に8時間が必要である。この数字はそれほど大きくなく、授業を受けながら週2ほどでバイトを入れて研究を進めるような生活をしていた。

学部と比較すると、試験ではなく提出物で評価する授業が増えたのと、教育改革により一部の講義は英語のみになった (日本人教員も英語を喋らなくてはならない) ぐらいの変化を感じたが、特に支障はなかった。

大学院での研究

大学院卒業すなわち修士修了に必要な研究成果のボーダーは不明瞭である。修論を提出した後、系の教員らによる修了判定会議というものがある。この会議で、修了レベルの研究ではないと判断されると、再提出が要求される。同年度中に卒業するためには、再提出の期限は1ヶ月ほどしかなく、修論の内容ではなくそもそもの研究が不出来だと修了はほぼ不可能である。

各研究室の研究をみていると、その成果レベルはまちまちである。国内の大会で1度発表しただけという人もいれば、何度も国際会議で発表しているという人もいる。研究に求められるレベルは、もちろん学生個人の力量にもよるが、研究室の指導教員が最も左右すると思う。

私の指導教員は、修士1年のうちに研究をほぼ終わらせるというスタンスのもとに指導をしていた。実際私は1年目の秋に国際会議に投稿して、冬には国内で何度か発表をした後に研究の進捗は打ち止めとなった。2年目は国際会議の発表があったり、国内論文誌に研究成果をまとめる活動だけで終わった。

大学院での修了

大学院の修了には、上述したように単位取得・修論提出・修論発表の3つが必須となる。修論については、修了判定会議の後に指導教員が結果を教えてくれる (おそらく。少なくとも私はそうだった)。単位取得については、修了要件を見ながら単位を取るしか方法がなく、自分が取得した単位が修了要件を満たせているかは判定不能である。取得単位を確認できる Web システムでも判定確認はできない。一体どうやって実際に修了判定しているんだ…という気持ちになる。修了要件が満たせていない人には教務から別途連絡が来るらしい [要出典] が、時既に遅しなので留年ということになるので、本当に注意深く修了要件を眺める必要がある。

完走した感想

学部2年間はわりとあっという間で、大学院2年間もあっという間だった。高専5年間が長すぎたのだろう…


  1. 他大学からの受験の場合、面接では志望動機や成績を質問されるようだ。内部生の成績はどのようなレベルの授業に対してどれぐらいの成績なのかという対応がとれる一方で、他大学の授業のレベルは分からないからである。

JOS 8, 9週目

3/11

  • Homework 8 hw08: finish · itkq/jos@8224e02 · GitHub

    • 結構悩んだが結局はヒントをよく読む
      • pushal, popal: register の save と restore
      • current_stack->sp = esp の手順
    • stack を thread のものに切り替えることをする
      • 1回目の thread_switch() が呼ばれる直前 f:id:itkq:20180312024749p:plain
      • 1回目の thread_switch()ret する直前
        • スタックポインタの切り替え
        • コンテキスト (registers) の入れ替え f:id:itkq:20180312024753p:plain
      • 2回目の thread_switch() が呼ばれる直前 f:id:itkq:20180312024756p:plain
      • 2回目の thread_switch()ret する直前
        • 同様 f:id:itkq:20180312025903p:plain
  • homework 9

    • condition variable がなにを指すのかよくわからなくてハマった
    • 要するに pthread_cond_wait() が入っている if もしくは while のブロックの条件のことで、それが真になるまでそのスレッドは待つ

3/12

  • Lab 4
    • exercise 1 ~ exercise 5
      • それほどはむずかしくない

3/13-15

  • Lab4
    • exercise 6 で2日溶かした
      • iteration が上手くいかない、各 CPU が同じ environment を掴んでしまっている?
      • lib/libmain.c で thisenv = envs; という先頭しか掴まないようになっていてビビる、直す
      • これは Lab 3 の領域なので Lab 3 にて make grade すると user/hello.c で失敗
      • sys_getenvid() システムコールがよくわからない値を返していた
      • カーネル空間では動いてるっぽいのでなんだとおもったら kern/syscall.csyscall() の dispatcher に SYS_getenvid の対応を書いてなかった!!!!!!!!!!!!!!!
      • これも直したら通った
    • exercise 7
      • child environment の syscall の引数がおかしい
        • 謎だけど tf をコピーするときに eax, esi にゴミが残っていて死んでたのでクリアした (あってるかは不明)
      • parent が free になったあと halt してる
        • exercise 6 の漏れだった

3/16

  • Lab 4 exercise 8
    • やるだけ

3/17

  • Lab 4 exercise 9
  • esp に eip を置いておくと、handler 内での trap という再帰的な動きにも対応できる。結構悩んだ

3/18

  • exercise 10, 11
    • ページをコピーした dumbfork() とは違って fork() では ページのマッピング をコピーする
    • sys_exofork がよくわかってなかった。eax を 0 にすることで戻り値を 0 にしていた

3/19

  • exercise 12
    • どこかでバグらせていて lib/fork 中で user page fault が起きる、原因がぜんぜんわからん…

3/21-3/24

  • 突然発熱して体調を崩して死んでた

3月13日

6時頃寝た。電話で13時頃起きた。ご飯を食べてから眠かったのでまた寝た。18時頃起きた。

Netflix でアナイアレイションという映画を見た。面白くはなくて、CG の出来の悪さが目立っていた。こういう映画って誰が好きなのかさっぱり分からない。

あと3週間後には毎日9時に出勤する毎日なはずなのだが、ビジョンが全くない。生活時間がここまで破綻しているのは人生で最高点なのではないか。

最近太陽を見ていない。太陽の光でホルモンがコントロールされるというのは進化の過程で得たのだろうが、現代ではもう必要ないし、生活時間だけで不健康になっていくのはやめてほしい。早く肉体を捨てたい。

JOS 7週目

3/6

  • Lab 3 Part A
    • Exercise 2 lab3: finish exercise2 (maybe) · itkq/jos@d0892b0 · GitHub
      • 実装できたと思いきや再起動ループになる…
      • が実際は想定通りの動作で、下に説明があった (気づかなくてハマった)。ELF バイナリ hello の中で文字を表示する int 命令があり、ここで CPU の kernel space から user space への遷移の許可をしていないため CPU はリセットしてリブートする (この挙動自体はレガシーらしい)
      • env_alloc() まわりのイメージはこんな感じだとおもう f:id:itkq:20180306192722p:plain

3/7

3/8

3/10

とりあえず Lab 3 まで終えたが…あと3週間でやるぞやるぞ

JOS 6週目

2/26

  • Lab2 part3: Kernel Address Space を読むが進捗は無し

2/27

  • アイカツ武道館 Day 1 に行って来年の今頃どんな景色を見つめたいのか考える

2/28

  • アイカツ武道館 Day 2 に行って輝きに包まれる

3/1

  • Lab 2 part3 を実装 Finish lab2 · itkq/jos@a4b73fc · GitHub
    • 特にヒントは書いてないが boot_map_region() を実装すれば良いことが分かった
    • 要件通り Page Table Page を alloc して check_kern_pgdir() は通るが check_page_installed_pgdir() でコケる
    • part 2 で実装した部分が微妙に間違っているっぽい…

3/2

  • Lab 2: Memory Management を達成した (チャレンジ課題は手を付けていない)

ようやくページテーブルあたりをスッキリ理解したのでまとめておく。次のコードは pmap.c の一部である。

// pmap.c
// static void check_page(void)

    // should be able to allocate three pages
    pp0 = pp1 = pp2 = 0;
    assert((pp0 = page_alloc(0)));
    assert((pp1 = page_alloc(0)));
    assert((pp2 = page_alloc(0)));

    assert(pp0);
    assert(pp1 && pp1 != pp0);
    assert(pp2 && pp2 != pp1 && pp2 != pp0);

    // temporarily steal the rest of the free pages
    fl = page_free_list;
    page_free_list = 0;

    // should be no free memory
    assert(!page_alloc(0));

    // there is no page allocated at address 0
    assert(page_lookup(kern_pgdir, (void *) 0x0, &ptep) == NULL);

    // there is no free memory, so we can't allocate a page table
    assert(page_insert(kern_pgdir, pp1, 0x0, PTE_W) < 0);

    // free pp0 and try again: pp0 should be used for page table
    page_free(pp0);
    assert(page_insert(kern_pgdir, pp1, 0x0, PTE_W) == 0);
    assert(PTE_ADDR(kern_pgdir[0]) == page2pa(pp0));
    assert(check_va2pa(kern_pgdir, 0x0) == page2pa(pp1));
    assert(pp1->pp_ref == 1);
    assert(pp0->pp_ref == 1);

    // should be able to map pp2 at PGSIZE because pp0 is already allocated for page table
    assert(page_insert(kern_pgdir, pp2, (void*) PGSIZE, PTE_W) == 0);
    assert(check_va2pa(kern_pgdir, PGSIZE) == page2pa(pp2));
    assert(pp2->pp_ref == 1);

このコードが期待する、linear address から physical address への変換構図は下図のようになる。

f:id:itkq:20180302170509p:plain

struct PageInfo* pages は物理ページとのマッピングに使われるが、*(struct PageInfo *) が 4096 bytes なのではない。 物理ページは page_init() で見ているように、物理メモリのうち未使用の領域を 4096 bytes のチャンクとして扱っているだけである……最初混乱した。

3/3

JOS 4~5週目

修論を完全に破壊したのでモチベはあったのだが、エディタをカスタマイズしたくなりついでに vim から neovim に移行していたら時間が消失した。 neovim はそこそこ満足した状態になった。

f:id:itkq:20180222233951p:plain

2/11

  • stab document を軽く読む
    • GCC は -g オプションで .s ファイルに追加のデバッグ情報を埋め込み、リンカによって実行ファイルにも伝播する
    • オブジェクトファイルには stab (symbol table) アセンブラディレクティブとして埋め込まれる
  • Lab 1: Booting a PC Finish lab1 · itkq/jos@224c471 · GitHub

2/21

  • xv6 book Chapter 1: Operating system organization をまともに読む
    • process multiplexing をするために process isolation が必要で、そのためには virtual address (address space) が必要
    • strong isolation のために、application が直接物理リソースを触るのではなく OS が抽象化する
      • Unix process: 透過的なプロセッサスイッチ、exec(2) によるメモリイメージ配置抽象化、file descriptor
    • プログラマの利便性と strong isolation のための system call interface
      • ある process が fail したとき OS も落ちたようでは困る
      • x86 の kernel mode と user mode
      • monolithic kernel, micro kernel
  • Lab 2: Memory Management

2/24

  • xv6 book Chapter 2: Page Tables の序盤を読む
    • x86 は 220 の論理的な PTEs (Page Table Entries) から成る
    • Page Table は two-level tree としてストアされる
      • VA (Virtual Address) => PDE (Page Directory Entry) => PTE => Physical Page
  • Lab2, Part2: Virtual Memory に取り組むが終わらず
    • たぶんまだ物理ページと論理ページの関係がわかってない