作って理解する仮想化技術 ─⁠─ ハイパーバイザを実装しながら仕組みを学ぶ

「作って理解する仮想化技術」のカバー画像
著者
森真誠もりまなみ 著
品川高廣しながわたかひろ 監修
定価
3,520円(本体3,200円+税10%)
発売日
2025.9.19
判型
B5変形
頁数
336ページ
ISBN
978-4-297-15012-9 978-4-297-15013-6

概要

仮想化技術はいたるところで利用されています。クラウドサービスなどで、自由度の高いサーバ環境を即座に利用できるのは仮想化技術があってこそです。ソフトウェアで疑似的にマシンを再現したものを仮想マシンと呼び、仮想マシンを実現するソフトウェアをハイパーバイザと呼びます。

本書では、ハイパーバイザをステップアップ式に実装していくことで、ハイパーバイザによる仮想化技術がどのように実現されているのかを理解していきます。ハードウェアデバイスを操作する側、操作される側の両方の実装を行うことで、仮想化技術と密接に関係している低レイヤの技術を深く理解できます。

こんな方にオススメ

  • 仮想化技術が何を行っているのかを理解したい方
  • ハイパーバイザの仕組みを理解したい方
  • マシンの仕組みを手を動かしながら理解したい方

目次

第1章 仮想マシンとハイパーバイザ

1.1 仮想マシンとはなんだろう

  • ハードウェアとソフトウェアの基本的な関係
    • 命令セットアーキテクチャ
  • リソースの管理と権限レベル
  • リソースを抽象化し再分配する

1.2 ハイパーバイザの目的とメリット

1.3 Type1ハイパーバイザとType2ハイパーバイザ

  • 本書で自作するハイパーバイザのタイプ

1.4 仮想化支援機能とは

  • 本書で利用する仮想化支援機能

1.5 Type1ハイパーバイザを開発する流れ

  • ブートローダによる起動と文字の出力
  • 仮想化支援機能の設定とページングの実装
  • 割り込み処理の実装
  • 割り込みコントローラとデバイスドライバの実装
  • 仮想マシンを管理する枠組みの実装
  • 仮想デバイスの実装
  • マルチコア対応の実装
  • 複数の仮想マシンの起動
  • 実装したハイパーバイザからの学び

1.6 開発環境の構築

  • Ubuntu 24.04 LTSの用意
  • MiniVisor公開リポジトリのクローン
  • 必要なツールのインストール
  • QEMUのビルドとインストール

1.7 本書で使用する仕様書について

  • Arm社の仕様書
  • その他仕様書

第2章 起動してメッセージを出せるようにする

2.1 何もしないソフトウェアを起動しよう

  • 最初に知っておいてほしいこと ── レジスタとスタック
  • メモリアドレスとは何か
  • OSの機能が使えないとは
  • ブートローダから起動する最低限のソフトウェア
  • リンカスクリプトの作成
  • U-Bootのビルド
  • ブートスクリプトの作成
  • 実行

2.2 DTBを解析しよう

  • 文字を出すデバイスと文字の送り方
  • デバイス情報の取得 ── Devicetree
    • DTBとDTS
  • DTSの読み方
  • DTBをソフトウェアで処理する

2.3 文字を出そう

  • デバイスドライバの実装
  • SerialDeviceトレイトとprintlnマクロの定義
  • 起動処理の追加
  • 起動スクリプトの更新
  • 実行

第3章 CPUの仮想化支援機能を使ってみる〜メモリを仮想化する

3.1 何もしない仮想化をしよう

  • 最小限の仮想化処理をする意義
  • 現在の例外レベルの確認
    • システムレジスタにアクセスする方法 ── インラインアセンブリ
  • 仮想化支援機能の有効化設定
  • 例外レベルの変更
  • EL1で動作する何もしない関数
  • 実行
  • QEMUモニタによる動作確認

3.2 メモリ管理をしよう

  • RAMのアドレスを取り出す
  • 使用しているメモリ領域の予約
    • DTB領域の予約
    • ELFプログラムヘッダの解析
    • ハイパーバイザ自体のメモリ領域の予約
    • スタック領域の予約
  • ブートスクリプトの変更

