Personal tools
You are here: Home ブログ 学習経過 カーネル(その5)
« December 2010 »
Su Mo Tu We Th Fr Sa
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Recent entries
sysfs tips 02 ohyama 2010-09-09
sysfs tips ohyama 2010-09-02
Haskell で周波数スペクトルを得る ohyama 2010-07-29
Haskell で線形識別関数の学習を行う ohyama 2010-07-19
Haskell で逆行列を求める ohyama 2010-07-16
Recent comments
Re:vim に lisp 機能をつける t.mimori 2010-12-16
Re:Haskell で周波数スペクトルを得る H.OHYAMA 2010-08-01
Re:lkml でお勉強 (その1-1) Hiroyasu OHYAMA 2009-08-21
Re:lkml でお勉強 (その1-1) kosaki 2009-08-20
Re:vim に lisp 機能をつける ohyama 2008-05-08
Categories
学習経過
GNU/Linux
 
Document Actions

カーネル(その5)


以前につまづいていた、プロセススイッチの実装がようやく完了した。

前回は、プロセスの概論についてと onix におけるプロセス生成の話を少しした。
今回は、プロセススイッチの仕組み及び onix におけるプロセスのデータ構造とプロセススイッチの実装について話をする。
尚、以下で話すプロセススイッチは、同じ特権レベル同士のプロセスにおけるそれである事を先に述べておく。

又、プログラムソースは
http://sourceforge.jp/projects/onix/
で svn リポジトリを公開している。

プロセススイッチを実現する為の手法として、TSS ディスクリプタによる far ジャンプと ret 命令の戻りアドレスを書き換える方法の2種類が存在する。onix では後者の方法によってプロセスの切替えを行っている。具体的には、割り込みサービスルーチンにおいてスタックを書き換えて iret を実行し、プロセスを切替えている。

では、プロセススイッチの全般の処理について話をする。プロセスの切り替えを円滑に行う為に、カーネルはページテーブル、プログラムカウンタ、スタックポインタ、各種汎用レジスタ、そしてフラグレジスタの内容 (以下、プロセス固有情報) を保存する。これが終了した後、カーネルは次に実行するプロセスを任意の方法で選択し、切り替えるプロセスのフラグレジスタ、コードセグメントセレクタ、プログラムカウンタをスタックに積み、プログラムカウンタ及び、各種汎用レジスタの値を切り替えるプロセスのそれらに更新し iret 命令を実行する。
しかし、同一の特権レベルのコードセグメントにジャンプする場合には、上記の処理だけでプロセスが切り替わるが、ユーザープロセスへの切り替えとなると、処理が若干ややこしくなる。これについては、次回以降に話をする。

ここまでの話は、CPU を使う上での作法のようなものなので、スケジューリング処理は違えど、プロセススイッチの方法はどのカーネルにおいてもほとんど同じである。
ほとんどの意は、先にも言ったように TSS ディスクリプタと far ジャンプを使ったプロセススイッチ処理を行う別の流派があるという事であるが、この方法によるプロセススイッチは試してないので、ここではこれ以上触れない事にする。

上記が、プロセススイッチの大まかな処理の流れである。
次に、onix におけるプロセススイッチを行う上でのプロセスのデータ構造及び、処理について見てゆく。
各プロセス固有のデータ構造を process.h にて定義した。タイマ割り込みのサービスルーチンでは、プロセススイッチを実行する際に、プロセス固有情報を process 構造体のオブジェクト (以下、プロセスディスクリプタ) に退避させている。
次に、切り替えるプロセスを決定するのだが。システムに現在どのようなプロセスがどのくらいあるのかを把握するために、カーネルはプロセスリストを持っている。通常、プロセスの状態 (アクティブ、ブロック、ゾンビなど) に応じて複数のリストをカーネルは持っているのだが、この文書を書いている時点では、開発中につき、カーネルは 1 本 のアクティブリストしか持っていない。
プロセス生成時、プロセスは所定のリストに追加登録される。そして、プロセススイッチ実行時にスケジューラは、アクティブリストから次に実行するプロセスを選択する。
ずいぶんさらっと言ったが、ここでの話は "並列処理における巧みなスケジューラを実現する" といったようなもので、学部の論文くらいは軽く書けてしまうような深いテーマである。
が。暫定 onix スケジューラはリストを回して、先頭プロセスをひたすら選択しつづけるだけである。

プロセス切り替えを行った後は、セオリー通り切り替えたプロセスのプロセス固有情報を取得し、スタックポインタを書き換え、プロセス固有情報をスタックに積み popa 命令を実行して各種レジスタを更新し、iret 命令でプロセスを切り替える。

これがこの文書を書いた時点でコミットされている onix の処理であるが、一般的な IA アーキテクチャを積んだマシンのカーネルは、ユーザープロセスなるプロセスが存在するわけであり、それを実行する場合には、セグメント間ジャンプを実行する為にセグメントセレクタもプロセス固有情報として持たせる必要がある。iret 命令を実行してプロセスの切り替えを行っているので、現在でもセグメント間ジャンプは行っているのだが、現時点での onix は同一コードセグメント及びデータセグメントのプロセスのみサポートしているので、セグメントの切り替えについては未実装である。これについては、ユーザープロセスをサポートした時にまた紹介する。

以上より、onix はマルチプロセスなカーネルになった。


Category(s)
学習経過
The URL to Trackback this entry is:
http://dev.ariel-networks.com/Members/ohyama/30ab30fc30cd30eb-305d306e5/tbping
Add comment

You can add a comment by filling out the form below. Plain text formatting.

(Required)
(Required)
(Required)
(Required)
(Required)
This helps us prevent automated spamming.
Captcha Image


Copyright(C) 2001 - 2006 Ariel Networks, Inc. All rights reserved.