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;
...
}