RISC-V裸机开发:QEMU中设置SATP寄存器触发指令页故障求助
RISC-V内核页表设置触发循环指令页故障问题
环境信息
- OS:Windows 10 上的 Ubuntu 24.04 LTS
- QEMU:qemu-system-riscv64 版本 8.2.2
- GDB:GNU gdb (GDB) 15.2
我正在用Rust开发运行于QEMU的RISC-V内核,初始化页表时程序崩溃,当前代码仅包含页表初始化逻辑。
通过make debug启动程序,bash debug.sh进行GDB调试,程序在src/lib.rs第109行执行时冻结:
pub fn use_sv39(&self) { // let satp: usize = self.page_table.satp_token().into(); // riscv::register::satp::write(satp); // let ppn = self.page_table.address.into(); unsafe { let tok: usize = self.page_table.satp_token().into(); 109: ---> asm!(concat!("csrw satp, {0}"), in(reg) tok); // let res = riscv::register::satp::try_set(Mode::Sv39, 0, ppn); println!("set satp"); asm!("SFENCE.VMA"); } }
调试汇编代码时,执行csrw satp, a0指令后程序冻结,设置前satp值为0x0。
新增调试信息
已在src/trap/trap.S第12行的__alltraps符号处设置断点(该入口已写入stvec寄存器),执行到上述第109行时,GDB停在__alltraps处,说明触发了异常。检查sstatus寄存器,SPP位为1,表明当前处于S模式;scause值为0xc,代表指令页故障。
但执行si单步调试时,会再次进入__alltraps(断点触发两次),sstatus仍为0x200000100,scause仍为0xc。
这种循环陷阱的原因是什么?该如何解决?
内容的提问来源于stack exchange,提问作者dvorak
相关产品推荐
相关产品推荐

