keigo1216 / ketchup

raspberrypi 3A+用のOS
1 stars 0 forks source link

Refactor process structure #57

Open keigo1216 opened 2 months ago

keigo1216 commented 2 months ago

プロセス周りの実装をリファクタリングする

プロセスを生成する関数の改良

現在:create_process関数でプロセスを作成&runqueueにpushを行う 改良後:init_process関数とプロセスをrunqueueに入れる関数(命名はまだ未定)に分ける。idel_processの扱いが現状ではめんどくさかったので。また、idel_processについては、レジスタにcpuの情報としてアドレスを格納しておくといいかも(riscvではtpレジスタ(x4)に格納していた。amではどこがいいんだろう) spの初期化などのハードウェアに近い部分はいつか分けれるといいな。

参考実装 init_task arm_init_task task_init_per_cpu

idelプロセスの生成方法の改良

現在の実装ではidelプロセスを別で生み出しているが、idelプロセスをカーネルの起動時に飛ぶmain関数にして、main関数の最後で割り込み待ちの関数を入れておけば、idelプロセスとして機能する(つまり、idelプロセスを新しく別に作り出す必要はなく、起動時のプログラムをidelプロセスにしてあげればOK!)

まずtask_init_per_cpuで現在のプログラムをIDELプロセスとして登録する。 そして、idel_task()で割り込み待ちになる。

idel_taskでは、task_switchとidel(つまり割り込み待ち)にしておく。IDELプロセスは常にBLOCKED状態なので、runqueueに入ることはない。task_switch関数のなかで呼び出されるスケジューラが、runqueueに何もなく、実行するタスクがない場合にIDELを返し、それによって、復帰することができる(頭いい)

void kernel_main(struct bootinfo *bootinfo) {
    printf("Booting HinaOS...\n");
    memory_init(bootinfo);
    arch_init();
    task_init_percpu();
    create_first_task(bootinfo);
    arch_init_percpu();
    TRACE("CPU #%d is ready", CPUVAR->id);

    // ここからアイドルタスクとして動作する
    idle_task();
}

スケジューリングアルゴリズムの改良

現在:プロセス配列の中からRUNNABLEなタスクを一つとってきている。 改良後:キューの構造にする

keigo1216 commented 2 months ago

ページ周りの整理

ページテーブル割り当ても別の関数に切り出したい

新しいプロセスに対して、ページテーブルを初期化する手順

  1. 一段目のページテーブル用のメモリ(物理アドレス)をalloc_pagesを用いて確保する
  2. プロセスの実行領域のプログラムを物理メモリに割り当てる(ページのサイズに分割して)
  3. 物理アドレス <=> 仮想アドレスに変換できるように二段目以降のページテーブルを作成する

仮想アドレスはUSER_BASEをベースアドレスとして設定しているみたい

概念図 IMG_3F607611E8B5-1

RISC-V実装とARM実装の違い

ARMはカーネル用のページテーブルとユーザー用のページテーブルを設定するレジスタが違うので、カーネルページはブート時に一度だけ設定すれば良い

TODO

別issusに切り出して検討する