Closed14

ベアメタルなMilk-V上でRustのHello Worldを動かす

ASAASA

まずは普通にアセンブリでHello Worldしてみる

参考:
https://community.milkv.io/t/opensbi/681

ASAASA

準備

$ git clone https://github.com/milkv-duo/duo-buildroot-sdk.git
$ cd duo-buildroot-sdk
$ docker run -itd --name duodocker -v $(pwd):/home/work milkvtech/milkv-duo:latest /bin/bash
$ docker exec -it duodocker /bin/bash
ASAASA

まずFSBLをコンパイルしてBL2イメージを取得する。
Milk-V Duo 256Mなのでボードの種類のところは元記事から変えている。

$ export MILKV_BOARD=milkv-duo256m-sd
$ source device/milkv-duo256m-sd/boardconfig.sh

$ source build/milkvsetup.sh
$ defconfig cv1812cp_milkv_duo256m_sd
$ build_fsbl
ASAASA

以下ファイルを作成。
これは元記事から変えていない。

start.S
#define UART0_THR 0x04140000
#define UART0_LSR 0x04140014

	.section .text
	.global _start
_start:
	/* BL33 information */
	j real_start
	.balign 4
	.word 0x33334c42  /* b'BL33' */
	.word 0xdeadbeea  /* CKSUM */
	.word 0xdeadbeeb  /* SIZE */
	.quad 0x80200000  /* RUNADDR */
	.word 0xdeadbeec
	.balign 4
	j real_start
	.balign 4
	/* Information end */

real_start:
	la s0, str
1:
	lbu a0, (s0)
	beqz a0, exit
	jal ra, uart_send
	addi s0, s0, 1
	j 1b

exit:
	j exit

uart_send:
	/* Wait for tx idle */
	li t0, UART0_LSR
	lw t1, (t0)
	andi t1, t1, 0x20
	beqz t1, uart_send
	/* Send a char */
	li t0, UART0_THR
	sw a0, (t0)
	ret

.section .rodata
str: 
	.asciz "Hello Milkv-duo!\n"
ASAASA
$ riscv64-unknown-elf-gcc -nostdlib -fno-builtin -march=rv64gc -mabi=lp64f -g -Wall -Ttext=0x80200000 -o bl33.elf start.S

$ riscv64-unknown-elf-objcopy -O binary bl33.elf bl33.bin
ASAASA

fib.binを作る。
Milk-V Duo 256Mなのでボードの種類のところは元記事から変えている。

$ cd fsbl/

$ ./plat/cv181x/fiptool.py -v genfip \
    'build/cv1812cp_milkv_duo256m_sd/fip.bin' \
    --MONITOR_RUNADDR="0x0000000080000000" \
    --CHIP_CONF='build/cv1812cp_milkv_duo256m_sd/chip_conf.bin' \
    --NOR_INFO='FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' \
    --NAND_INFO='00000000'\
    --BL2='build/cv1812cp_milkv_duo256m_sd/bl2.bin' \
    --DDR_PARAM='test/cv181x/ddr_param.bin' \
    --MONITOR='../opensbi/build/platform/generic/firmware/fw_dynamic.bin' \
    --LOADER_2ND='/home/work/bl33.bin' \
    --compress='lzma'
ASAASA

できたfip.binをSDカードに書き込む。

今回は公式のイメージを書き込んだSDカードを読み込んで、中に入っていたfip.binを今回作成したもので置き換えた。

ASAASA

SDカードを差し込んでMilk-V Duo 256Mを起動。
起動時のログを見ると、一番最後にHello Milkv-duo!と書いてある。

起動時のログ
...省略...
OpenSBI v0.9
   ____                    _____ ____ _____
  / __ \                  / ____|  _ \_   _|
 | |  | |_ __   ___ _ __ | (___ | |_) || |
 | |  | | '_ \ / _ \ '_ \ \___ \|  _ < | |
 | |__| | |_) |  __/ | | |____) | |_) || |_
  \____/| .__/ \___|_| |_|_____/|____/_____|
        | |
        |_|

Platform Name             : Milk-V Duo256M
Platform Features         : mfdeleg
Platform HART Count       : 1
Platform IPI Device       : clint
Platform Timer Device     : clint
Platform Console Device   : uart8250
Platform HSM Device       : ---
Platform SysReset Device  : ---
Firmware Base             : 0x80000000
Firmware Size             : 132 KB
Runtime SBI Version       : 0.3

Domain0 Name              : root
Domain0 Boot HART         : 0
Domain0 HARTs             : 0*
Domain0 Region00          : 0x0000000074000000-0x000000007400ffff (I)
Domain0 Region01          : 0x0000000080000000-0x000000008003ffff ()
Domain0 Region02          : 0x0000000000000000-0xffffffffffffffff (R,W,X)
Domain0 Next Address      : 0x0000000080200020
Domain0 Next Arg1         : 0x0000000080080000
Domain0 Next Mode         : S-mode
Domain0 SysReset          : yes

Boot HART ID              : 0
Boot HART Domain          : root
Boot HART ISA             : rv64imafdcvsux
Boot HART Features        : scounteren,mcounteren,time
Boot HART PMP Count       : 16
Boot HART PMP Granularity : 4096
Boot HART PMP Address Bits: 38
Boot HART MHPM Count      : 8
Boot HART MHPM Count      : 8
Boot HART MIDELEG         : 0x0000000000000222
Boot HART MEDELEG         : 0x000000000000b109
Hello Milkv-duo!
ASAASA
ASAASA

ツールチェーンの追加

$ rustup target add riscv64gc-unknown-none-elf
ASAASA

成果物をduo-buildroot-sdkプロジェクトにコピーし、以下を実行

$ riscv64-unknown-elf-objcopy -O binary riscv-helloworld riscv-helloworld.bin
$ cd fsbl
$ ./plat/cv181x/fiptool.py -v genfip \
    'build/cv1812cp_milkv_duo256m_sd/fip.bin' \
    --MONITOR_RUNADDR="0x0000000080000000" \
    --CHIP_CONF='build/cv1812cp_milkv_duo256m_sd/chip_conf.bin' \
    --NOR_INFO='FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF' \
    --NAND_INFO='00000000'\
    --BL2='build/cv1812cp_milkv_duo256m_sd/bl2.bin' \
    --DDR_PARAM='test/cv181x/ddr_param.bin' \
    --MONITOR='../opensbi/build/platform/generic/firmware/fw_dynamic.bin' \
    --LOADER_2ND='/home/work/riscv-helloworld.bin' \
    --compress='lzma'
ASAASA

生成されたfip.binをSDカードに書き込んでMilk-Vを起動すると...

...省略...
Boot HART ID              : 0
Boot HART Domain          : root
Boot HART ISA             : rv64imafdcvsux
Boot HART Features        : scounteren,mcounteren,time
Boot HART PMP Count       : 16
Boot HART PMP Granularity : 4096
Boot HART PMP Address Bits: 38
Boot HART MHPM Count      : 8
Boot HART MHPM Count      : 8
Boot HART MIDELEG         : 0x0000000000000222
Boot HART MEDELEG         : 0x000000000000b109
Hello, Milk-V with Rust!

ちゃんと動いた〜

このスクラップは4ヶ月前にクローズされました