Diary/2019-2-16
RISC-VをQemuで試す
Qemuで試す環境構築のメモ.
- Qemu
関連ライブラリをインストールして
sudo apt install pkg-config libglib2.0-dev zlib1g-dev libpixman-1-dev sudo apt install libsdl2-dev
ソースツリーをcloneしてビルド
git clone --recursive https://github.com/riscv/riscv-qemu.git cd riscv-qemu mkdir build && cd build ../configure --target-list=riscv64-softmmu,riscv32-softmmu,riscv64-linux-user,riscv32-linux-user make -j8 sudo make install
これで
/usr/local/bin/qemu-riscv
などがインストールされる
- ツールチェイン
関連ライブラリをインストールして
sudo apt-get install autoconf automake autotools-dev \
curl libmpc-dev libmpfr-dev libgmp-dev libusb-1.0-0-dev \
gawk build-essential bison flex texinfo gperf libtool \
patchutils bc zlib1g-dev device-tree-compiler \
pkg-config libexpat-dev
ソースツリーをcloneしてビルド
git clone https://github.com/riscv/riscv-tools.git cd riscv-tools git submodule update --init --recursive export RISCV=/usr/local/riscv-tools sudo -E ./build.sh
- 動作確認
とりあえず,
hello.s
.section .text
.equ UART_ADDR, 0x10000000
.global _start
_start:
la s0, message # set a pointer to head of message
loop:
lb a0, 0(s0) # load head of message into a0
addi s0, s0, 1 # increment the pointer for message
beqz a0, halt
jal put
j loop
put:
li t0, UART_ADDR
sb a0, 0(t0)
ret
halt:
j halt
.section .rodata
message:
.ascii "Hello, RISC-V.\n\0"
と,
hello.ld
OUTPUT_ARCH("riscv")
ENTRY(_start)
SECTIONS
{
. = 0x80000000;
.text : { *(.text) }
.rodata : { *(.rodata) }
.data : { *(.data) }
.bss : { *(.bss) }
}
を用意して,
export PATH=/usr/local/riscv-tools/bin:$PATH riscv64-unknown-elf-gcc -march=rv64g -mabi=lp64 -nostartfiles -Thello.ld hello.s -o hello
とコンパイルして,
qemu-system-riscv64 -M virt -kernel hello -nographic
で実行.終了はC-a x.
- Cも試す.
test.c
volatile char * UART = (volatile char*)0x10000000;
int main(){
char *mesg = "Hello RISC-V\n";
while(*mesg != 0){
*UART = *mesg;
mesg++;
}
}
test0.s
.section .text
.global _start
_start:
la sp, sp_top
jal main
halt:
j halt
test.ld
OUTPUT_ARCH("riscv")
ENTRY(_start)
SECTIONS
{
. = 0x80000000;
test0 : { test0.o(.text) }
.text : { *(.text) }
.rodata : { *(.rodata) }
.data : { *(.data) }
.bss : { *(.bss) }
. = ALIGN(8);
. = . + 0x4000;
sp_top = .;
}
コンパイルして,
riscv64-unknown-elf-gcc -march=rv64g -mabi=lp64 -o test0.o -c test0.s riscv64-unknown-elf-gcc -march=rv64g -mabi=lp64 -mcmodel=medany -o test.o -c test.c riscv64-unknown-elf-ld -static -nostartupfiles -T test.ld -o test test0.o test.o
実行
qemu-system-riscv64 -M virt -kernel test -nographic
- Qemuのmemory mapped I/Oのアドレス
riscv-qemu/hw/riscv/virt.cに定義されてる.
[VIRT_DEBUG] = { 0x0, 0x100 },
[VIRT_MROM] = { 0x1000, 0x11000 },
[VIRT_TEST] = { 0x100000, 0x1000 },
[VIRT_CLINT] = { 0x2000000, 0x10000 },
[VIRT_PLIC] = { 0xc000000, 0x4000000 },
[VIRT_UART0] = { 0x10000000, 0x100 },
[VIRT_VIRTIO] = { 0x10001000, 0x1000 },
[VIRT_DRAM] = { 0x80000000, 0x0 },