- 仮想アドレス <-> 物理アドレスの変換をするのがページング
- 実際にはTLBに対象のアドレスがある場合はそちらが使われる
- TLBとアドレスの対応を同期させるために tlb flushが必要になる
- 実際にはTLBに対象のアドレスがある場合はそちらが使われる
- プロセスを造ったとき, 拡張したい時などに使われる
- ゼロページ
- ゼロが入っているページは書き込まれるまではすべてのプロセスが見ていていい
- 書き込まれた場合に初めて物理メモリに割当をする
- copy on write…
- 書き込まれた場合に初めて物理メモリに割当をする
- ゼロが入っているページは書き込まれるまではすべてのプロセスが見ていていい
- 仮想メモリにCPUがアクセスに行くと、ディスクをコピって制御する必要がある
- 一旦追い出して、コピった後はtlb flushする必要がある
- いろいろしたら tlb flush して trap return
# Xv6では
- memlayout.h
- v2p(仮想メモリ -> 実メモリ)などを制御するマクロが宣言されている
- mmu.h
- 実際に使用されるページに関するマクロが定義
- おおよそ定数を指定しているもの, ビット演算が書かれているものがある
- user page table sizeは4K
# vm.c
- 大体このファイルで実装されていそう
- staticがついているものはprivate codegear
- xv6は4K
- ARMは1K
- 1つのブロックを4つに分ける
pde_t *kpgdir; // for use in scheduler()
- スケジューラーに値を渡すためのglobal variable
- contextに書き込めば問題なさそう
kpt_mem
とかはDataGearにすれば良さそう
# init_vmm
|
|
- lockのとこに0をいれるだけ
- 0だったら誰も使ってない
- 使っている人のidをいれるのが本来
- freelistをNULLにしてるのはclearにしている
- init_vmmは外から呼び出されるのでInterfaceにするべき
# _kpt_free
- メモリページ全体をlinked listにしているrを取り出す
- vで指しているページテーブルをフリーリストにつなげる
- このリストは物理メモリで作られている
|
|
# ktp_free
- kfreeがカーネルのメモリフリー
- acquireとreleaseをしているので並列によばれる可能性がある
- acquireとreleaseはメタ計算でやるべき…?
|
|
# kpt_freerange
- 何ページもfreeするときはページごとにlinked listに接続する
- lockしていない
- これを呼ぶときはマルチプロセス環境で読んではいけない
- とはいえ外からよばれる
- release/lockは自前でする必要がある
|
|
# kpt_alloc
- lockしてNULLだったら kmalloc
- 失敗したらpanic
- allocateに成功したらゼロクリア
|
|
# walkpgdir
- page table側の場所を探す
- page table entryにNULL pointerがあるとセグフォして死ぬので厳しい
|
|
# mappages
- code gearに書き換えなくても良さそう
|
|
# switchuvm
- pageを切り替えるやつ
- inline 展開されそう
- push/pop cliで割り込み禁止
|
|
# inituvm
- pageディレクトリを作るやつ
|
|
# loaduvm
- swapから呼び出す
- kernelの中をぐるぐるしてreadiに入る
- 入った場合は待ちになる
- user proc側が街になる
- context側でどこで止まっていて、どこから実行するかを書かないとだめ
|
|
# allocuvm/deallocuvm
- page tableをallocateするか消すかの対応になっている
- memory clearはここでは行われない
- user virtual momeryの略?
# copyuvm
- forkのときによばれる
- forkの場合は自分のメモリ空間を子供にコピるので
- for文のパラメーターをどこかに保存しておく必要がある
|
|
# copyout
- 仮想メモリのコピーに巻き込まれそう…
|
|
# 方針
- free以外のfor/while文はCodeGearに変換する