您尚未登录。

楼主 #1 2018-10-04 17:28:12

lilo
会员
注册时间: 2017-10-15
已发帖子: 215
积分: 215

学习使用一个最简单的RISCV项目 ---- riscv-probe

学习使用一个最简单的RISCV项目 ---- riscv-probe

项目地址: https://github.com/michaeljclark/riscv-probe

项目简介:

riscv探头
简单的机器模式程序,用于探测RISC-V控制和状态寄存器。

riscv-probe目前主要用于 Spike, QEMU和 SiFive E21内核。riscv-probe是一种测试工具,用于比较多个RISC-V仿真器和RISC-V硬件实现之间的CSR(控制和状态寄存器)。

riscv-probe包含libfemto,它是一个轻量级的裸金属C库,符合POSIX.1-2017 / IEEE 1003.1-2017标准的简化集。libfemto可以用作需要中断处理,基本字符串例程和printf的裸机RISC-V程序的起点。

项目构建:

构建系统使用CROSS_COMPILE工具链前缀并期望工具链存在于PATH环境变量中。然而,默认值CROSS_COMPILE是riscv64-unknown-elf-可以覆盖的,例如make CROSS_COMPILE=riscv64-unknown-linux-gnu-。构建系统需要一个multilib工具链,因为它使用相同的工具链来构建riscv32和riscv64。确保--enable-multilib在配置riscv-gnu-toolchain时使用。这些示例都是-nostartfiles -nostdlib -nostdinc使用RISC-V GCC Newlib工具链或RISC-V GCC Glibc Linux工具链构建的。

要在environent设置后构建示例,请键入:

make


使用方法:

要在spike和RISC-V QEMU中调用探测器示例:

$ spike --isa=RV32IMAFDC build/bin/rv32imac/spike/probe
$ spike --isa=RV64IMAFDC build/bin/rv64imac/spike/probe
$ qemu-system-riscv32 -nographic -machine spike_v1.10 -kernel build/bin/rv32imac/spike/probe
$ qemu-system-riscv64 -nographic -machine spike_v1.10 -kernel build/bin/rv64imac/spike/probe
$ qemu-system-riscv32 -nographic -machine virt -kernel build/bin/rv32imac/virt/probe
$ qemu-system-riscv64 -nographic -machine virt -kernel build/bin/rv64imac/virt/probe
$ qemu-system-riscv32 -nographic -machine sifive_e -kernel build/bin/rv32imac/qemu-sifive_e/probe
$ qemu-system-riscv64 -nographic -machine sifive_e -kernel build/bin/rv64imac/qemu-sifive_e/probe
$ qemu-system-riscv32 -nographic -machine sifive_u -kernel build/bin/rv32imac/qemu-sifive_u/probe
$ qemu-system-riscv64 -nographic -machine sifive_u -kernel build/bin/rv64imac/qemu-sifive_u/probe

离线

楼主 #2 2018-10-04 17:29:27

lilo
会员
注册时间: 2017-10-15
已发帖子: 215
积分: 215

Re: 学习使用一个最简单的RISCV项目 ---- riscv-probe

按上面的流程编译,参考晕哥前面发的帖子, 运行都没有问题, 起码链接出来的 hello 程序在 qemu 虚拟机下面跑是完全正常的。

离线

楼主 #3 2018-10-04 17:34:24

lilo
会员
注册时间: 2017-10-15
已发帖子: 215
积分: 215

Re: 学习使用一个最简单的RISCV项目 ---- riscv-probe

但是我想自己用 gcc  编译链接却卡在那个汇编文件了

