雑記帳
ここはhideyosiの雑記帳です。テケトーに書き散らしてるだけなので間違っていたりとは普通にしてます。信用度は相当低いことをあらかじめご了承を。またご覧のようにWikiを使ってますが、hideyosi意外は書き込めません。
3: 2007-01-27 (土) 16:14:04 ソース バックアップ No.3 を復元して編集 現: 2024-01-06 (土) 22:39:13 ソース 編集
Line 18: Line 18:
         ・・・と、こういう指定で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化して
Line 36: Line 36:
 /*なので、以降は単に「どの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;
Line 42: Line 42:
     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; /* 動作中マーク */
Line 61: Line 61:
    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関数で指令してやらないといけない。