ASUS Chromebook Flip C302CA 上の Crouton(Ubuntu) に、VirtualBox (x86) をインストールするには

## Crouton で、VirtualBox を動かすための前提条件
- VirtualBox を使用するには、vboxdrv.ko など 専用カーネルモジュールのコンパイルが必要。
- その為には、Chromebook の Linuxカーネルバージョン(chrootなので、Crouton(Ubuntu)側でも同じバージョン)に合致するカーネルヘッダなどが無ければならない。
- Chromebook の Linuxカーネルアップデートのたびに、これらの作業が必要。

つまり、これらをやってでも 上の環境で VirtualBox を動かしたい人のみ、自己責任で 以下を実行してください。


## Ubuntu で カーネルヘッダ・イメージを コンパイル・インストールする
引用元：
https://github.com/dnschneid/crouton/wiki/Build-kernel-headers-and-install-Virtualbox-(x86)

コンパイルの為の 事前準備。

```sh
(ubuntu)$ sudo apt-get install git-core make kernel-package bc
(ubuntu)$ sudo add-apt-repository ppa:ubuntu-toolchain-r/test
(ubuntu)$ sudo apt-get update
(ubuntu)$ sudo apt-get install g++-4.9
(ubuntu)$ sudo rm /usr/bin/gcc
(ubuntu)$ sudo ln -s /usr/bin/gcc-4.9 /usr/bin/gcc
```
```sh
(ubuntu)$ uname -r
3.18.0-17554-g9194949d4df2
(ubuntu)$ cd ~
(ubuntu)$ git clone https://chromium.googlesource.com/chromiumos/third_party/kernel -b chromeos-3.18
```

ブラウザで 上のURLを開き、合致するバージョンを確認・指定し、カーネルソースを ホームディレクトリにコピーする。

```sh
(ubuntu)$ cd kernel
(ubuntu)$ ./chromeos/scripts/prepareconfig chromeos-intel-pineview
(ubuntu)$ make oldconfig
(ubuntu)$ make kernelrelease
　〜
3.18.0-18111-g67722d7
```

ここで、表示されるバージョンが、現在のカーネルバージョンと合わないはず。

```sh
(ubuntu)$ uname -r
3.18.0-17554-g9194949d4df2
(ubuntu)$ git reset --hard origin/chromeos-3.18
(ubuntu)$ git checkout HEAD~17554-g9194949d4df2
```

チルダ以降に、現在のカーネルバージョンのリビジョンを つなげて入れる。

```sh
(ubuntu)$ ./chromeos/scripts/prepareconfig chromeos-intel-pineview
(ubuntu)$ make oldconfig
(ubuntu)$ make kernelrelease
　〜
3.18.0-17554-g9194949
```

一応、リビジョンの 前半部分は一致するが、完全に同じになっていない。
カーネルヘッダをインストールするには、完全に同じリビジョンでなければならない。

```sh
(ubuntu)$ vi scripts/setlocalversion
```

「 -dirty」(半角スペース＋ハイフン＋アルファベット)で検索し、リビジョン後半の、切れている、上で言えば「d4df2」に置き換える。２箇所ある。

```sh
(ubuntu)$ vi chromeos/config/base.config
```

ここで、「CONFIG_ERROR_ON_WARNING」を探し、「n」に変える。

```sh
(ubuntu)$ ./chromeos/scripts/prepareconfig chromeos-intel-pineview
(ubuntu)$ make oldconfig
(ubuntu)$ make-kpkg --rootcmd fakeroot kernel_image kernel_headers
　〜
drivers/gpu/drm/udl/udl_connector.c:17:27: fatal error: udl_connector.h: そのようなファイルやディレクトリはありません
　〜
```

コンパイル途中で、ヘッダファイルが見つからないエラーになる。

```sh
(ubuntu)$ vi drivers/gpu/drm/udl/udl_connector.c
```
`drivers/gpu/drm/udl/udl_connector.c`の中の include文「udl_connector.h」を、<> から "" に変える。
再度、コンパイル。

