3: 2007-01-27 (土) 16:14:04  |
現: 2024-01-06 (土) 22:39:13  |
| | ・・・と、こういう指定でtssをGDTにセットしていた。 */ | | ・・・と、こういう指定でtssをGDTにセットしていた。 */ |
| | /*----------------------------------------------------------------------------*/ | | /*----------------------------------------------------------------------------*/ |
| | + | |
| | /* ここはまあ、前と同じだが・・・・ */ | | /* ここはまあ、前と同じだが・・・・ */ |
| | struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; | | struct SEGMENT_DESCRIPTOR *gdt = (struct SEGMENT_DESCRIPTOR *) ADR_GDT; |
| | /*これ以降が違う。GDTの何番目にセットするのか。セットするtss構造体はどれなのか? | | /*これ以降が違う。GDTの何番目にセットするのか。セットするtss構造体はどれなのか? |
| | という情報を、以下のプログラムで自動的に探し出してセットしている*/ | | という情報を、以下のプログラムで自動的に探し出してセットしている*/ |
| | + | |
| | /* ちなみにtaskctl構造体がデカイのでメモリをゲットしているところ。 | | /* ちなみにtaskctl構造体がデカイのでメモリをゲットしているところ。 |
| | taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL)); | | taskctl = (struct TASKCTL *) memman_alloc_4k(memman, sizeof (struct TASKCTL)); |
| | + | |
| | /* ここにあるforで0〜最大タスク個数まで繰り返す。空いている番号が見つかったら | | /* ここにあるforで0〜最大タスク個数まで繰り返す。空いている番号が見つかったら |
| | そこを新しいタスクとする。これにより、GDTの何番目を使うのか、tssがどの | | そこを新しいタスクとする。これにより、GDTの何番目を使うのか、tssがどの |
| | タスク内のものなのかがわかる*/ | | タスク内のものなのかがわかる*/ |
| | + | |
| | /*↑・・・っと思い込んでたが大間違いだった。 | | /*↑・・・っと思い込んでたが大間違いだった。 |
| | /*ここは、とにかくGDTの3(TASK_GDT0)〜最大数までのGDTテーブルを一気にtss化して | | /*ここは、とにかくGDTの3(TASK_GDT0)〜最大数までのGDTテーブルを一気にtss化して |
| | /*なので、以降は単に「どのtasks[?]が空いてるかな?」を探し、空きが見つかったら | | /*なので、以降は単に「どのtasks[?]が空いてるかな?」を探し、空きが見つかったら |
| | /*そのtasks0[?]に当て込めば自動的にtssも設定させると!。こういう仕掛けか! | | /*そのtasks0[?]に当て込めば自動的にtssも設定させると!。こういう仕掛けか! |
| | + | |
| | for (i = 0; i < MAX_TASKS; i++) { | | for (i = 0; i < MAX_TASKS; i++) { |
| | taskctl->tasks0[i].flags = 0; | | taskctl->tasks0[i].flags = 0; |
| | set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); | | set_segmdesc(gdt + TASK_GDT0 + i, 103, (int) &taskctl->tasks0[i].tss, AR_TSS32); |
| | } | | } |
| - | | + | |
| | + | |
| | /*上記のGDTの予約?のおかげで、もうGDTは気にしなくていいのだ! | | /*上記のGDTの予約?のおかげで、もうGDTは気にしなくていいのだ! |
| | /*以降は、task_allocさえすれば、自動的にタスクがすぐ走れる状態で | | /*以降は、task_allocさえすれば、自動的にタスクがすぐ走れる状態で |
| | /*1個準備される。 | | /*1個準備される。 |
| | + | |
| | /*以下は、今動いている自分自身(HariMain。これまでの仮想的なtask_aのこと)を | | /*以下は、今動いている自分自身(HariMain。これまでの仮想的なtask_aのこと)を |
| | /*ひとつのタスクとして登録しているだけ。 | | /*ひとつのタスクとして登録しているだけ。 |
| | + | |
| | task = task_alloc(); | | task = task_alloc(); |
| | task->flags = 2; /* 動作中マーク */ | | task->flags = 2; /* 動作中マーク */ |
| | return task; | | return task; |
| | } | | } |
| | + | |
| | + | -たくさん勘違いしていたが、このtask_init関数は、ほぼ一度だけやれば以降はしなくていい。タスクをシートのように管理するための単なる下地作りに過ぎないのだ。 |
| | + | |
| | + | -これ以降、タスクを新設したい場合はtask_alloc関数を使う。この関数は |
| | + | |
| | + | struct TASK *task_alloc(void) |
| | + | { |
| | + | int i; |
| | + | struct TASK *task; /*とりあえずtask構造体を一つ用意する*/ |
| | + | |
| | + | for (i = 0; i < MAX_TASKS; i++){ /*このforループで、taskctl内にある */ |
| | + | /*tasks0[]配列を上からチェックする。*/ |
| | + | |
| | + | if (taskctl->tasks0[i].flags == 0 { /*もしflagsが0。つまり使用されていないtasks0[]があったら */ |
| | + | task = &taskctl->tasks0[i]; /*よし!ここだ!上で今回用意したtask構造体をこのtasks0[]とする */ |
| | + | task->flags = 1; /*そこをとりあえず使用中とするためマークする。(確保するわけ) */ |
| | + | task->tss.eflags = 0x00000202; /*これ以降は、まったく新しいタスクの |
| | + | /*tssを準備したのだから、初期化処理をする。*/ |
| | + | task->tss.eax = 0; |
| | + | : |
| | + | : |
| | + | task->tss.ldtr = 0; |
| | + | task->tss.iomap = 0x40000000; |
| | + | return task; |
| | + | } |
| | + | } |
| | + | } |
| | + | |
| | + | -これによって全ての準備が出来上がった。しかし、まだ走っていない。走らせるには、task_run関数で指令してやらないといけない。 |