QEMUをビルドしてHinaOSを動かした

自作OS RISC-V

今回は、QEMUをビルドして、他の人の自作OSを実行してみようというものです。少しだけ躓くポイントがあるので、解消ポイントも書いておきます。RISC-V対応OSを自作しようと思っていたら、どストライクな本が発売されていました。『自作OSで学ぶマイクロカーネルの設計と実装』(秀和システム、ISBN: 978-4-7980-6871-8)で紹介されているHinaOSは、教育向けマイクロカーネルOSです。RISC-Vに対応しており、マルチコア対応やファイルシステムの実装などが特徴です。自分のRISC-V対応OSにもかなり参考になるものと思っています。参考にするにはまず動かしてどんなことが出来るのか見てみようということで、実際に動かしてみます。実際の本は以下の画像のリンク先から購入できます。とても良い本なので是非。

https://github.com/nuta/microkernel-book

ただ動かすだけでは面白みが無いと思うので、QEMUの勉強を兼ねて、QEMUのビルドからやっていこうと思います。QEMUは、仮想マシンをエミュレートするソフトウェアです。今回は、RISC-Vの仮想マシンをエミュレートするために使用します。

QEMUのビルド(これだとOSの起動に失敗します)

せっかくなので、最新の安定版である、8.0.0をビルドします。まず、ソースコードをダウンロードしてきます。

wget https://download.qemu.org/qemu-8.0.0.tar.xz
tar xvJf qemu-8.0.0.tar.xz
cd qemu-8.0.0

次にいつも通りconfigureしたいのですが、オプションがよくわからないので、configure --helpを見てみます。

./configure --help

すると以下のように丁寧なオプションの説明が出てきます(後半は省略)。今回はprefixとtarget-listでriscv32-softmmuを設定するだけで良さそうです。

Usage: configure [options]
Options: [defaults in brackets after descriptions]

Standard options:
  --help                   print this message
  --prefix=PREFIX          install in PREFIX [/usr/local]
  --target-list=LIST       set target list (default: build all)
                           Available targets: aarch64-softmmu alpha-softmmu
                           arm-softmmu avr-softmmu cris-softmmu hppa-softmmu
                           i386-softmmu loongarch64-softmmu m68k-softmmu
                           microblaze-softmmu microblazeel-softmmu mips-softmmu
                           mips64-softmmu mips64el-softmmu mipsel-softmmu
                           nios2-softmmu or1k-softmmu ppc-softmmu ppc64-softmmu
                           riscv32-softmmu riscv64-softmmu rx-softmmu
                           s390x-softmmu sh4-softmmu sh4eb-softmmu
                           sparc-softmmu sparc64-softmmu tricore-softmmu
                           x86_64-softmmu xtensa-softmmu xtensaeb-softmmu
                           aarch64-linux-user aarch64_be-linux-user
                           alpha-linux-user arm-linux-user armeb-linux-user
                           cris-linux-user hexagon-linux-user hppa-linux-user
                           i386-linux-user loongarch64-linux-user
                           m68k-linux-user microblaze-linux-user
                           microblazeel-linux-user mips-linux-user
                           mips64-linux-user mips64el-linux-user
                           mipsel-linux-user mipsn32-linux-user
                           mipsn32el-linux-user nios2-linux-user
                           or1k-linux-user ppc-linux-user ppc64-linux-user
                           ppc64le-linux-user riscv32-linux-user
                           riscv64-linux-user s390x-linux-user sh4-linux-user
                           sh4eb-linux-user sparc-linux-user
                           sparc32plus-linux-user sparc64-linux-user
                           x86_64-linux-user xtensa-linux-user
                           xtensaeb-linux-user
  --target-list-exclude=LIST exclude a set of targets from the default target-list

Advanced options (experts only):
  --cross-prefix=PREFIX    use PREFIX for compile tools, PREFIX can be blank []
  --cc=CC                  use C compiler CC [cc]
  --host-cc=CC             use C compiler CC [cc] for code run at
...
./configure --prefix=/path/to/qemu --target-list=riscv32-softmmu
make -j$(nproc)
make install

これで、QEMUのビルドは完了です。/path/to/qemu/binqemu-system-riscv32が生成されているはずです。 最後に、~/.bashrcに以下のようにパスを通しておきます。

export PATH=$PATH:/path/to/qemu/bin

HinaOSの環境構築(QEMU以外)

QEMU以外に関しては、READMEに従っておきましょう。ただし、Pythonの環境を破壊しないように、ここではvenvを使用します。

sudo apt update
sudo apt install llvm clang lld python3-pip python3-venv gdb-multiarch git
git clone https://github.com/nuta/microkernel-book.git
cd microkernel-book
# 仮想環境を作成
python3 -m venv .env
# 仮想環境を有効化
source .env/bin/activate
# 仮想環境に必要なパッケージをインストール
pip install -r requirements.txt
# HinaOSのビルド
make -j$(nproc)

驚くことに、一瞬でビルドが終わります。実行してみると、以下のようなエラーが出ます。