```sh
(ubuntu)$ make-kpkg --rootcmd fakeroot kernel_image kernel_headers
　〜
/etc/kernel/postinst.d/apt-auto-removal: 84: /etc/kernel/postinst.d/apt-auto-removal: cannot create
/etc/apt/apt.conf.d//01autoremove-kernels.dpkg-new: Permission denied
run-parts: /etc/kernel/postinst.d/apt-auto-removal exited with return code 2
make[3]: *** [install] エラー 1
make[2]: *** [install] エラー 2
make[2]: ディレクトリ ``/home/kuri/kernel' から出ます
make[1]: *** [debian/stamp/install/linux-image-3.18.0-17554-g9194949d4df2] エラー
make[1]: ディレクトリ ``/home/kuri/kernel' から出ます
make: *** [kernel_image] エラー 2
```

コンパイルの後半で、ROOT権限がなくて エラーになる為、sudo で再実行する。

```sh
(ubuntu)$ sudo make-kpkg --rootcmd fakeroot kernel_image kernel_headers
(ubuntu)$ cd ~
(ubuntu)$ sudo vi /etc/rc.local
```

```bash
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
# umount bindmounts /lib/modules from enter-chroot
for m in `cat /proc/mounts | /usr/bin/cut -d ' ' -f2 | grep /lib/modules| grep -v "^/$" `; do
        umount "$m"
done
# try to load vboxdrv modules
if [ `find /lib/modules/"\`uname -r\`" -name vboxdrv.ko` ]; then
    # check if module_locking is disabled
    if ! grep -q "module_locking=0" /proc/cmdline; then
        exit 2
    fi
    modprobe vboxdrv
    modprobe vboxpci
    modprobe vboxnetadp
    modprobe vboxnetflt
fi
exit 0
```
```sh
(ubuntu)$ sudo chmod +x /etc/rc.local
```

Ubuntuを再起動する。
/lib/modules がアンマウントされ、書き込み可能状態になるので、コンパイルしたパッケージをインストールする。

```sh
(ubuntu)$ sudo dpkg -i linux-headers-3.18.0-17554-g9194949d4df2_3.18.0-17554-g9194949d4df2-10.00.Custom_amd64.deb
(ubuntu)$ sudo dpkg -i linux-image-3.18.0-17554-g9194949d4df2_3.18.0-17554-g9194949d4df2-10.00.Custom_amd64.deb
```
## VirtualBox ダウンロードサイトから、最新版をダウンロードし、インストールする
Ubuntu のバージョンに合致するファイルを、ダウンロード・インストールする。
https://www.virtualbox.org/wiki/Linux_Downloads

```sh
(ubuntu)$ sudo apt-get -f install
(ubuntu)$ sudo apt-get install libopus0
(ubuntu)$ sudo dpkg -i ダウンロード/virtualbox-5.2_5.2.16-123759~Ubuntu~trusty_amd64.deb
```

## Chromebookで、VT-x 有効化し 再起動する
VT-x の有効化(カーネルオプションの変更)は、失敗すると システム起動しなくなり、リカバリメディアからリカバリすることになる危険性が あります。

有効化する前に データのバックアップと、本番運用する前の 動作検証を 十分に行ってください。
また、標準で付属している Chromebook リカバリ ユーティリティ を使って、リカバリメディアを作ってください。
これが無いと、起動できなくなったら ASUS のサイトから 機種名などを指定してダウンロードすることになり、かなり面倒です。
有効化した場合、通常起動や 強制電源断後の再投入などで、ブートが出来ない可能性が高い ようです。
私の環境では、reboot コマンドで リブートすれば大丈夫そう。

