GRUB/98 (PC-9800 シリーズのための GRUB)

GRUB/98 は、もともと IBM PC 互換機用に作られたブートローダである GRUB (GRand Unified Bootloader) を、 NEC PC-9800 シリーズ (Epson などの互換機も含む、以下単に 98 と表記します) 上で動作するよう移植したものです。

このドキュメントでは主に移植にあたって GRUB の内部構造に加えた変更点について記述しています。 オリジナルの GRUB のドキュメントも随時参照ください。

全般的な事柄

まず基本的に、 IBM PC と 98 では BIOS の仕様が全然違います (INT 命令を 使う点では共通ですが)。このため、特に BIOS を直接呼び出す部分 (stage1、shared_src/asm.S) はほとんどすべて書き換えています。

98 は IBM PC 互換機の世界とは異なり、I/Oポートの配置や BIOS のワークエリアが 比較的固定されています (ほとんど一社から出ていたので、当然といえば当然です)。 したがって、 GRUB/98 でもオリジナルでは BIOS を呼び出しているのを、 I/Oポートを直接アクセスしたりワークエリアを直接参照するコードで置き換えている ところがあります。

GRUB/98 では、文字表示まわりやディスクまわりなどで処理が複雑になり、 コードサイズが肥大化しがちになっていますので、これを少しでも抑えるため 随所に工夫 (?) を凝らしています。

文字表示関係

IBM PC の BIOS には、テキスト画面に文字を出力するための BIOS (INT 10h ファンクション 01h) がありますが、 98 にはこれに相当する BIOS はありません。 GRUB/98 ではテキストVRAMに文字コードを書き込むルーチンを 自前で用意することで対応しています (putchar() <shared_src/asm.S>)。このルーチンはオリジナルの putchar() と互換性を保っていますが、 この他に 98 のハードウェアを活かすべく漢字表示にも対応させています。 漢字コードは基本的に EUC-JP を使用しており、 SS2 を使用した半角片仮名の表示、 98 固有の 2バイト半角文字にも対応しています。また 2バイト文字を表示する際にも putchar() には1バイトずつ順に渡していけばよいようにしています。 さらにこのルーチンの動作を指定する次のような外部変数を定義しています (これらはすべて unsigned char 型です)。

putchar_x, putchar_y
それぞれ文字表示位置の桁位置、行位置です。 いずれも0にすると画面左上隅になります。
putchar_attribute
文字をテキストVRAMに表示する際にアトリビュート領域に書き込む値です。 初期値は 0xE1 (白、反転・下線・反転なし) です。
putchar_flags
次の記号定数のビットORです。
PUTCHAR_SJIS
これを指定すると、 putchar() は漢字コードとして EUC-JP ではなくシフトJIS を認識するようになります。
PUTCHAR_XZENKAKU
これを指定すると、 putchar() は全角文字を表示しなく なります (全角文字のコードを与えても何も表示しません)。メニュー画面で 表示領域右端で表示を切るために使います。
putchar_save
2バイト文字の1バイト目を保存する領域です。ここが 0 でないと putchar() は次に渡される文字を (それが正しいか否かに関らず) 2バイト目の文字として扱います。

このように putchar() が明確に定義された外部変数を使うことから、 98 では gotoxy()getxy() はこれらの変数を操作する マクロにしています。

メモリ関係

これも、 IBM PC の INT 12h のようにメモリサイズを取得するBIOSが 98にはありません。 98 ではBIOSのワークエリアを参照することによって メモリサイズを取得しています (get_memsize() <shared_src/common.c>)。

98 では、物理メモリ空間のアドレス 0x00F00000 〜 0x01000000 (15MB 〜 16MB) にメモリがないことがあります。セットアップメニューでは「16MBシステム空間」 と表現されていますが、簡単に言えばこの領域にはVRAMなどが割り当てられており 通常の用途には使えません。 GRUB では、アドレス 0x00100000 (1MB) から始まる 連続したメモリ空間のサイズを upper memory としていますので、 「16MBシステム空間」を「使用する」に設定している場合は、 16MB 以上メモリを塔載していても「14336K upper momory」と 表示されます (「使用しない」に設定している場合は、塔載している全メモリの 容量が表示されます)。

なお IBM PC でも、物理メモリ空間の一部にグラフィックメモリやメモリマップド I/O のための「穴」があることがあり (GRUB のドキュメントでは ``chipset hole'' と呼ばれています)、オリジナルの GRUB でもこれに対応しています (GRUB/98 は この機構を利用しています)。

オリジナルの GRUB は BIOS のワークエリアとして 0x00000000 〜 0x00000FFF (0KB 〜 4KB) を確保していますが、 98 では BIOS のワークエリアは 0x00000000 〜 0x000005FF (0KB 〜 1.5KB) となっています。 GRUB/98 では 0x00000600 〜 0x00000FFF (1.5KB 〜 4KB) の領域をディスクのジオメトリの キャッシュやパーティションテーブルのバッファに利用しています (このため、 memcheck() <shared_src/char_io.c> のメモリ下限値を 修正しています)。