3.3 メモリの仮想化をしよう

  • メモリの仮想化とは
  • 仮想メモリの意義
    • 複数のソフトウェアをメモリに配置する際の問題点
    • 仮想メモリによる複数ソフトウェアの配置
    • メモリアクセスを変換表を管理するソフトウェアに移行できる
  • ページングの概要
    • 2段階ページングによるハイパーバイザでのページング
  • ページテーブルの構造
  • AArch64におけるページングの実装
    • Translation tableとLevelについて
    • Table descriptorの構造
    • Page descriptorとBlock descriptorの構造
    • ページの属性の設定
  • Descriptorの実装
  • Translation tableの初期化
    • システムレジスタの設定 ── VTCR_EL2とVTTBR_EL2
  • アドレスのマップ処理の実装
    • Page descriptorの処理
    • Block descriptorとTable descriptorの処理
    • Stage 2 Translationの初期化処理
  • 実行

第4章 割り込みの仕組みと仮想デバイスを作る

4.1 割り込みのセットアップをしよう

  • 割り込みの種類
  • 本書における例外と割り込み
  • AArch64での例外処理の流れ
  • 例外テーブルの作成
    • [column]br命令とret命令
  • 例外ハンドラの作成

4.2 ページフォルトの原因を解析しよう

  • 例外テーブルの登録
    • [column]スタックポインタとゼロレジスタ
  • EL1でのメモリアクセスの追加
  • 実行

4.3 仮想PL011デバイスを実装しよう

  • 仮想デバイスを実装するということ
  • 仮想デバイスの実装
  • 実行
  • 仮想デバイスで実験

第5章 割り込みコントローラを制御し、デバイス割り込みを可能にする

5.1 割り込みを制御するデバイスを初期化しよう

  • デバイス割り込みとは
  • 割り込みコントローラとは
  • 使用する割り込みコントローラ
  • Distributorの初期化
  • 割り込みのセットアップ
    • 割り込み優先度の設定
    • 割り込みグループの設定
    • 割り込みのトリガモードの設定
    • 割り込み先の設定
    • 割り込みの有効化
  • Redistributorの初期化
  • 割り込みハンドラの実装
  • 割り込みコントローラの検出
  • 割り込み先の設定
  • 実行

5.2 PL011の割り込みを受け取ろう

  • デバイスからの割り込みの有効化
  • PL011の割り込みハンドラの実装
  • 割り込み番号の取得
  • PL011の割り込みの有効化
  • 実行

第6章 ファイルの読み書きをできるようにする

6.1 Virtio-Blkを制御しよう

  • ゲストOSの読み込み方
  • ブロックデバイスと通信規格
  • Virtioとは
  • Virtioの基本
  • Virtio Over MMIOの基本
  • VirtQueueの構造
  • Virtioドライバの実装
  • VirtQueueの初期化の実装
  • Virtio-Blkの読み書き
  • Virtio-Blkの検出
  • 実行

6.2 ファイルシステムを実装しよう

  • ファイルシステムの意味
  • パーティションテーブルの構造
  • パーティションテーブルの解析
  • ファイルシステムの解析
  • ディレクトリエントリの解析
    • [column]ASCIIとShift_JIS
  • ファイルの読み出しの実装
  • ファイル読み込みのテスト
  • ディスクイメージの作成
  • 実行

第7章 初めての仮想マシンを実装する

7.1 VM構造体を実装しよう

  • VM構造体の定義
  • 仮想PL011デバイスの再実装
  • 例外ハンドラの再実装
  • 仮想マシンの起動処理の実装
  • メモリ管理機能の追加
  • 実行

7.2 VMを起動してみよう

  • Linuxのブート処理
  • Linux Kernelの用意
  • 仮想マシン用のDevicetreeの準備
  • Linux Kernel Imageの解析
  • 実行
    • [column]Imageの先頭の8バイトの意味

第8章 Linuxが動作するようにする

