BitVisorのADvisor機能の利用

BitVisorのADvisor機能を利用する方法について説明します．

ADvisor機能は，BitVisorがグラフィクスハードウェアのフレームバッファを読み書きすることにより画面情報の取得や更新をする機能です．

ADvisor機能を使うには，グラフィクスハードウェアがIntelのものである必要があります．NVIDIAのグラフィクスハードウェア上でADvisor機能が動いたという報告を聞いたことはありません．また，Haswell以降のチップセットのマシンではADvisor機能が動かないという報告を聞いたことがあります．

## API

core/vga.c には数個の関数が定義されています．BitVisorの中でこれらの関数を呼び出すことにより，ADvisor機能を使うことができます．
これらの関数の仕様についてはドキュメントはたぶん無いですが，おそらく以下の通りです．

#### `int vga_is_ready (void);`
フレームバッファに読み書きできる状態かどうかを調べる．Ready状態なら1，そうでないなら0が返る．

#### `int vga_transfer_image (enum vga_func_transfer_dir dir, void *image, enum vga_func_image_type type, int stride, unsigned int width, unsigned int lines, unsigned int x, unsigned int y);`
ビットマップ情報をフレームバッファから読み込む，または，フレームバッファに書き込む．

引数に関する仕様：
dir: VGA_FUNC_TRANSFER_DIR_GETを与えると読み込み．VGA_FUNC_TRANSFER_DIR_PUTを与えると書き込み．
image: ビットマップ情報を格納するバッファへのポインタ．
type: ビットマップの表現形式を与えるための引数と思われるが，おそらく現在はVGA_FUNC_IMAGE_TYPE_BGRX_8888が唯一の選択肢．
stride: ビットマップ情報の各行のデータのサイズ（単位はバイト）．
width, lines: 読み書きする領域の横幅と縦幅（単位はピクセル）．
x, y: 読み書きする領域の座標．

#### `int vga_fill_rect (void *image, enum vga_func_image_type type, unsigned int x, unsigned int y, unsigned int width, unsigned int height);`
ビットマップ情報をフレームバッファに書き込む．

引数に関する仕様： vga_transfer_imageと同様．

#### `int vga_get_screen_size (unsigned int *width, unsigned int *height);`
スクリーンの縦幅と横幅を取得する．取得に成功したら1，失敗したら0が返る．

引数に関する仕様：
width: このポインタの先にスクリーンの横ピクセル数が格納される．
height: このポインタの先にスクリーンの縦ピクセル数が格納される．

## 利用例

これらの関数を組み合わせて，たとえば，ハイパバイザが勝手にデスクトップをモザイク化する処理を実現できます．以下の関数を core/vga.c の中に加えて，BitVisorの中のどこかから呼び出せばOKです．

```c:
int vga_tessellate_screen(unsigned int tile_size)
{
  unsigned int width, height;
  unsigned int x, y;
  u32 *tile;

  if (!vga_is_ready()) {
    return 0;
  }

  if (!vga_get_screen_size(&width, &height)) {
    return 0;
  }

  tile = alloc(tile_size * tile_size * sizeof(u32));
  for (y = 0; y < height; y += tile_size) {
    for (x = 0; x < width; x += tile_size) {
      int j;
      if ((x + tile_size > width) || (y + tile_size > height)) {
        continue;
      }
      if (vga_transfer_image(VGA_FUNC_TRANSFER_DIR_GET, tile,
                             VGA_FUNC_IMAGE_TYPE_BGRX_8888,
                             sizeof tile[0] * tile_size,
                             tile_size, tile_size,
                             x, y) < 0) {
        goto out;
      }
      for (j = 1; j < tile_size * tile_size; j++) {
        tile[j] = tile[0];
      }
      if (vga_transfer_image(VGA_FUNC_TRANSFER_DIR_PUT, tile,
                             VGA_FUNC_IMAGE_TYPE_BGRX_8888,
                             sizeof tile[0] * tile_size,
                             tile_size, tile_size,
                             x, y) < 0) {
        goto out;
      }
    }
  }

 out:
  free(tile);
  return 1;
}
```
Before

![advisor1.jpg](https://qiita-image-store.s3.amazonaws.com/0/105071/107d4a56-280f-f72e-0c88-29a9cbf9ea10.jpeg)

After

![advisor2.jpg](https://qiita-image-store.s3.amazonaws.com/0/105071/b72984b8-11bf-6860-2288-a9bab6d1697a.jpeg)

## 資料や発表

ADvisorについては以下に詳しいです．

- 宮元 景冬. "ADvisor機能を応用した有害画像の視覚的規制", [BitVisor Summit 4](https://www.bitvisor.org/summit4/), 2015年11月.

- 平井 成海. "SSLWatcher: SSL/TLS通信を監視し警告するハイパバイザ", [BitVisor Summit 4](https://www.bitvisor.org/summit4/), 2015年11月. [PDF](https://www.bitvisor.org/summit4/slides/bitvisor-summit-4-8-hirai.pdf)

- 大山 恵弘. "ハイパバイザによる災害警報通知", 第14回情報科学技術フォーラム, pages 213-216, 2015年9月.

- Yoshihiro Oyama. "A Hypervisor for Manipulating Guest Screens", In poster session in [the 6th ACM SIGOPS Asia-Pacific Workshop on Systems (APSys 2015)](http://www.sslab.ics.keio.ac.jp/apsys2015/), July 2015. [Abstract](http://www.sslab.ics.keio.ac.jp/apsys2015/assets/posters/4.pdf)

- Yoshihiro Oyama, Natsuki Ogawa, Yudai Kawasaki, Kazuhiro Yamamoto.  "ADvisor: A Hypervisor for Displaying Images on a Desktop", In Proceedings of the 2nd International Workshop on Computer Systems and Architectures (CSA '14), held in conjunction with the 2nd International Symposium on Computing and Networking (CANDAR 2014), pages 412-418, December 2014. [Paper](http://dx.doi.org/10.1109/CANDAR.2014.43)

- 山本 航洋. "ネットワークによるADvisor機能の拡張", [BitVisor Summit 2](http://www.bitvisor.org/summit2/), 2013年12月. [PDF](http://www.bitvisor.org/summit2/slides/bitvisor-summit-2-08-yamamoto.pdf)

- 大山 恵弘, 河崎 雄大. "BitVisorを用いたメッセージ表示システム", [BitVisor Summit](http://www.bitvisor.org/summit/), 2012年12月. [PDF](http://www.bitvisor.org/summit/slides/BitVisor-Summit-06-oyama.pdf)

- 小川 夏樹, 大山 恵弘. "ADvisor: ゲストOSの操作に連動した広告を表示するハイパバイザ", 情報処理学会2011年並列／分散／協調処理に関する『鹿児島』サマー・ワークショップ（SWoPP鹿児島2011）, 2011年7月. [論文](http://id.nii.ac.jp/1001/00075279/)

- 大山 恵弘. "ハイパバイザによる広告表示", 第9回情報科学技術フォーラム, pages 341-342, 2010年9月.