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
putchar_attribute
putchar_flags
PUTCHAR_SJIS
putchar()
は漢字コードとして EUC-JP
ではなくシフトJIS を認識するようになります。
PUTCHAR_XZENKAKU
putchar()
は全角文字を表示しなく
なります (全角文字のコードを与えても何も表示しません)。メニュー画面で
表示領域右端で表示を切るために使います。
putchar_save
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> のメモリ下限値を
修正しています)。
GRUB/98 では、移植者の趣味(?) によって次のような機能が オリジナルの GRUB から拡張されています。
次の機能は、 GNU GRUB のファイルシステムバックエンドをバックポートすることで対応しました。
なお GNU GRUB でも FAT32 に対応していますが GRUB/98 の FAT32 サポートはそれとは関係なく独自に実装されています。
フラグ | 表示する内容 |
---|---|
b | DISK BIOS 呼び出し前後のレジスタの値 |
e | DISK BIOS でエラーが発生したときの BIOS の戻り値 |
c | リムーバブルメディア (フロッピーや MO、 CD-ROM など) の交換検出 |
f | フロッピーのフォーマット検出の詳細 |
g | GRUB/98 のディスクジオメトリの計算の詳細 |
s | ファイルシステムバックエンド固有のデバッグ出力 |
これらのコマンドは主にデバッグ用に実装したもので、 インタフェースは暫定的です。将来高い確率で変更される可能性があります。