Posted at

RISC-V Linuxを動かしてみる(on QEMU/SPIKE)

More than 1 year has passed since last update.


動機

最近良く聞くRISC-Vを動かしてみたい。

基本は手順どおり進めただけだけど、いくつかエラーに遭遇したので備忘のために投稿しとく。


環境


  • OS: Ubuntu 16.04

  • CPU: Intel(R) Core(TM) i7-3517U CPU @ 1.90GHz x4


方法1. Fedoraの作成済イメージを動かす

RISC-V版QEMUでLinuxを立ち上げる試行

めちゃくちゃ楽。感謝感謝です。

ただ楽すぎてほとんどやることがない。


方法2. yoctoでビルドする

riscv-poky

結構楽。ビルドに結構時間はかかるけど。

※ちなみに試したのは、こちらの状態。


ビルド手順

$ git clone https://github.com/riscv/riscv-poky.git

$ cd riscv-poky
$ source oe-init-build-env
$ bitbake core-image-riscv


Trouble Shooting


1. gitのバージョン

yoctoなので、ほとんどのホストツールも自動でビルドしてくれるが、gitはnativeのものをそのまま使う。

Ubuntu 16.04のaptで入るgit 2.18.0 (2018/7/20時点)ではobsoleteされている--set-upstreamオプションが使われているので、エラーになってしまう。

diff --git a/bitbake/lib/bb/fetch2/git.py b/bitbake/lib/bb/fetch2/git.py

index 534c93d3c5..88b99bdc03 100644
--- a/bitbake/lib/bb/fetch2/git.py
+++ b/bitbake/lib/bb/fetch2/git.py
@@ -485,7 +485,7 @@ class Git(FetchMethod):
branchname = ud.branches[ud.names[0]]
runfetchcmd("%s checkout -B %s %s" % (ud.basecmd, branchname, \
ud.revisions[ud.names[0]]), d, workdir=destdir)
- runfetchcmd("%s branch --set-upstream %s origin/%s" % (ud.basecmd, branchname, \
+ runfetchcmd("%s branch --set-upstream-to=origin/%s %s" % (ud.basecmd, branchname, \
branchname), d, workdir=destdir)
else:
runfetchcmd("%s checkout %s" % (ud.basecmd, ud.revisions[ud.names[0]]), d, workdir=destdir)


2. riscv-qemuのfetchに失敗する

recipeで指定しているrevisionがfetchできないというエラーに遭遇する。

riscv-pokyのissue#15に回避策も上がっていた。

diff --git a/meta-riscv/recipes-devtools/qemu/qemu_2.5.0.bb b/meta-riscv/recipes-devtools/qemu/qemu_2.5.0.bb

index 578c74dd51..235bdffe5a 100644
--- a/meta-riscv/recipes-devtools/qemu/qemu_2.5.0.bb
+++ b/meta-riscv/recipes-devtools/qemu/qemu_2.5.0.bb
@@ -1,6 +1,6 @@
require recipes-devtools/qemu/qemu.inc

-SRC_URI = "gitsm://github.com/riscv/riscv-qemu.git;destsuffix=${S}"
+SRC_URI = "git://github.com/riscv/riscv-qemu.git;rev=9bfcd4717b3010eb7efc50057232e92ecb741cac;nobranch=1;destsuffix=${S}"
SRCREV_pn-qemu-native = "9bfcd4717b3010eb7efc50057232e92ecb741cac"
SRCREV_pn-nativesdk-qemu = "9bfcd4717b3010eb7efc50057232e92ecb741cac"


SPIKE起動

ちなみにSPIKEというのは、RISC-Vの標準シミュレータのこと。

$ runspike riscv64

Continuing with the following parameters:
KERNEL: [riscv-poky/build/tmp/deploy/images/riscv64/vmlinux-riscv64.bin]
ROOTFS: [riscv-poky/build/tmp/deploy/images/riscv64/core-image-riscv-riscv64-20180720134101.rootfs.ext2]
FSTYPE: [ext2]
SPIKE_BIN: [riscv-poky/build/tmp/work/riscv64-poky-linux/core-image-riscv/1.0-r0/recipe-sysroot-native/usr/bin/spike]
BBL_PATH: [riscv-poky/build/tmp/work/riscv64-poky-linux/riscv-pk/1.0-r0/build/bbl]

[ 0.000000] OF: fdt: Ignoring memory range 0x80000000 - 0x80200000
[ 0.000000] Linux version 4.13.0 (oe-user@oe-host) (gcc version 7.2.0 (GCC)) #1 Fri Jul 20 23:41:04 JST 2018
[ 0.000000] bootconsole [early0] enabled
[ 0.000000] Zone ranges:
[ 0.000000] DMA [mem 0x0000000080200000-0x00000000ffffffff]
[ 0.000000] Normal empty
[ 0.000000] Movable zone start for each node
[ 0.000000] Early memory node ranges
[ 0.000000] node 0: [mem 0x0000000080200000-0x00000000ffffffff]
[ 0.000000] Initmem setup node 0 [mem 0x0000000080200000-0x00000000ffffffff]
[ 0.000000] elf_hwcap is 0x112d
[ 0.000000] Built 1 zonelists in Zone order, mobility grouping on. Total pages: 516615
[ 0.000000] Kernel command line: root=/dev/sbi-disk
[ 0.000000] PID hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.000000] Dentry cache hash table entries: 262144 (order: 9, 2097152 bytes)
[ 0.000000] Inode-cache hash table entries: 131072 (order: 8, 1048576 bytes)
[ 0.000000] Sorting __ex_table...
[ 0.000000] software IO TLB [mem 0xfa0ed000-0xfe0ed000] (64MB) mapped at [ffffffe079eed000-ffffffe07deecfff]
[ 0.000000] Memory: 1994216K/2095104K available (1660K kernel code, 148K rwdata, 466K rodata, 76K init, 750K bss, 100888K reserved, 0K cma-reserved)
[ 0.000000] SLUB: HWalign=64, Order=0-3, MinObjects=0, CPUs=1, Nodes=1
[ 0.000000] NR_IRQS: 0, nr_irqs: 0, preallocated irqs: 0
[ 0.000000] riscv,cpu_intc,0: 64 local interrupts mapped
[ 0.000000] clocksource: riscv_clocksource: mask: 0xffffffffffffffff max_cycles: 0x24e6a1710, max_idle_ns: 440795202120 ns
[ 0.000000] console [hvc0] enabled
[ 0.000000] console [hvc0] enabled
[ 0.000000] bootconsole [early0] disabled
[ 0.000000] bootconsole [early0] disabled
[ 0.000000] Calibrating delay loop (skipped), value calculated using timer frequency.. 20.00 BogoMIPS (lpj=40000)
[ 0.000000] pid_max: default: 32768 minimum: 301
[ 0.000000] Mount-cache hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.004000] Mountpoint-cache hash table entries: 4096 (order: 3, 32768 bytes)
[ 0.004000] devtmpfs: initialized
[ 0.004000] clocksource: jiffies: mask: 0xffffffff max_cycles: 0xffffffff, max_idle_ns: 7645041785100000 ns
[ 0.004000] futex hash table entries: 256 (order: 0, 6144 bytes)
[ 0.008000] random: get_random_u32 called from bucket_table_alloc+0x7c/0x1e6 with crng_init=0
[ 0.008000] NET: Registered protocol family 16
[ 0.008000] vgaarb: loaded
[ 0.008000] clocksource: Switched to clocksource riscv_clocksource
[ 0.008000] NET: Registered protocol family 2
[ 0.008000] TCP established hash table entries: 16384 (order: 5, 131072 bytes)
[ 0.012000] TCP bind hash table entries: 16384 (order: 5, 131072 bytes)
[ 0.012000] TCP: Hash tables configured (established 16384 bind 16384)
[ 0.012000] UDP hash table entries: 1024 (order: 3, 32768 bytes)
[ 0.012000] UDP-Lite hash table entries: 1024 (order: 3, 32768 bytes)
[ 0.012000] NET: Registered protocol family 1
[ 0.012000] workingset: timestamp_bits=62 max_order=19 bucket_order=0
[ 0.012000] random: fast init done
[ 0.028000] jitterentropy: Initialization failed with host not compliant with requirements: 2
[ 0.028000] io scheduler noop registered
[ 0.028000] io scheduler cfq registered (default)
[ 0.028000] io scheduler mq-deadline registered
[ 0.028000] io scheduler kyber registered
[ 0.036000] disk [sbi-disk] of 737095680 bytes loaded
[ 0.040000] VFS: Mounted root (ext2 filesystem) readonly on device 254:0.
[ 0.040000] devtmpfs: mounted
[ 0.040000] Freeing unused kernel memory: 76K
[ 0.040000] This architecture does not have kernel memory protection.
INIT: version 2.88 booting
hwclock: can't open '/dev/misc/rtc': No such file or directory
Fri Jul 20 15:53:09 UTC 2018
hwclock: can't open '/dev/misc/rtc': No such file or directory
INIT: Entering runlevel: 5
Configuring network interfaces... ifconfig: SIOCGIFFLAGS: No such device
hwclock: can't open '/dev/misc/rtc': No such file or directory
Starting syslogd/klogd: done

