编译篇
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

Logo

一站式 AI 云服务平台

更多推荐