OSをもっと小さくしよう!(その1)

  • (by K, 2006.09.28)
  • 発展課題のページ(全部読む前にここを読むのは混乱するのでおすすめじゃないです)

はじめに

  • advance/osselectを使うようになると、ディスクにアプリやデータを詰め込むだけではなく、面白いOSまで詰め込むようになるので、容量が不足し始めるかもしれません。そうなってくるとうらめしいのが haribote.sys の大きさです。osselectで切り替える.bhsはtek圧縮をかけてもいいのでかなり小さくできるのですが、 haribote.sys は圧縮してはいけないのでそうはいかないわけです。
  • 仮に容量不足にならなくても、OSが小さければIPLでのCYLSを減らせて、そのぶん起動が速くなることもあるかもしれませんしね。・・・というかOSが小さくなって困ることなんてないのですから、絶対にいいことなんです!(笑)。
  • ということで、まずはSeroさんの提案してくださった方法で、 haribote.sys を小さくすることにしましょう。・・・でもそのままだと面白くないので、Kなりに少しだけアレンジしてあります(理由は後述)。

書き換えるところ

  • timer.c
    void init_pit(void)
    {
        io_out8(PIT_CTRL, 0x34);
        io_out8(PIT_CNT0, 0x9c);
        io_out8(PIT_CNT0, 0x2e);
        timerctl.count = 0;
        timerctl.next = 0xffffffff; /* 番兵しかいないので番兵の時刻 */
        return;
    }
    
    void init_timerctl(void)
    {
        struct MEMMAN *memman = (struct MEMMAN *) MEMMAN_ADDR;
        int i;
        struct TIMER *t;
        timerctl.timers0 = (struct TIMER *) memman_alloc_4k(memman, MAX_TIMER * sizeof(struct TIMER));
        for (i = 0; i < MAX_TIMER; i++) {
            timerctl.timers0[i].flags = 0; /* 未使用 */
        }
        t = timer_alloc(); /* 一つもらってくる */
        t->timeout = 0xffffffff;
        t->flags = TIMER_FLAGS_USING;
        t->next = 0; /* 一番うしろ */
        timerctl.t0 = t; /* 今は番兵しかいないので先頭でもある */
        return;
    }
    

  • bootpack.h
    void init_timerctl(void);
  • これを適当なところに書き加える。さらに以下の一行を変更。
    struct TIMERCTL {
        unsigned int count, next;
        struct TIMER *t0;
        struct TIMER *timers0;  /* ココ! */
    };

  • bootpack.c
    void HariMain(void)
    {
        (中略)
    
        memtotal = memtest(0x00400000, 0xbfffffff);
        memman_init(memman);
        memman_free(memman, 0x00001000, 0x0009e000); /* 0x00001000 - 0x0009efff */
        memman_free(memman, 0x00400000, memtotal - 0x00400000);
    
        init_timerctl();    /* ココ! */
        init_palette();
        shtctl = shtctl_init(memman, binfo->vram, binfo->scrnx, binfo->scrny);
        task_a = task_init(memman);
        fifo.task = task_a;
        task_run(task_a, 1, 2);
        *((int *) 0x0fe4) = (int) shtctl;
        task_a->langmode = 0;
    
        (中略)
    }
    

Seroさん版との違いは?

  • Seroさん版のほうが改造量が少なくていいのですが、Seroさん版だとinit_pit()の前にメモリチェックをすることになり、これは結構時間がかかる処理なので(そりゃあ4KBずつチェックするようになったのでそれなりに速くはなりましたが、それでも他の処理に比べたら長い処理です)、io_sti()するまでの時間が長くなってしまいます。
  • 割り込み禁止期間はたとえ起動時であっても短いほうがいいので(あまり長く割り込みを禁止してから再開すると、いろいろとトラブルの元にもなる)、このページではとりあえずtimerctl.timers0[]に関する初期化以外をメモリテストより前にやってしまって、それでio_sti()し、そのあとでのんびりとメモリテストをして、timerctl.timers0[]に関する初期化をやるようにしています。

これでどのくらい効果があるのか?

  • harib27fのharibote.sysで比較
    無改造40,344バイト
    このページの改造30,416バイト
    差し引き-9,928バイト
    • 註:このharib27fには、Athlon64X2でのバージョン6のパッチやbugsのbug0008までのパッチを含んでいます。

余談

  • 本文中での完成が、ムダに10KBも多い状態だったなんて、非常に不覚!そしてそれに自力で気づいたSeroさんに感謝!

こめんと欄

  • 自分の改良を本家に取り込んでもらえるなんてうれしいです。メモリチェックは重い処理だということも分かったので、Lightsも修正したいと思います。もともとこの問題は1週目の開発でmapファイルを眺めて気づいたもので(2週目の開発で修正)、mapファイルが意外に便利なことが分かりました。 -- Sero 2006-09-30 (土) 13:04:45

コメントお名前NameLink

リロード   新規 編集 差分 添付   トップ 一覧 検索 最終更新 バックアップ   ヘルプ   最終更新のRSS
Last-modified: 2006-09-30 (土) 13:04:45 (5537d)