Poky (Yocto Project Reference Distro) 2.3 riscv64 /dev/console

riscv64 login: root
root
root@riscv64:~# cat /proc/cpuinfo
cat /proc/cpuinfo
hart : 0
isa : rv64imafdc
mmu : sv48

root@riscv64:~# readelf -h /usr/bin/readelf
readelf -h /usr/bin/readelf
ELF Header:
Magic: 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00
Class: ELF64
Data: 2's complement, little endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: EXEC (Executable file)
Machine: RISC-V
Version: 0x1
Entry point address: 0x122d4
Start of program headers: 64 (bytes into file)
Start of section headers: 467296 (bytes into file)
Flags: 0x5, RVC, double-float ABI
Size of this header: 64 (bytes)
Size of program headers: 56 (bytes)
Number of program headers: 8
Size of section headers: 64 (bytes)
Number of section headers: 27
Section header string table index: 26
root@riscv64:~# uname -a
Linux riscv64 4.13.0 #1 Fri Jul 20 23:41:04 JST 2018 riscv64 riscv64 riscv64 GNU/Linux

動いた!

ちゃんとRISC-Vになってる!


感想

先人たちのおかげでもう十分遊べる。

情報が不足していることを危惧していたが、今回試した範囲ぐらいだったら、むしろ情報がまとまってる印象。

まだ試せてないけど、riscv-toolsに書かれてい手順で最低限のrootfsでLinux起動できるっぽいので、それも今度やってみよう。