はりぼて日記
2007 | 01 | 02 | 03 | 04 | 05 | 07 | 08 | 10
2006 | 11 | 12
1月 18 (木曜日) 2007
22:56
ちょっと脱線(LDTがわからん)
 
まずはGDTをもう一度復習。P110から読み直し!

GDTはセグメントの情報を管理する表。で、メモリに存在する。GDTはかならずセットしないとセグメントが使えないのでこまるが、GDTをどこから始めるのかは勝手に決めてよいようだ。(GDTRに書きこめばよいらしい。)

for (i = 0; i < 8192; i++) {
set_segmdesc(gdt + i, 0, 0, 0);
}

ええと、これが約8000個分あるGDTの各行の設定のパターン。(ここではforで回して、一旦ぜーんぶのGDTに0を入れている。

   set_segmdesc(gdt + 1, 0xffffffff, 0x00000000, 0x4092);
   set_segmdesc(gdt + 2, 0x0007ffff, 0x00280000, 0x409a);

このパターンで個々のGDTをセットアップしている。細かく言えば、

set_segmdesc(gdt + GDT番号, 大きさ, 開始番地, 属性);

と、こうなる。ちなみに属性は少々ややこしいが、P126のカッコ内をとりあえず下二桁にあてはめればいいようだ。

なので、上記 GDT1番、GDT2番はそれぞれ、「92なので、システム専用の読み書き可能セグメント。実行はできない」「9aなので、システム専用の実行可能セグメント。読み込みもOK。書き込みはできない」と、こうなる。

P292。
マルチタスクする場合、切り替える前のレジスタの情報全てを一旦どこかに退避させ、別のタスクに切り替える。(ちょうどレジスタを丸ごとバックアップするようなもの)
その退避場所(104バイト必要)をTSSという。TSSはプログラム上で勝手に適当な変数を作ってやるのではない。セグメントの一種としてあつかう。なので、上記のGDTの設定と同じようにしないといけない。(大きさと属性だけが決まっている。あとは適当でいい)

 set_segmdesc(gdt + 3, 103, (int) &tss_a,AR_TSS32);

(AR_TSS32は0x0089のこと。とにかくこの数値を当て込むと、そのセグメントはTSSという特殊なセグメントになる)

P312から汎用なタスク操作のプログラムが始まっている。
これを見ると、「task」という構造体を用意し、これがおのおののタスクに必要なデータを管理and記憶していることがわかる。

task->sel  簡単に言えば、GDTの何番のセグメントを使うのかという情報。
task->flags  使用中かそうでないかのフラグ
task->tss  このタスクが使うtss構造体


task_init 関数を使い、これらを初期化している。初期化はいったいなにをやっているかというと

for (i = 0; i < MAX_TASKS; i++) {
taskctl->tasks0[i].flags = 0;
taskctl->tasks0[i].sel = (TASK_GDT0 + i) * 8;
set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32);
}














・・・・あーーー。だめだぁ・・・わっかんねぇ〜・・・・

今日はもう寝る!
 
30日を過ぎたBlogにはコメントできません。

Referer  (8)
(1) 2 3 4 5 6 7 8 9 10 » 

PopnupBlog V3 Denali created by Bluemoon inc.