RISC-V Getting Started Guideというページがある。目的ベースで、QEMUやLinuxなどのオペレーティングシステムを動かすための方法や、様々なツールキットを動かすための情報がまとめられている。
risc-v-getting-started-guide.readthedocs.io
ここに"Running 64- and 32-bit RISC-V Linux on QEMU" という項目がある。これまでFreedom-u-sdkのツールキットを使うしか方法が無いのかと思っていたが、どうやら別の方法を使ってQEMUでLinuxをブートできるらしい。やってみよう。
risc-v-getting-started-guide.readthedocs.io
前提としてriscv64-unknown-elf-gcc
とriscv64-unknown-linux-gnu-gcc
がビルドできる状態であること。
フローの中にはricsv-gnu-toolchain
をダウンロードしてこれらのビルドを行うステップも含まれているが、ネットワーク帯域が必要だしビルドも時間がかかるので、私はすでにビルドしてある自前のツールを使って省略。
Getting the sourcesから始める。
# すでにビルドしてあるものを使用するためriscv-gnu-toolchainは使用しない # git clone --recursive https://github.com/riscv/riscv-gnu-toolchain git clone https://github.com/qemu/qemu git clone https://github.com/torvalds/linux git clone https://github.com/riscv/riscv-pk git clone https://github.com/michaeljclark/busybear-linux
まずはQEMUのビルドから。これはフローに乗るだけで問題なくビルドできた。sudo make install
がしたくないので、prefix=
を設定してホーム領域中にインストールしておく。
cd qemu git checkout v3.0.0 ./configure --target-list=riscv64-softmmu --prefix=${HOME}/riscv-linux-toolkit make -j $(nproc) make install
次はLinuxのビルドとなる。これもフローに則って行う。
cd linux git checkout v4.19-rc3 cp ../busybear-linux/conf/linux.config .config make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- olddefconfig
カーネルのコンフィグレーションは特に変更せずに特に設定は適用されていた。
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- nconfig
.config
で以下のパラメータが設定されていることを確認する。
ARCH_RV64I CMODEL_MEDANY CONFIG_SIFIVE_PLIC
ビルドを実行する。
make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- vmlinux -j $(nproc)
次はBBL(Berkeley Boot Loader)のビルドを行う。BBLはブートローダなのだが、ブートローダによるセットアップが終わった後にvmlinux
を起動するという要領だ。
cd riscv-pk mkdir build && cd build ../configure --enable-logo --host=riscv64-unknown-elf --with-payload=../../linux/vmlinux make -j $(nproc)
最後にファイルシステムの用意だ。Busybear Linuxのビルドを行う。
cd busybear-linux make -j $(nproc)
あれ、途中でビルドが止まってしまった。
KSYM .tmp_kallsyms2.o LD vmlinux SYSMAP System.map make[1]: Leaving directory '/home/msyksphinz/work/riscv/riscv-linux-kit/busybear-linux/build/linux-5.0' ./scripts/build.sh: line 84: ../../src/riscv-pk/configure: No such file or directory make: *** [Makefile:10: busybear.bin] Error 127 zsh: exit 2 make -j$(nproc) DESKTOP-P42Q0NR:busybear-linux msyksphinz$
色々調べると、なんだ、busybear-linuxにはひそかにsubmodulesが含まれているじゃないか。
git submodule update --init --recusive
再度ビルドに挑戦する。
In file included from /home/msyksphinz/riscv64-ctng-linux/riscv64-unknown-linux-gnu/sysroot/usr/include/features.h:474, from /home/msyksphinz/riscv64-ctng-linux/riscv64-unknown-linux-gnu/sysroot/usr/include/sys/stat.h:25, from ../../src/riscv-pk/pk/file.h:6, from ../../src/riscv-pk/pk/file.c:3: /home/msyksphinz/riscv64-ctng-linux/riscv64-unknown-linux-gnu/sysroot/usr/include/gnu/stubs.h:8:11: fatal error: gnu/stubs-lp64.h: No such file or directory # include <gnu/stubs-lp64.h> ^~~~~~~~~~~~~~~~~~
次はこんな感じのエラーで怒られた。gnu/stubs-lp64.h
が無い?
渡しのriscv64-unknown-linux-gnuはcrostools-ngでビルドしたものだ。これだと問題が発生するのだろうか?
以下のIssueを見ながら、とりあえず既存のstubs-lp64d.h
をstubs-lp64.h
にコピーした。
sudo cp ./riscv64-unknown-linux-gnu/sysroot/usr/include/gnu/stubs-lp64d.h ./riscv64-unknown-linux-gnu/sysroot/usr/include/gnu/stubs-lp64.h
さらに進めると今度は謎のエラーだ。なんだこれは。。。
riscv64-unknown-linux-gnu-ranlib libsoftfloat.a riscv64-unknown-linux-gnu-gcc -Wl,--build-id=none -nostartfiles -nostdlib -static -march=rv64gc -mabi=lp64 -o pk pk.o -L. -lpk -lmachine -lsoftfloat -lutil -lgcc -T ../../src/riscv-pk/pk/pk.lds riscv64-unknown-linux-gnu-gcc -Wl,--build-id=none -nostartfiles -nostdlib -static -march=rv64gc -mabi=lp64 -o bbl bbl.o -L. -lbbl -ldummy_payload -lmachine -lsoftfloat -lutil -lgcc -T ../../src/risc v-pk/bbl/bbl.lds make[1]: Leaving directory '/home/msyksphinz/work/riscv/riscv-linux-kit/busybear-linux/build/riscv-pk' [sudo] password for msyksphinz: env: 'Files/PuTTY:/mnt/c/Program': No such file or directory make: *** [Makefile:10: busybear.bin] Error 127
これはどうもWSL特有の問題らしい。PATHに変な文字列が入っているのがおかしいようなので、PATHに通すディレクトリを限定して再度試行する。
100+0 records in 100+0 records out 104857600 bytes (105 MB, 100 MiB) copied, 0.0597549 s, 1.8 GB/s mke2fs 1.44.4 (18-Aug-2018) Creating filesystem with 102400 1k blocks and 25688 inodes Filesystem UUID: e992d615-9ab7-470d-b78e-6b980fffb641 Superblock backups stored on blocks: 8193, 24577, 40961, 57345, 73729 Allocating group tables: done Writing inode tables: done Creating journal (4096 blocks): done Writing superblocks and filesystem accounting information: done mount: mnt: mount failed: Operation not permitted. make: *** [Makefile:10: busybear.bin] Error 1 zsh: exit 2 make -j$(nproc)
最後はエラーで止まったが、目標のbusybear.bin
は生成されたようなのでさっそくQEMUで実行してみよう。
~/riscv-linux-kit/bin/qemu-system-riscv64 -nographic -machine virt \ -kernel riscv-pk/build/bbl -append "root=/dev/vda ro console=ttyS0" \ -drive file=busybear-linux/busybear.bin,format=raw,id=hd0 \ -device virtio-blk-device,drive=hd0
bbl loader vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv vvvvvvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvv rrrrrrrrrrrrr vvvvvvvvvvvvvvvvvvvvvv rr vvvvvvvvvvvvvvvvvvvvvv rr vvvvvvvvvvvvvvvvvvvvvvvv rr rrrr vvvvvvvvvvvvvvvvvvvvvvvvvv rrrr rrrrrr vvvvvvvvvvvvvvvvvvvvvv rrrrrr rrrrrrrr vvvvvvvvvvvvvvvvvv rrrrrrrr rrrrrrrrrr vvvvvvvvvvvvvv rrrrrrrrrr rrrrrrrrrrrr vvvvvvvvvv rrrrrrrrrrrr rrrrrrrrrrrrrr vvvvvv rrrrrrrrrrrrrr rrrrrrrrrrrrrrrr vv rrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrrrr rrrrrrrrrrrrrrrrrrrrrr INSTRUCTION SETS WANT TO BE FREE [ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000 [ 0.000000] Linux version 4.19.0-rc3 (msyksphinz@DESKTOP-P42Q0NR) (gcc version 8.3.0 (crosstool-NG 1.24.0)) #1 SMP Sun May 3 19:13:43 JST 2020 [ 0.000000] bootconsole [early0] enabled [ 0.000000] Initial ramdisk at: 0x(____ptrval____) (512 bytes) [ 0.000000] Zone ranges: [ 0.000000] DMA32 empty [ 0.000000] Normal [mem 0x0000000080200000-0x0000000087ffffff] [ 0.000000] Movable zone start for each node [ 0.000000] Early memory node ranges [ 0.000000] node 0: [mem 0x0000000080200000-0x0000000087ffffff] [ 0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x0000000087ffffff] [ 0.000000] software IO TLB: mapped [mem 0x83e3d000-0x87e3d000] (64MB) [ 0.000000] elf_hwcap is 0x112d [ 0.000000] percpu: Embedded 16 pages/cpu @(____ptrval____) s25496 r8192 d31848 u65536 [ 0.000000] Built 1 zonelists, mobility grouping on. Total pages: 31815 [ 0.000000] Kernel command line: root=/dev/vda ro console=ttyS0
ブートは始まったようだが、しばらくすると止まってしまった。うーん、やはりWSLでビルドしたのが良くないのだろうか...?
[ 0.592000] Run /bin/init as init process [ 0.592000] Run /bin/sh as init process [ 0.592000] Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance. [ 0.592000] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 4.19.0-rc3 #1 [ 0.592000] Call Trace: [ 0.592000] [<ffffffe00002825c>] walk_stackframe+0x0/0xa0 [ 0.592000] [<ffffffe0000283bc>] show_stack+0x2a/0x34 [ 0.592000] [<ffffffe0003376f4>] dump_stack+0x62/0x7c [ 0.592000] [<ffffffe00002c31a>] panic+0xd2/0x1e8 [ 0.592000] [<ffffffe0003489d8>] kernel_init+0xe4/0xf0 [ 0.592000] [<ffffffe0000272ee>] ret_from_exception+0x0/0xc
カーネルパニックを起こしてしまった。これが問題なのかが分からないので、純粋なUbuntuの環境を作成して試行してみよう。