Rust 製 OS の Redox を Windows 上で動かす

# Redox とは

https://www.redox-os.org/

Rust 製の Unix Like OS 。
以下、公式サイトより引用。

- Implemented in Rust
- Microkernel Design
- Includes optional GUI - Orbital
- Supports Rust Standard Library
- MIT Licensed
- Drivers run in Userspace
- Includes common Unix commands
- Newlib port for C programs

開発は Github 上で進められている。
https://github.com/redox-os/redox

公式ドキュメントも充実。
https://doc.redox-os.org/book/

# とにかく動かしてみたい

ということで、公式の Get Start に沿って進めてみる。

## 仮想マシンで動作

https://doc.redox-os.org/book/getting_started/try_vm.html

[Github Release](https://github.com/redox-os/redox/releases) に、 `redox_VERSION.bin.gz` という名前でそのバージョンの OS の入った仮想 HDD イメージが公開されているので、これを読み込んで実行させるのが一番手っ取り早い。 

## 物理マシンで動作

https://doc.redox-os.org/book/getting_started/real_hardware.html

[Github Release](https://github.com/redox-os/redox/releases) では、ブータブルな Live ISO も提供されていて、物理マシンでも動かせるらしいが、なんか色々制約がありそう。

# 仮想マシンの構築

ということで、まずは仮想マシンでやってみることに。
公式サイトでは、QEMU を使う方法を推奨されているが。

さて、QEMU とは。

## QEMU

OSS のハードウェアエミュレータ。
仮想化技術は、大きく分けて Native 型と Host 型に分けられるが、QEMU は Host 型に分類される。

| Native | Host |
|:-------:|:-------:|
| Hyper-V<br/>KVM<br/>ESXi | QEMU<br/>VirtualBox<br/>VMware Workstation |

最近のハイパーバイザは、CPU 仮想化に VT-x/AMD-V の利用を前提としているものも多いが、QEMU は CPU もソフトウェア的にエミュレートすることができるので、その辺からの需要もある。

QEMU を Raspberry Pi のエミュレータに良く使うのは、ARM プロセッサをエミュレートするためだ。

普段 Host 型仮想化ツールは Windows 上でしか使わないので、QEMU と聞いても「Linux で KVM と一緒に使う何か」程度の認識だったが、[Windows にもしっかり対応していた](https://www.qemu.org/download/#windows)。

## Acceralator

ちなみに、その **KVM と一緒に使う** というのは、QEMU の CPU 仮想化の部分を KVM が担当し、VT-x/AMD-V が使えるようにするという関係性らしい。

で、驚きなのが、2018 年初めに [**Hyper-V も同様に Accelerator として使えるようになった**](https://lists.nongnu.org/archive/html/qemu-devel/2018-01/msg02742.html) という事。 

QEMU 自体にも俄然興味が出てきたぞ。
とは言え、今回は Redox。

# 続・仮想マシンの構築

Windows 上で動かそうとした場合、主に2つの方法が思いつく。

1. Github Release にある `redox_VERSION.bin.gz` を、言われた通り QEMU で動かす
2. `redox_VERSION.bin.gz` を、お気に入りの仮想化ツール用に変換し、動かす

どっちもやってみた

## 1. QEMU で起動

公式にあるコマンドは、以下 (順不同)

```bash
$ qemu-system-x86_64 -serial mon:stdio \
   -d cpu_reset -d guest_errors \
   -cpu host \
   -smp 4 \
   -m 1024 \
   -s \
   -net nic,model=e1000 -net user \
   -machine q35 \
   -device ich9-intel-hda \
   -device hda-duplex \
   -device nec-usb-xhci,id=xhci \
   -device usb-tablet,bus=xhci.0 \
   -enable-kvm \
   -drive file=redox_VERSION.bin,format=raw
```

主なオプションの意味としては、

|オプション|設定|備考|
|----|----|----|
|-cpu|CPU アーキテクチャ|`qemu-system-x86_64 -cpu help` で一覧|
|-smp|CPU コア数||
|-m|メモリ量||
|-drive|仮想HD||
|-net nic,model=e1000 -net user|ネットワーク パススルー||
|-machine|マシンタイプ指定|`qemu-system-x86_64 -machine help` で一覧|
|-device|デバイス|ich9-intel-hda : Intel HDA<br/>hda-duplex : Sound device ?<br/>nec-usb-xhci : Intel Wireless Display<br/>usb-tablet : Touch device ?|
|-serial mon:stdio|シリアルポートシステムコンソールと QEMU HMI の多重化|[・QEMU Human Monitor Interface, Example Usage](http://nairobi-embedded.org/qemu_monitor_console.html)<br/>[・QEMU Serial Port System Console](http://nairobi-embedded.org/qemu_serial_port_system_console.html)|
|-d cpu_reset<br/>-d guest_errors|デバッグ設定||
|-s|`-gdb tcp::1234` のショートハンド||
|-enable-kvm|KVM モードで起動||

どうやら、[USB HID ドライバが無いため、キーボードやマウスは使えない](https://doc.redox-os.org/book/getting_started/real_hardware.html)ようだ。

### Windows で QEMU 起動

まずは、[scoop を使って QEMU をインストール](https://qiita.com/kikuchi_kentaro/items/77793e4a21db6ffdb7cd)する

```powershell
PS> scoop install qemu
```

上記コマンドから、不要な設定を外して実行してみる。
( `:` や `,` を含むオプションは、`''` で囲む必要がある )

```powershell
PS> qemu-system-x86_64 -serial 'mon:stdio' `
   -d cpu_reset -d guest_errors `
   -cpu host `
   -smp 4 `
   -m 1024 `
   -s `
   -net 'nic,model=e1000' -net user `
   -machine q35 `
   -device ich9-intel-hda `
   -device hda-duplex `
   -device 'nec-usb-xhci,id=xhci' `
   -device 'usb-tablet,bus=xhci.0' `
   -drive 'file=redox_VERSION.bin,format=raw'
```

と、こんな感じになります。

![totuzennoshi.png](https://qiita-image-store.s3.amazonaws.com/0/20198/1e9e04d7-501d-0a3e-328a-ab37a507d50e.png)

どうやら、QEMU for Windwos のバージョン 2.12.0-rc0 には[バグがある](http://lists.gnu.org/archive/html/qemu-devel/2018-03/msg05484.html)ようだ。
QEMU をビルドし直せば行けそうだが、無理せず次のリリースを待とう :frog:

## 2. 他の仮想ツールで動かす

Github Issues を見ていると、 Virtualbox や Hyper-V で挑戦している人も結構居るので、ちょっとやってみる。

### 2.1 Hyper-V

Docker for Windows 中毒なので、まずは  Hyper-V で挑戦。

#### **● raw 形式の仮想 HDD イメージを変換する**

ダウンロードした `redox_VERSION.bin.gz` を `qemu-img` を使って、VHDX 形式に変換する。

```powershell
PS> qemu-img convert .\redox_VERSION.bin -O vhdx -o subformat=dynamic .\harddrive.vhdx 
```

で、これを元に起動してみると、以下の画面が出る。

![hyper-v.png](https://qiita-image-store.s3.amazonaws.com/0/20198/e5bdcd0f-40c8-d1ee-9fac-6169fbaba8bb.png)

ん～、よく分からん。

#### **● Live ISO から起動**

諦めて、ISO から起動することにする。
[偉大なる先駆者が似たような事をやっていた](https://github.com/ctaggart/redox/issues/1)ので、参考にやってみる。

- **設定**
    - 第一世代
    - メモリ
        - 4G (固定)
    - ネットワーク
        - なし
    - 仮想ハードディスク
        - 10G
    - ブート CD/DVD からオペレーティングシステムをインストールする
        - ダウンロードした ISO を指定

で、起動すると、しばらく bootloader が何かゴニョゴニョしている。
多分、[これ](https://doc.redox-os.org/book/getting_started/real_hardware.html)ではないかと。

> Therefore, the current ISO image uses a bootloader to load the filesystem into memory and emulates one.

終わると起動する。

![redox.png](https://qiita-image-store.s3.amazonaws.com/0/20198/e72d5219-d133-08f4-61dd-2a53bf203f5e.png)


**◆ 感触**

まず、ネットワークがつながらない。
試しに NAT 追加してみたけど駄目だった。
公式には [rtl8168d と e1000 しか対応していない](https://doc.redox-os.org/book/getting_started/real_hardware.html) らしく、その辺が問題だろうか。

### 2.2 Virtualbox

Virtualbox でも同じ様な事ができそうなので、やってみたい。

#### **● Live ISO から起動**

- **設定**
    - タイプ
        - Other
    - バージョン
        - Other/Unknown (64 bit)
    - メモリ
        - 4G
    - 仮想ハードディスク
        - VDI
        - 10G (固定)
    - ネットワーク
        - NAT
        - 82540EM
    - ストレージ/光学ドライブ
        - ダウンロードした ISO を指定
        - Live CD/DVD
        
![vbx.png](https://qiita-image-store.s3.amazonaws.com/0/20198/922156e9-111b-5b73-751b-2e3280818dde.png)


**◆ 感触**

起動めっちゃ速い。
ネットワーク繋がる。別に 82540EM でも繋がる。

#### **● raw 形式の仮想 HDD イメージを変換する**

こんなものを見つけた。

https://github.com/redox-os/redox/blob/master/mk/virtualbox.mk

ぱっと見、VBoxManage を操作して VM 作っているだけに見えるが、実は RAW 形式から VDI にしてから起動していた。

https://github.com/redox-os/redox/blob/master/mk/virtualbox.mk#L37

```makefile
     $(VBM) convertfromraw $< build/harddrive.vdi
```

なるほど、こんなやり方もあるのか。
ということで、まずは以下コマンドで VDI を作成する。

```powershell
PS> VBoxManage convertfromraw .\redox_VERSION.bin redox.vdi
```

マシンを作成する。
新規マシン作成時、作成した VDI は直接読み込まず、後からアタッチするので注意。

- **設定**
    - タイプ
        - Other
    - バージョン
        - Other/Unknown (64 bit)
    - メモリ
        - 2G
    - ストレージ
        - IDE は空
        - SATA コントローラ追加
            - タイプ : AHCI
            - ポート : 1
            - ハードディスクを追加
                - 変換した VDI を追加
    - ネットワーク
        - NAT
        - 82540EM

これで ISO 同様に起動ができた。
ファイルも永続化している。

# Redox 使用感

POSIX っぽいし、ファイルシステムも Linux っぽい。最低限の事はできる。

GUI はまだオマケだった。
ブラウザの URL を変更する方法すら分からなかった。

今はまだそういう段階なんだろうと言う感じ。

# 他の Rust 製 OS

## Blog OS

https://os.phil-opp.com/
https://github.com/phil-opp/blog_os

## Reenix

https://github.com/scialex/reenix

# 感想

かかった時間の半分以上が Redox 自身ではなく、QEMU 含む仮想化技術についての学習になってしまった。
( 元々 OS, Kernel 周りは苦手というのもあるが )

Redox の OS 設計部分の面白さを感じられるように、もう少し追いかけていきたい。

# 参考

## Redox

- [Redox OS Kernelのコーディングガイドラインが示唆に富んでいたのでメモ - Qiita](https://qiita.com/hogemax/items/6f9737a5f757497fba709)

## QEMU 

- [QEMU - ArchLinux](https://wiki.archlinux.jp/index.php/QEMU)
- [QEMU - Gentoo Linux](https://wiki.gentoo.org/wiki/QEMU)
- [イメージ形式の変換 - OpenStack](https://docs.openstack.org/ja/image-guide/convert-images.html)
- [QEMUで作成可能な仮想ディスクファイルフォーマット 比べてみた - Qiita](https://qiita.com/pixie-grasper/items/e57c7bfb1d58bd4b241b)

## KVM と QEMU

- [KVM のサーバ仮想化技術](http://www.fujitsu.com/downloads/JP/archive/imgjp/jmag/vol62-1/paper18.pdf)