nemu linux
Difftest 适配
在跑linux需要加入csr的检查,以测出特权指令执行的结果是否正确
首先需要做的就是维护一套csr寄存器,我个人做法就是设置一个csr_map结构体,然后查询这个结构体来找到csr是否实现
1 | nemu_csr_t csr_map[] = { |
然后每次增加一个csr寄存器,只需在difftest.cc和inst.c同时将寄存器加入map即可
之后我们需要实现非法指令异常,可以参考yield在nemu实现,当遇到一些没实现的csr时,就可以触发异常,然后sbi会自己处理这些没实现的csr,我们此时也要去将这个非法指令访问异常同步到spike中,具体可以参考spike的get_csr
完成上述,基本difftest改造完成
移植opensbi
首先下载opensbi
1 | git clone https://github.com/riscv-software-src/opensbi |
然后复制一份platform/templete,将这个改为适配nemu的平台,具体改动:
先设置objects.mk,然后
1 | PLATFORM_RISCV_XLEN = 32 |
然后设置platform.c,主要就是设置timer,uart的地址,这里可以根据自己的想法去设置设备地址,也可以使用nemu内部的地址,建议uart使用nemu的,只需稍微改动即可,改动可参考uart8250手册
之后就是debug过程,最后由于跳转到0x0,所以会直接段错误退出,注意最好看19年的手册,24年新出的手册会增加一些csr,从而导致spike触发非法指令
运行结果如下
如果不确定需要实现哪些寄存器,可以先抛出非法指令异常,之后opensbi会告诉你要设置哪些寄存器
移植linux
为什么执行到relocate_enable_mmu会访问无效地址?
因为指第一次写入satp并没有去执行sfence,所以导致系统仍然使用之前的映射关系
- 需要去为ref传递异常号
- 为什么会跳转到c000098,这里可能发生了嵌套异常(错误的行为)
终于可以跑起来一部分页表了:
发现之前的问题是因为自己的pte解析出错了
目前的问题是:
会访问0x80040000的数据,这个就是j指令