はりぼて日記
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); } ・・・・あーーー。だめだぁ・・・わっかんねぇ〜・・・・ 今日はもう寝る! |
||
(1) 2 3 4 5 6 7 8 9 10 »  |
PopnupBlog V3 Denali created by Bluemoon inc. |