その為、インストールした Crouton を [SDカードなどに移動して、そこから起動できるようにしておく](https://qiita.com/shinya-kurioka/items/f563bd51c2a897f8d937#croutonubuntu%E9%A0%98%E5%9F%9F%E3%82%92sd%E3%82%AB%E3%83%BC%E3%83%89%E7%AD%89-%E5%88%A5%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%AB%E7%A7%BB%E5%8B%95%E3%81%95%E3%81%9B%E3%81%9D%E3%81%A1%E3%82%89%E3%81%8B%E3%82%89%E8%B5%B7%E5%8B%95%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95)ことをお勧めします。([方法は 後述](https://qiita.com/shinya-kurioka/items/f563bd51c2a897f8d937#croutonubuntu%E9%A0%98%E5%9F%9F%E3%82%92sd%E3%82%AB%E3%83%BC%E3%83%89%E7%AD%89-%E5%88%A5%E3%83%87%E3%83%90%E3%82%A4%E3%82%B9%E3%81%AB%E7%A7%BB%E5%8B%95%E3%81%95%E3%81%9B%E3%81%9D%E3%81%A1%E3%82%89%E3%81%8B%E3%82%89%E8%B5%B7%E5%8B%95%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%88%E3%81%86%E3%81%AB%E3%81%99%E3%82%8B%E6%96%B9%E6%B3%95))
こうしておけば、Chromebookの内部ストレージをリカバリしても Crouton の領域は 別デバイスにそのまま残るので、Crouton まで再インストール・環境再構築する必要が無くなります。

情報として、[スリープからの復帰時にクラッシュする](https://qiita.com/meganetaaan/items/d7b1544f6cac8460b490)という話もあるらしいので、必要に応じて、フタを閉じても スリープしないように設定したり、
　[Keep Awake - Chrome ウェブストア](https://chrome.google.com/webstore/detail/keep-awake/bijihlabcfdnabacffofojgmehjdielb)
みたいな機能拡張で スリープしないようにする必要があるかもしれません。

ただ、私の環境では、確かに スリープからの復帰時、
　Chromebook側からは SDカードが アンマウントされているのですが、Ubuntu側は クラッシュしないので、
機種や 使用環境・使用方法に 依存する問題かもしれません。
ご自分の環境で問題ないか ご確認のうえ、必要に応じて対応してください。

VT-x 有効化するには、Chromebookで、以下から enable-vmx.sh をダウンロードし、crosh の shellコマンド内でROOTで実行し、マシンを再起動する。
https://gist.github.com/DennisLfromGA/cd3455530cec2a5a1ef4

私の場合、ゲストとして 32ビットOS しか、うまく動かなかった。
VT-x が うまく有効になっていないのかも知れない。

---
## <a name="SD">Crouton(Ubuntu)領域を、SDカード等 別デバイスに移動させ、そちらから起動できるようにする方法</a>
１，SDカードを ext4 などでフォーマットする。
　df コマンドなどで、デバイスファイルを確認の上、ファイルシステム作成します。

```sh:crosh.shell
$ sudo umount /dev/mmcblk1p1
$ sudo mkfs -t ext4 -L UNITY /dev/mmcblk1p1
```

２，SDカードを挿し直すと `/media/removable/UNITY` にマウントされるはずなので、
　`/mnt/stateful_partition/crouton/chroots` を、SDカードに移動する。

```sh:crosh.shell
$ sudo mv /mnt/stateful_partition/crouton/chroots /media/removable/UNITY/
```

３，/usr/local/bin も、SDカードに移動する。

```sh:crosh.shell
$ sudo mv /usr/local/bin /media/removable/UNITY/
```

４，/mnt/stateful_partition/crouton と /usr/local に、SDカードの chrootsディレクトリへの シンボリックリンクを張り直す。

```sh:crosh.shell
$ cd /mnt/stateful_partition/crouton/
$ sudo ln -s /media/removable/UNITY/chroots .
$ cd /usr/local/
$ sudo ln -sf /media/removable/UNITY/chroots .
```

５，/usr/local/bin に、SDカードから ディレクトリごと、コピーする。

```sh:crosh.shell
$ cd /usr/local/
$ sudo cp -Rdp /media/removable/UNITY/bin .
```

あとは 通常通り、`sudo startunity` などとすれば、Ubuntu が SD からブートできます。

Chromebook を リストアして、Crouton も元通りにしたい場合には、４以降をやり直すだけで 問題ありません。
再セットアップ用スクリプトは 以下の通り。

```bash:crouton_setup.sh
#!/bin/sh

sudo mkdir -p /mnt/stateful_partition/crouton/
cd /mnt/stateful_partition/crouton/
sudo ln -sf /media/removable/UNITY/chroots .
cd /usr/local/
sudo ln -sf /media/removable/UNITY/chroots .
sudo cp -Rdp /media/removable/UNITY/bin .

exit 0
```