トップ 一覧 Farm 検索 ヘルプ RSS ログイン

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 },