8.1 GICv3の仮想化をしよう

  • 仮想割り込みの仕組み
  • VGICの仕組みと実装
  • 仮想割り込みコントローラのインタフェースの作成
  • 仮想割り込みの挿入処理の実装
  • その他処理の実装
  • 実行

8.2 仮想タイマを提供しよう

  • Generic Timerの概要
  • Generic Timerの初期化
  • Generic Timerの割り込み処理
  • 実行

8.3 仮想PL011を改良しよう

  • レジスタの追加実装
  • 入力と割り込みの実装
  • 実行

8.4 Virtio-Blkデバイスを実装しよう

  • Virtio-Blkデバイスの実装
  • イメージファイルの操作処理の実装
  • イメージファイルの読み込みの実装
  • 実行
  • ここまでを振り返って

第9章 複数のCPUコアを動作させる

9.1 コアの起動をしよう

  • PSCIのバージョン確認
  • PSCIによるCPUコアの起動
  • 全CPUコアの起動
  • CPUコアの起動処理
  • 実行

9.2 ロック機構を実装しよう

  • スピンロックの仕組み
  • Mutex構造体の実装
  • Compare And Swapの仕組み
    • [column]CASの実装について
  • メモリオーダの意味
  • ロックしたデータへのアクセス
  • グローバル変数へのMutexの適用
  • 実行

第10章 コンソールとマルチ仮想マシンを実装する

10.1 コンソールとコマンドを実装しよう

  • コンソールへの入力の実装
  • コマンド実行部分の実装
  • echoコマンドの実装
  • poweroffコマンドの実装
  • 入力の切り替えの実装
  • 実行

10.2 マルチ仮想マシンを実現しよう

  • CPUコア起動処理の拡充
  • マルチ仮想マシンの管理の対応
  • 仮想割り込みのマルチ仮想マシン対応
  • 仮想マシン管理用コマンドの実装
  • 実行
  • ここまでを振り返って

第11章 作成したハイパーバイザを発展させるには

11.1 対応デバイスの追加

11.2 独自の仮想デバイス

11.3 スナップショット機能

11.4 実機への移植

11.5 マイグレーション機能

11.6 デバイスパススルー機能

11.7 Type2ハイパーバイザの実装

11.8 Nested Virtualizationの実装

第12章 仮想化技術を使いこなす

12.1 ハイパーバイザの選び方

  • ハイパーバイザとエミュレータ
    • [column]エミュレータとしてのQEMU(難易度高め)
  • Type1ハイパーバイザとType2ハイパーバイザ
    • [column]AArch64でのType2ハイパーバイザ
  • 完全仮想化デバイスと準仮想化デバイスの比較
  • コンテナとの比較

12.2 ハイパーバイザの便利な使い方

  • テストやデバッグ
  • マルウェアの解析
  • 軽量ハイパーバイザ

12.3 これからのハイパーバイザ

  • クラウドと機密仮想マシン
  • 組み込みシステムと仮想化技術

プロフィール

森真誠もりまなみ

小学生時代からプログラミングに興味を持ち、OSからデスクトップアプリなど幅広いレイヤのプログラミングを趣味で行う。

大学生のときにAArch64向けの軽量ハイパーバイザ「MilvusVisor」の実装に従事。

また、セキュリティ・キャンプ全国大会での講師や世界的に権威あるカンファレンスの一つであるBlack Hat Eurpose 2024で機密仮想マシンに関する講演などを経験。

品川高廣しながわたかひろ

東京大学大学院情報理工学系研究科 教授。

オペレーティングシステムや仮想化技術、コンピュータセキュリティ等を専門とし、次世代の安全で高性能なシステム基盤の研究開発に取り組んでいる。

国産ハイパーバイザ「BitVisor」のチーフアーキテクトとして設計を主導し、その成果を応用した製品「vThrii Seamless Provisioning」の開発にも貢献している。

仮想化技術の研究成果により、令和2年度科学技術分野の文部科学大臣表彰「科学技術賞」を受賞した。

https://www.os.is.s.u-tokyo.ac.jp/shina/