qemu-system-riscv32: -netdev user,id=net0: network backend 'user' is not compiled into this binary
make: *** [Makefile:176: run] Error 1

QEMUの再ビルド

なんか、network backend ‘user’がないとか言われています。よくわからないので、調べてみるとstack overflowに解決策がありました。どうやら、QEMUをビルドするときに--enable-slirpをつける必要があるようです。というわけで、QEMUを再ビルドします。

./configure --prefix=/path/to/qemu --target-list=riscv32-softmmu --enable-slirp

また、エラーが出ます。

E: Unable to locate package libslirp

libslirpがないみたいなので、入れてあげましょう。ubuntuでは、libslirp-devというパッケージになっているようです。

sudo apt install libslirp-dev

もう一回、QEMUをビルドします。

./configure --prefix=/path/to/qemu --target-list=riscv32-softmmu --enable-slirp
make -j$(nproc)
make install

これで、HinaOSも動くようになるはずです。

HinaOSを動かしてみる

make run

いい感じですね。catlsも動くみたいです。

    UPDATE  build/consts.mk
       GEN  build/compile_commands.json

Kernel Executable: build/hinaos.elf (3733 KiB)
BootFS Image:      build/bootfs.bin (3016 KiB)
HinaFS Image:      build/hinafs.img (131072 KiB)
      QEMU  build/hinaos.elf
Booting HinaOS...
[kernel] free memory: 803bd000 - 88000000 (124MiB)
[kernel] MMIO memory: 10001000 - 10002000 (4KiB)
[kernel] MMIO memory: 10002000 - 10003000 (4KiB)
[kernel] created a task "vm" (tid=1)
[kernel] bootelf: 32000000 - 3200c8ac r-x (50 KiB)
[kernel] bootelf: 3200d000 - 3234148a r-- (3281 KiB)
[kernel] bootelf: 32342000 - 32789118 rw- (4380 KiB)
[kernel] CPU #0 is ready
[vm] bootfs: found following 9 files
...
[fs] successfully loaded the file system
[vm] service "fs" is up
[fs] ready

Welcome to HinaOS!

shell> ls
[shell] Contents of /:
[fs] block 7 is not in cache, reading from disk
[shell] [FILE] "hello.txt"
shell> c
shell> cat hello.txt
[fs] block 6 is not in cache, reading from disk
[shell] Hello World from HinaFS!

QEMUでregisterの状態を見てみる。

Ctrl-A + CでQEMUのモニタに入ります。こんな感じで、レジスタの状態を見ることができます。

(qemu) info registers
CPU#0
 V      =   0
 pc       800098b2
 mhartid  00000000
 ...
 x0/zero  00000000 x1/ra    800098a2 x2/sp    803b0e70 x3/gp    00000000
 x4/tp    803ac3d0 x5/t0    803a0e00 x6/t1    803a0d60 x7/t2    00000000
 x8/s0    803b0e80 x9/s1    803ac3f8 x10/a0   00040022 x11/a1   0000c0be
 x12/a2   000012ab x13/a3   000012ab x14/a4   00000000 x15/a5   803a0da0
 x16/a6   803a0e20 x17/a7   803a0de0 x18/s2   80011404 x19/s3   803a4560
 x20/s4   80054094 x21/s5   00448000 x22/s6   00000006 x23/s7   80054088
 x24/s8   00000016 x25/s9   80054034 x26/s10  00000006 x27/s11  807ae000
 x28/t3   00000000 x29/t4   00000000 x30/t5   00000000 x31/t6   00000000
 f0/ft0   0000000000000000 f1/ft1   0000000000000000 f2/ft2   0000000000000000 f3/ft3   0000000000000000
 f4/ft4   0000000000000000 f5/ft5   0000000000000000 f6/ft6   0000000000000000 f7/ft7   0000000000000000
 f8/fs0   0000000000000000 f9/fs1   0000000000000000 f10/fa0  0000000000000000 f11/fa1  0000000000000000
 f12/fa2  0000000000000000 f13/fa3  0000000000000000 f14/fa4  0000000000000000 f15/fa5  0000000000000000
 f16/fa6  0000000000000000 f17/fa7  0000000000000000 f18/fs2  0000000000000000 f19/fs3  0000000000000000
 f20/fs4  0000000000000000 f21/fs5  0000000000000000 f22/fs6  0000000000000000 f23/fs7  0000000000000000
 f24/fs8  0000000000000000 f25/fs9  0000000000000000 f26/fs10 0000000000000000 f27/fs11 0000000000000000
 f28/ft8  0000000000000000 f29/ft9  0000000000000000 f30/ft10 0000000000000000 f31/ft11 0000000000000000

他にも、色々なコマンドが使えます。詳しくはこちらを参照してください。 抜け出すときはCtrl-A + Xです。

まとめ

QEMUをビルドして、RISC-V対応のHinaOSを動かすことが出来ました。OSの勉強を進めつつ、自分のOSの要件定義や、設計を進めていきたいと思います。


© 2023 Yuto Nakamura   •  Theme  Moonwalk