前回の続き。前回は
- QEMU for RISC-V のビルド実行
- Fedora の vmlinux, bbl, ディスクイメージをダウンロード (http://msyksphinz.hatenablog.com/entry/2018/05/07/040000)
まで実施した。次に、フルスクラッチからこれらの環境を作るために以下のことをやっていきたい。
- vmlinux のフルスクラッチビルド (ソースコードからコンパイルしてvmlinuxを作る)
- BBLをフルスクラッチビルド (ソースコードからコンパイルしてBBL)を作る
ディスクイメージの自作 (BusyBoxを使用して基本的なコマンドが実行できるような環境を作る)
と 4. を試行した。
--
RISC-V の vmlinux と BBLを生成する
BBLというのはBerkeley Boot Loaderのことで、Linuxや各種プログラムを起動させるためのブートローダだ。 x86でいうところの GRUB のようなものだろうか。
BBLを作るためには、vmlinux を先にビルドし、--with-payload
でvmlinuxを取り込みながらBBLを作る必要があるらしい。
以下のriscv-toolsの資料を参考にした。
rsicv64-unknown-elf では、Linuxを起動するためのBBLは作れない
最初にかなり試行錯誤したのだが、まず気をつけなければならないのは riscv64-unknown-elf-gcc でコンパイルしても正しく動作する BBL を生成することができない。 専用の riscv64-unknown-linux-gnu-gcc でコンパイルする必要がある。
riscv64-unknown-linux-gnu-gcc の作り方
riscv64-unknown-elf-gcc の作り方は簡単だ。 riscv-tools
をダウンロードし、./build.sh
を起動すれば、環境変数 $RISCV
で指定される領域にツールチェインがインストールされる。
$ export RISCV=/home/msyksphinz/riscv64 $ MAKEFLAGS="-j4" ./build.sh
一方で、riscv64-unknown-linux-gcc をビルドする場合には別の手法を用いる。riscv-tools の riscv-gnu-toolchain を使うことには変わりないのだが、オプションを指定しなければならない。
$ export RISCV=/home/msyksphinz/riscv64_linux # 別のRISC-Vツールチェイン用のコンパイルツールをビルドする $ cd riscv-tools/riscv-gnu-toolchain $ ./configure --prefix=$RISCV $ make linux
上記のスクリプトで、${RISCV}/bin/riscv64-unknown-linux-gnu-gcc
などのツールチェインが作られる。
vmlinux の作り方
vmlinux も、コンパイルツールチェインとして riscv64-unknown-linux-gnu
を使う必要がある。
Linuxのリポジトリをダウンロードして、RISC-V用のカーネルを作成しよう。 Linuxのソースコードをダウンロードする。v4.15 もしくは v4.16 から、ビルド可能になっている。
$ curl -L http://cdn.kernel.org/pub/linux/kernel/v4.x/linux-4.16.tar.xz | tar -xJ $ cd linux-4.16/
追記: 上記のLinuxソースコードをダウンロードするのではダメだった。riscv-linuxリポジトリからダウンロードしてくる必要があるようだ。
git clone https://github.com/riscv/riscv-linux.git --recurse-submodules -b riscv-linux-4.15 --depth 1
menuconfig
を使ってGNUツールチェインとしてriscv64-unknown-linux-gcc を使うように設定する。
$ make ARCH=riscv defconfig $ make ARCH=riscv menuconfig
[General Setup] → [Cross-compiler tool prefix] を選択し、riscv64-unknown-linux-gnu-
を指定する。
これで設定は完了だ。 Save して Exit する。ビルドしよう。数分するとビルドが完了した。vmlinux
が生成できている。
$ make
BBLを生成する
BBLを生成するためには、vmlinux を取り込む必要がある。こちらも、riscv64-unknown-linux-gnu- を使用する。このとき、vmlinuxの位置を--with-payload
で指定する。
$ git clone https://github.com/riscv/riscv-pk.git $ cd riscv-pk $ mkdir build $ cd build $ ../configure --enable-logo --host=riscv64-unknown-linux-gnu --with-payload=../../../linux-4.16/vmlinux # 修正。以下が正しい。 $ ../configure --enable-logo --host=riscv64-unknown-linux-gnu --with-payload=../../../riscv-linux/vmlinux $ make
これで bbl が生成できた。念のため1つのディレクトリに、 bbl と vmlinux と Fedora のディスクイメージをシンボリックリンクしておこう。
$ ln -s ./riscv-pk/build/bbl $ ln -s ./fedora/stage4-disk.img
qemuを立ち上げてみると、起動...しなかった。なんでだ?
$ qemu-system-riscv64 -m 4G \ -nographic \ -machine virt \ -kernel bbl \ -object rng-random,filename=/dev/urandom,id=rng0 -device virtio-rng-device,rng=rng0 \ -append "console=ttyS0 ro root=/dev/vda" -device virtio-blk-device,drive=hd0 \ -drive file=stage4-disk.img,format=raw,id=hd0 -device virtio-net-device,netdev=usernet \ -netdev user,id=usernet,hostfwd=tcp::10000-:22 ... Segment Routing with IPv6 sit: IPv6, IPv4 and MPLS over IPv4 tunneling driver NET: Registered protocol family 17 Key type dns_resolver registered VFS: Cannot open root device "vda" or unknown-block(0,0): error -6 Please append a correct "root=" boot option; here are the available partitions: Kernel panic - not syncing: VFS: Unable to mount root fs on unknown-block(0,0) CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.16.0 #1 Call Trace: [<ffffffe000030efe>] walk_stackframe+0x0/0xa2 [<ffffffe000030ffc>] show_stack+0x26/0x34 [<ffffffe0005558a8>] dump_stack+0x5e/0x7c [<ffffffe000034458>] panic+0xce/0x1e8 [<ffffffe000000fc6>] mount_block_root+0x182/0x244 [<ffffffe000001194>] mount_root+0x10c/0x128 [<ffffffe0000012c6>] prepare_namespace+0x116/0x160 [<ffffffe000000c40>] kernel_init_freeable+0x17a/0x19e [<ffffffe00056648a>] kernel_init+0xe/0xf0 [<ffffffe00002ff86>] ret_from_syscall+0xa/0xe