はじめに
BitVisor にVMMCALLを追加する方法を説明します.
本日はオーストリアよりBitVisor 情報をお届けなので,ソースコードの動作確認などできてません.
それなのに関数名を手で直したりしてるので,多分どこか動かない部分があると思います.
でもまぁ,だいたいの感じはつかんでもらえるかと思います.
VMMCALL って 何?
VMMCALL というのは,ゲストOSからVMMに機能を呼び出す機構です.
ゲストOSはvmmcall
というCPU命令を発行することでVMMの機能を呼び出せます.
構造としては,アプリケーションレイヤからシステムコールを呼び出すのに似ています.
ゲストOSからVMM内の情報を取得したり,何か指示を出すのに有用な機能です.
BitVisor では,dbgsh(デバッグ用のシェル)などが,VMMCALLを用いて実現されています.
VMMCALL を追加する方法
core/vmmcall_hello.c
ってな感じのファイルを追加しましょう.
中身は以下のような感じで.
static void
hello(void)
{
ulong rbx;
ulong ret = 10;
/*引数の受け取り*/
current->vmctl.read_general_reg (GENERAL_REG_RBX, &rbx);
printf("Hello BitVisor!, arg1 = %d\n", rbx);
/*戻り値の格納*/
current->vmctl.write_general_reg (GENERAL_REG_RAX, (ulong)ret);
}
/* 関数の登録 */
static void
vmmcall_hello_init(void)
{
vmmcall_register("hello", hello);
}
INITFUNC ("vmmcal0", vmmcall_hello_init);
VMMCALL を呼び出す方法.
Makefile やらなんやら必要で,一から全部書くのは面倒なので,BitVisor 内ですでに定義しているVMMCALLをコピペして中を変えて,新しいVMMCALLを足してみましょう.
というわけで,VMMCALL をつかっているdbgshを拝借しましょう.
以下の準備はゲストOS上で行います.
まず,tools/dbgsh をコピー
cd ~/bitvisor/tool/
cp -r dbgsh hello
ファイル名の変更
cd hello
mv dbgsh.c hello.c
Makefile の変更
Makefile 内のdbgshをhelloに置換(sedとかM-%とかで)
windows 用のバイナリが不要な場合は以下を削除(この作業は要らないかも)
先頭3行
all: 行の my_vmmcall.exe
my_vmmcall.exe : の行とその次の行すべて
呼び出し側のコードのプログラムを以下のように書き換えます.
static void
vmmcall_hello (int arg)
{
call_vmm_function_t f; /*vmm call に関する情報を格納*/
call_vmm_arg_t a; /*vmm call に渡す引数を格納*/
call_vmm_ret_t r; /*vmm call の戻り値を格納*/
CALL_VMM_GET_FUNCTION ("hello", &f); /*vmm call の名前から関数に関する情報を取得*/
/*エラー処理*/
if (!call_vmm_function_callable (&f)) {
fprintf (stderr, "vmmcall \"hello\" failed\n");
exit (1);
}
a.rbx = (long)c; /*引数を設定*/
call_vmm_call_function (&f, &a, &r); /*vmm call 呼び出し*/
return (int)r.rax; /*戻り値の取得*/
で,ビルドして動かしてみましょう.
$ make
BitVisor が動いてる状態で
$ ./hello
ってやれば動く(はず(はず))