GRUB Multibootを使用し自作のカーネルなどでSVGAを使う方法

GRUB Multibootの仕様書にはVBE Controller InformationやVBE Mode Informationの構造体のアドレスを取得できると書いてあるが、現在のGRUB 0.97では構造体のアドレスを取得できない。これはGRMUのmenu.lstにvbesetコマンドを書いてもVGAの画面のままでVBEを利用することができない事が原因である。

GRUB Multibootを使い、かつVBEを利用したいときはGRUBの古いバージョンを使用するか、もしくはVBE grubを使用すればこの問題を解決できる。パッチを当てるときはGRUBソースコードcvsからチェックアウトしVBE grubのパッチを当てるとうまくいく。ftp://alpha.gnu.org/gnu/grub/grub-0.97.tar.gzソースコードにパッチを当ててもうまくいかなかった。(configureのオプションが原因かもしれない)

GRUBの設定

GRUBの設定ファイルであるmenu.lstにvbesetのコマンドの引数に値を設定するとカーネル起動時にGRUB側がSVGA表示に切替えてくれる。引数の値は解像度の値でありVBEの仕様書を見るかhttp://en.wikipedia.org/wiki/VESA_BIOS_Extensionsを参考にするととてもわかりやすい。

例えば/boot/grub/menu.lstは以下のように設定する。

title           pxegrub + kernel
dhcp
tftpserver      server_address
root            (nd)
kernel          /kernel
vbeset          0x117
savedefault
boot

フレームバッファなどの取得

VBE Controller InformationやVBE Mode Informationの構造体のアドレスを取得するにはmultiboot.hをGUB Multboot仕様書に書いてあるように追加する。具体的には以下のようにmultiboot_headerとmultiboot_infoの構造体に以下の変数を追加する。

@@ -56,6 +45,10 @@
   unsigned long load_end_addr;
   unsigned long bss_end_addr;
   unsigned long entry_addr;
+  unsigned long mode_type;
+  unsigned long width;
+  unsigned long height;
+  unsigned long depth;
 } multiboot_header_t;
 
 /* The symbol table for a.out.  */
@@ -93,6 +86,17 @@
   } u;
   unsigned long mmap_length;
   unsigned long mmap_addr;
+  unsigned long drives_length;
+  unsigned long drives_addr;
+  unsigned long config_table;
+  unsigned long boot_loader_name;
+  unsigned long apm_table;
+  unsigned long vbe_control_info;
+  unsigned long vbe_mode_info;
+  unsigned short vbe_mode;
+  unsigned short vbe_interface_seg;
+  unsigned short vbe_interface_off;
+  unsigned short vbe_interface_len;
 } multiboot_info_t;
 

変更後、VBE Controller InformationやVBE Mode Informationの構造体のアドレスは以下のように簡単に取得ができる。VBE Mode Informationの構造体にフレームバッファの先頭のアドレスがある。

void vga_init(multiboot_info_t *info)
{
	vbe_info_block_t *vbe_info_blk = (vbe_info_block_t *)info->vbe_control_info;
	mode_info_block_t *mode_info_blk = (mode_info_block_t *)info->vbe_mode_info;

	...
}

スクリーンショット

VMWare上でVBEのデバイスドライバ書いて、四角をランダムに表示するプログラムを試してみた。