xv6 on VirtualBox

せっかくMacBook AirVirtualBoxをインストールしたので、xv6VirtualBoxで動かそうという話(わざわざそんなことをする人はいないだろうので、誰得なわけだが)。この日記を読んでいる人には説明の必要はないだろうけど、xv6はUNIX v6をx86に移植してOS講義の教材に使おうというMITのプロジェクト。講義を重ねることでバージョンは上がっていて、最新バージョンはrev4になっている。

xv6は仮想マシン上で動かすことを想定されていて、bochsQEMUで動くように環境が整備されている。VirtualBoxで動かすには何も難しいことはなく、ディスクフォーマットをVDI形式に変換するだけでOK。

xv6のビルドにはELFを吐くツールチェイン(gccbinutilsgdb)が必要である。Linuxなら問題ないだろうけど、Mac OS Xの場合は、xv6のページにあるツールチェインをインストールする必要がある。私はLinux上でビルドしてコピーしちゃったけど。

xv6のmakeに成功するとxv6.imgとfs.imgという二つのディスクイメージが生成される。xv6.imgがブートローダからカーネル、fs.imgがxv6のファイルシステムになる。

$ VBoxManage clonehd --format vdi xv6.img xv6.vdi
$ VBoxManage clonehd --format vdi fs.img fs.vdi

そして、VirtualBoxを起動してVMを新規作成し、xv6.vdiをprimary master、fs.vdiをprimary slaveのIDEに設定する。これでOK。

xv6はVGA以外にシリアルにも出力しているので、ヘッドレスモード+シリアルコンソールできればうれしかったのだけど、現状出力が崩れてしまって使い物にならない(出力文字が欠けてしまう)。ちゃんと調べてないけどxv6のドライバを疑っている。まぁ、どこで何の役に立つかはわからないので、設定方法は残しておく。

VirtualBoxのシリアル設定には、host pipeとhost deviceの2種類のポートモードがあるが、後者はroot権限が必要なので前者を使う。このモードでは、ホストOSのUNIXドメインソケットを介してゲストOSのシリアルと通信できる。次のスクリーンショットのように設定した。

VirtualBoxのマニュアルには、UNIXドメインソケットの通信にsocatを使えとあるが、Mac OSには標準でインストールされていない。まぁ、xv6用に使うならncで十分だろう。VirtualBoxをヘッドレスモードで起動するコマンドはVBoxHeadlessである。次のようなスクリプトを書いてみた。Ctrl-dでncの接続を切ると、xv6 VMの電源を落とすようにしている。

#!/bin/sh

name=xv6
com1=/tmp/serial
port=10000
TERM=vt100

# start VM
VBoxHeadless -s $name &

# connect serial console
while [ ! -e $com1 ]; do
	sleep 1	
done

nc -U $com1
#socat UNIX-CONNECT:$com1 TCP-LISTEN:$port &
#telnet 127.0.0.1 $port

# destroy VM
VBoxManage controlvm $name poweroff

QEMUbochsだとモニタに落ちて、レジスタ見たりできるので、やっぱり学習目的だとQEMUを使うのがよいか。