lilo@ubuntu:/opt/riscv-probe# riscv64-unknown-elf-as -Ienv/common-I./libfemto/include/-I./env/common/rv64/ -I./libfemto/include/ -I./env/common/ -c ./env/virt/crt.s
./env/common//crtm.s: Assembler messages:
./env/common//crtm.s:3: Error: can't open macros.s for reading: No such file or directory
./env/common//crtm.s:39: Error: illegal operands `addi sp,sp,-CONTEXT_SIZE'
./env/common//crtm.s:40: Error: unrecognized opcode `sxsp ra,0'
./env/common//crtm.s:41: Error: unrecognized opcode `sxsp a0,1'
./env/common//crtm.s:42: Error: unrecognized opcode `sxsp a1,2'
./env/common//crtm.s:43: Error: unrecognized opcode `sxsp a2,3'
./env/common//crtm.s:44: Error: unrecognized opcode `sxsp a3,4'
./env/common//crtm.s:45: Error: unrecognized opcode `sxsp a4,5'
./env/common//crtm.s:46: Error: unrecognized opcode `sxsp a5,6'
./env/common//crtm.s:47: Error: unrecognized opcode `sxsp a6,7'
./env/common//crtm.s:48: Error: unrecognized opcode `sxsp a7,8'
./env/common//crtm.s:49: Error: unrecognized opcode `sxsp t0,9'
./env/common//crtm.s:50: Error: unrecognized opcode `sxsp t1,10'
./env/common//crtm.s:51: Error: unrecognized opcode `sxsp t2,11'
./env/common//crtm.s:52: Error: unrecognized opcode `sxsp t3,12'
./env/common//crtm.s:53: Error: unrecognized opcode `sxsp t4,13'
./env/common//crtm.s:54: Error: unrecognized opcode `sxsp t5,14'
./env/common//crtm.s:55: Error: unrecognized opcode `sxsp t6,15'
./env/common//crtm.s:64: Error: unrecognized opcode `lxsp ra,0'
./env/common//crtm.s:65: Error: unrecognized opcode `lxsp a0,1'
./env/common//crtm.s:66: Error: unrecognized opcode `lxsp a1,2'
./env/common//crtm.s:67: Error: unrecognized opcode `lxsp a2,3'
./env/common//crtm.s:68: Error: unrecognized opcode `lxsp a3,4'
./env/common//crtm.s:69: Error: unrecognized opcode `lxsp a4,5'
./env/common//crtm.s:70: Error: unrecognized opcode `lxsp a5,6'
./env/common//crtm.s:71: Error: unrecognized opcode `lxsp a6,7'
./env/common//crtm.s:72: Error: unrecognized opcode `lxsp a7,8'
./env/common//crtm.s:73: Error: unrecognized opcode `lxsp t0,9'
./env/common//crtm.s:74: Error: unrecognized opcode `lxsp t1,10'
./env/common//crtm.s:75: Error: unrecognized opcode `lxsp t2,11'
./env/common//crtm.s:76: Error: unrecognized opcode `lxsp t3,12'
./env/common//crtm.s:77: Error: unrecognized opcode `lxsp t4,13'
./env/common//crtm.s:78: Error: unrecognized opcode `lxsp t5,14'
./env/common//crtm.s:79: Error: unrecognized opcode `lxsp t6,15'
./env/common//crtm.s:80: Error: illegal operands `addi sp,sp,CONTEXT_SIZE'
./env/virt/crt.s: Error: invalid operands (*ABS* and *UND* sections) for `*' when setting `CONTEXT_SIZE'

https://github.com/michaeljclark/riscv-probe/blob/master/env/virt/crt.s
https://github.com/michaeljclark/riscv-probe/blob/master/env/common/constants.s
https://github.com/michaeljclark/riscv-probe/blob/master/env/common/crtm.s
https://github.com/michaeljclark/riscv-probe/blob/master/env/common/rv64/macros.s

看起来包含目录也是没有问题的.

离线

楼主 #4 2018-10-04 17:38:07

lilo
会员
注册时间: 2017-10-15
已发帖子: 215
积分: 215

Re: 学习使用一个最简单的RISCV项目 ---- riscv-probe

实在没办法了,把三个 .s 文件手动合并成 crt.s 文件:

# See LICENSE for license details.

# See LICENSE for license details.

.equ REGBYTES, 8

.macro lx a, b
ld \a, \b
.endm

.macro sx a, b
sd \a, \b
.endm

.macro lxsp a, b
ld \a, ((\b)*REGBYTES)(sp)
.endm

.macro sxsp a, b
sd \a, ((\b)*REGBYTES)(sp)
.endm

.macro .ptr a
.8byte \a
.endm










# See LICENSE for license details.

.equ MAX_HARTS,    4
.equ SAVE_REGS,    16
.equ STACK_SIZE,   1024
.equ STACK_SHIFT,  10
.equ CONTEXT_SIZE, (SAVE_REGS * REGBYTES)

.globl _text_start
.globl _text_end
.globl _rodata_start
.globl _rodata_end
.globl _data_start
.globl _data_end
.globl _bss_start
.globl _bss_end
.global _memory_start;
.global _memory_end;







#
# start of trap handler
#

.section .text.init,"ax",@progbits
.globl _start

_start:
    # setup default trap vector
    la      t0, trap_vector
    csrw    mtvec, t0

    # set up stack pointer based on hartid
    csrr    t0, mhartid
    slli    t0, t0, STACK_SHIFT
    la      sp, stacks + STACK_SIZE
    add     sp, sp, t0

    # park all harts excpet hart 0
    csrr    a0, mhartid
    bnez    a0, park

    # jump to libfemto_start_main
    j       libfemto_start_main

    # sleeping harts mtvec calls trap_fn upon receiving IPI
park:
    wfi
    j       park

    .align 2
trap_vector:
    # Save registers.
    addi    sp, sp, -CONTEXT_SIZE
    sxsp    ra, 0
    sxsp    a0, 1
    sxsp    a1, 2
    sxsp    a2, 3
    sxsp    a3, 4
    sxsp    a4, 5
    sxsp    a5, 6
    sxsp    a6, 7
    sxsp    a7, 8
    sxsp    t0, 9
    sxsp    t1, 10
    sxsp    t2, 11
    sxsp    t3, 12
    sxsp    t4, 13
    sxsp    t5, 14
    sxsp    t6, 15

    # Invoke the handler.
    mv      a0, sp
    csrr    a1, mcause
    csrr    a2, mepc
    jal     trap_handler

    # Restore registers.
    lxsp    ra, 0
    lxsp    a0, 1
    lxsp    a1, 2
    lxsp    a2, 3
    lxsp    a3, 4
    lxsp    a4, 5
    lxsp    a5, 6
    lxsp    a6, 7
    lxsp    a7, 8
    lxsp    t0, 9
    lxsp    t1, 10
    lxsp    t2, 11
    lxsp    t3, 12
    lxsp    t4, 13
    lxsp    t5, 14
    lxsp    t6, 15
    addi sp, sp, CONTEXT_SIZE

    # Return
    mret

    .bss
    .align 4
    .global stacks
