riscv代码调试遇到过的问题及坑
gdb 篇Could not fetch register "scause"; remote failure reply 'E14'原因该版本的gdb中不支持该 csr1.更新到一个高版本的gdb试试Cannot find bounds of current function原因abi的问题2.在gdb命令行中输入 setarchitecture riscv:rv32 试试链接篇target em
·
编译篇
riscv32-unknown-elf-gcc -march=rv32ima -mabi=ilp32 遇到这个问题
Error: unrecognized opcode `csrr a5,mhartid'
解决方案:
https://lkml.org/lkml/2022/2/10/879
https://blog.csdn.net/u011011827/article/details/121371305
riscv32-unknown-elf-gcc -march=rv32ima_zicsr -mabi=ilp32
//-march=rv32ima_zicsr_zifencei
原因:
> +# Newer binutils versions default to ISA spec version 20191213 which moves some
> +# instructions from the I extension to the Zicsr and Zifencei extensions.
链接篇
riscv64-unknown-elf-ld 链接遇到如下问题
target emulation `elf32-littleriscv' does not match `elf64-littleriscv'
原因
应该是 riscv64-unknown-elf-ld 不支持 将32-elf 链接为 32-elf
1.用 riscv 编译链 中的 gcc 链接试试
riscv64-unknown-elf-gcc -T arch/rv32/linker.lds -nostdlib -nostartfiles -Wl,-Map=baremetal.map -Wl,--whole-archive arch/rv32/built-in.a init/built-in.a modules/built-in.a -Wl,--no-whole-archive -o baremetal.elf
2.用 riscv32 工具链试试
undefined reference to `__clzdi2' // https://github.com/riscv-collab/riscv-gnu-toolchain/issues/588
我用的 是 x-tools 8.3.0 , riscv64-unknown-elf/lib/gcc/riscv64-unknown-elf/8.3.0/ 下的 .a 是 32bit的
直接链接 riscv64-unknown-elf/lib/gcc/riscv64-unknown-elf/8.3.0/rv64imac/lp64 下的 libgcc.a 会报其他的错
/home/pop/x-tools/riscv64-unknown-elf/lib/gcc/riscv64-unknown-elf/8.3.0/rv64imac/lp64/libgcc.a(_clzsi2.o): in function `__clzdi2':
/home/pop/work/freertos-riscv/crosstool-ng-crosstool-ng-1.24.0/.build/riscv64-unknown-elf/src/gcc/libgcc/libgcc2.c:710:(.text+0x1c): relocation truncated to fit: R_RISCV_HI20 against symbol `__clz_tab' defined in .rodata section in /home/pop/x-tools/riscv64-unknown-elf/lib/gcc/riscv64-unknown-elf/8.3.0/rv64imac/lp64/libgcc.a(_clz.o)
---
riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14 编译 , 也是 这个问题 : undefined reference to `__clzdi2'
riscv64-unknown-elf-toolchain-10.2.0-2020.12.8-x86_64-linux-ubuntu14/lib/gcc/riscv64-unknown-elf/10.2.0/ 下的 .a 是 64bit的
---
目前观察到 10.2.1 的 adnes toolchain 没有这个问题,这个是rv64 only 的 , 可以正常链接 __clzdi2
---
https://github.com/riscv-collab/riscv-gnu-toolchain/issues/457
增加
CT_LIBC_NEWLIB_TARGET_CFLAGS="-mcmodel=medany"
没有解决
解决方案:
直接把 crosstool-ng 中的
./.build/src/gcc-12.1.0/libgcc/config/nds32/lib2csrc-mculib/_clzsi2.c
./.build/src/gcc-12.1.0/libgcc/config/nds32/lib2csrc-mculib/_clzdi2.c
这两个文件放到 工程 中编译链接
gdb 篇
Could not fetch register "scause"; remote failure reply 'E14'
原因
该版本的gdb中不支持该 csr
1.更新到一个高版本的gdb 解决问题
Cannot find bounds of current function
原因
abi的问题
2.在gdb命令行中输入 set architecture riscv:rv32 解决问题
qemu 篇
qemu-6.1.0 build from source /ubuntu 22.04 6.2.0 have questions
mode 切换时
切换后的pc 执行第一条指令后会进入异常(不是中断)
原因(mcause) 为 "Instruction access fault"
mdcause 为 "Reserved"
原因
未知
1.换一个 qemu-system-riscv 解决了该问题
// ubuntu 20.04 qemu V4.2.1 is ok
// v5.2.0 build from source by gcc 9 is ok , and it can load kernel from opensbi
// v6.0.0-rc0 is not ok , but it can load kernel from opensbi
// 这个 大概意思已经明了了,只是把 mcause 改了
$ git show 4c48aad122b9dd4d96184828d7172cc62dae01c5
commit 4c48aad122b9dd4d96184828d7172cc62dae01c5
Author: Bin Meng <bmeng@tinylab.org>
Date: Mon Dec 5 14:53:03 2022 +0800
target/riscv: Fix mret exception cause when no pmp rule is configured
The priv spec v1.12 says:
If no PMP entry matches an M-mode access, the access succeeds. If
no PMP entry matches an S-mode or U-mode access, but at least one
PMP entry is implemented, the access fails. Failed accesses generate
an instruction, load, or store access-fault exception.
At present the exception cause is set to 'illegal instruction' but
should have been 'instruction access fault'.
Fixes: d102f19a2085 ("target/riscv/pmp: Raise exception if no PMP entry is configured")
Signed-off-by: Bin Meng <bmeng@tinylab.org>
Reviewed-by: Wilfred Mallawa <wilfred.mallawa@wdc.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-Id: <20221205065303.204095-1-bmeng@tinylab.org>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
diff --git a/target/riscv/op_helper.c b/target/riscv/op_helper.c
index 09f1f5185d..d7af7f056b 100644
--- a/target/riscv/op_helper.c
+++ b/target/riscv/op_helper.c
@@ -202,7 +202,7 @@ target_ulong helper_mret(CPURISCVState *env)
if (riscv_feature(env, RISCV_FEATURE_PMP) &&
!pmp_get_num_rules(env) && (prev_priv != PRV_M)) {
- riscv_raise_exception(env, RISCV_EXCP_ILLEGAL_INST, GETPC());
+ riscv_raise_exception(env, RISCV_EXCP_INST_ACCESS_FAULT, GETPC());
}
target_ulong prev_virt = get_field(env->mstatus, MSTATUS_MPV);
// 解决方案,在 切换Mode 前 调用此函数
/*************************************************************************
> File Name: pmp.c
> Author: SuWeishuai
> Mail: suwsl@foxmail.com
> Created Time: 2023年06月10日 星期六 18时09分05秒
************************************************************************/
#include "pmp.h"
#include "stdint.h"
void pmp_setup(void)
{
unsigned long int pmpc = PMP_A_NAPOT | PMP_R | PMP_W | PMP_X;
asm volatile (
"csrw pmpaddr0, %1\n\t"
"csrw pmpcfg0, %0\n\t"
:
: "r" (pmpc), "r" (-1UL)
:
);
}
/*************************************************************************
> File Name: pmp.h
> Author: SuWeishuai
> Mail: suwsl@foxmail.com
> Created Time: 2023年06月10日 星期六 18时12分12秒
************************************************************************/
#ifndef PMP_H
#define PMP_H
#define PMP_R 0x01UL
#define PMP_W 0x02UL
#define PMP_X 0x04UL
#define PMP_A 0x18UL
#define PMP_A_TOR 0x08UL
#define PMP_A_NA4 0x10UL
#define PMP_A_NAPOT 0x18UL
#define PMP_L 0x80UL
#endif
更多推荐


所有评论(0)