stacks:
    .skip STACK_SIZE * MAX_HARTS

然后执行编译, 生成 crt.o:

riscv64-unknown-elf-gcc -c -march=rv64imac -mabi=lp64 -mcmodel=medany -ffunction-sections -fdata-sections  crt.s

再编译其他的 .c 文件

riscv64-unknown-elf-gcc -Ienv/common    \
-I./libfemto/include/    \
-I./env/common/rv64 \
-I./libfemto/include/ \
-I./env/common/ \
-c                  \
./examples/hello/hello.c                         \
./libfemto/std/strncmp.c                         \
./libfemto/std/abort.c                           \
./libfemto/std/memcpy.c                          \
./libfemto/std/ctz.c                             \
./libfemto/std/printf.c                          \
./libfemto/std/strcmp.c                          \
./libfemto/std/putchar.c                         \
./libfemto/std/memset.c                          \
./libfemto/std/getchar.c                         \
./libfemto/std/clz.c                             \
./libfemto/std/strlen.c                          \
./libfemto/std/memchr.c                          \
./libfemto/std/vsnprintf.c                       \
./libfemto/std/exit.c                            \
./libfemto/std/strchr.c                          \
./libfemto/std/malloc.c                          \
./libfemto/std/puts.c                            \
./libfemto/std/vprintf.c                         \
./libfemto/std/strncpy.c                         \
./libfemto/std/memcmp.c                          \
./libfemto/std/snprintf.c                        \
./libfemto/arch/riscv/device.c                   \
./libfemto/arch/riscv/csr.c                      \
./libfemto/arch/riscv/trap.c                     \
./libfemto/arch/riscv/pmp.c                      \
./libfemto/arch/riscv/memory.c                   \
./libfemto/arch/riscv/auxval.c                   \
./libfemto/arch/riscv/start.c                    \
./libfemto/drivers/ns16550a.c                    \
./libfemto/drivers/sifive_test.c                 \
./env/virt/setup.c                               \
-march=rv64imac -mabi=lp64  \
-mcmodel=medany -ffunction-sections -fdata-sections

链接成 hello:

riscv64-unknown-elf-gcc -o hello \
hello.o                         \
strncmp.o                         \
abort.o                           \
memcpy.o                          \
ctz.o                             \
printf.o                          \
strcmp.o                          \
putchar.o                         \
memset.o                          \
getchar.o                         \
clz.o                             \
strlen.o                          \
memchr.o                          \
vsnprintf.o                       \
exit.o                            \
strchr.o                          \
malloc.o                          \
puts.o                            \
vprintf.o                         \
strncpy.o                         \
memcmp.o                          \
snprintf.o                        \
device.o                   \
csr.o                      \
trap.o                     \
pmp.o                      \
memory.o                   \
auxval.o                   \
start.o                    \
ns16550a.o                    \
sifive_test.o                 \
setup.o                               \
crt.o                                 \
-T env/virt/default.lds                 \
-mcmodel=medany -ffunction-sections -fdata-sections  -nostartfiles -nostdlib -nostdinc -static -lgcc -Wl,--nmagic -Wl,--gc-sections

运行:

qemu-system-riscv64 -nographic -machine virt -kernel hello

运行一切正常:

lilo@ubuntu:/opt/riscv-probe# qemu-system-riscv64 -nographic -machine virt -kernel hello
hello
lilo@ubuntu:/opt/riscv-probe#

离线

楼主 #5 2018-10-04 17:49:39

lilo
会员
注册时间: 2017-10-15
已发帖子: 215
积分: 215

Re: 学习使用一个最简单的RISCV项目 ---- riscv-probe

riscv64-unknown-elf-gcc -o hello                  \
hello.o                         \
printf.o                          \
putchar.o                         \
getchar.o                         \
vsnprintf.o                       \
exit.o                            \
malloc.o                          \
puts.o                            \
vprintf.o                         \
snprintf.o                        \
device.o                   \
csr.o                      \
trap.o                     \
memory.o                   \
auxval.o                   \
start.o                    \
ns16550a.o                    \
sifive_test.o                 \
setup.o                               \
crt.o                                 \
-T env/virt/default.lds                 \
-mcmodel=medany -ffunction-sections -fdata-sections  -nostartfiles -nostdlib -nostdinc -static -lgcc -Wl,--nmagic -Wl,--gc-sections

这个差不多是 ns16550串口(qemu virt 模拟器)模拟 printf输出 RISCV程序 的最精简版本了.

如果不使用 printf 可以更精简一些.

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn