-
Notifications
You must be signed in to change notification settings - Fork 68
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
关于 os/src/sbi.rs::shutdown 后 qemu 和 gdb 问题以及相关一些探索和疑问 #127
Comments
os/src/sbi.rs::shutdown
后 qemu
提示不支持的问题以及相关一些探索和疑问
@wyfcyx 谢谢,在我的机器下的运行结果和文档中有些出入,具体说来,我这里运行的结果如下: [rustsbi] Version 0.1.0
.______ __ __ _______.___________. _______..______ __
| _ \ | | | | / | | / || _ \ | |
| |_) | | | | | | (----`---| |----`| (----`| |_) || |
| / | | | | \ \ | | \ \ | _ < | |
| |\ \----.| `--' |.----) | | | .----) | | |_) || |
| _| `._____| \______/ |_______/ |__| |_______/ |______/ |__|
[rustsbi] Platform: QEMU
[rustsbi] misa: RV64ACDFIMSU
[rustsbi] mideleg: 0x222
[rustsbi] medeleg: 0xb109
[rustsbi] Kernel entry: 0x80020000
Hello, world!
.text [0x80020000, 0x80022000)
.rodata [0x80022000, 0x80023000)
.data [0x80023000, 0x80023000)
boot_stack [0x80023000, 0x80033000)
.bss [0x80033000, 0x80033000)
Panicked at src/main.rs:46 Shutdown machine!
panicked at 'Unhandled exception! mcause: Exception(StoreFault), mepc: 000000008000261c, mtval: 0000000000100000', platform/qemu/src/main.rs:395:18
我暂时先发出这个结果,等研究完文档上的说明之后再查查什么原因。再次感谢!!! |
根据上述结果最后一行的信息,定位到了 RUSTSBI 原码处,再根据 目前的解决方法是,安装 qemu v5.0.0 。 备注:安装 qemu v5.0.0 之后的 rCore-Tutorial 和 rCore-Tutorial-v3 均能正常 shutdown 。 |
最近在 qemu v5.1.0 上遇到了同样的问题,最后发现原因如下: qemu 中 shutdown 的实现是让 guest OS 对 sifive,test1 设备进行 MMIO 写操作,在 qemu v5.1.0 中要求对该设备的 MMIO 必须是 32 位访问,而 OpenSBI 使用了 16 位的写操作 (这里),导致在 M 态发生 Store/AMO access fault 异常。 在 QEMU v5.2.0 之后该问题被修复,详见该补丁:qemu/qemu@ab3d207 |
问题描述
下载最新代码后,切换到 lab-1 分支,
make run
出现如下错误信息:之后,gbd 和 qemu 陷入卡死状态,目前我的处理方式是
kill -9
。我的环境
我的追踪过程
os/src/main.rs:44: 'end of rust_main'
提示,追踪到os/src/panic.rs::panic_handler:26
中shutdown
;os/src/sbi.rs:44
中shutdown
调用sbi_call(8,0,0,0)
。根据os/src/sbi.rs:7
的定义,发现是使用了ecall
请求 M 态(即SBI)服务,在这里是 qemu 下的 openSBI v0.7,该版本实现了 RISCV SBI 的 v0.2 版本。shutdown
的说明。起初,看到 Replacement EID 这一列时,认为可能是我的机器环境比实验手册中环境要新一些,故阅读完该文档之后,实现了一个新版本的sbi_shutdown
取代此前os/src/panic.rs::panic_handler:26
处的shutdown
,代码如下:而后,在
os/src/panic.rs::panic_handler:27
处打印struct Sbiret
的值,结果为sbi_ret.error = -2
和sbi_ret.value = 0
;根据文档,查到-2
代表SBI_ERR_NOT_SUPPORTED
,即 SBI v0.2 不支持这个用法。于是放弃了继续改写的打算,转而查找shutdown
后sbi_trap_error: hart0: trap handler failed (error -2)
原因。sbi_trap_error
trap handler failed
error
检索之后,发现相关内容数量少且关系不大。只好回到 rCore 本身。shutdown
和sbi_call
进行了断点调试,主要涉及os/src/panic.rs
和os/src/sbi.rs
两个文件,其中将os/src/interrupt/mod.rs:15
即timer::init()
注释掉了,因为这个时钟也是通过ecall
来实现的,因此会多次影响调试时的程序运行栈。结果证明是个loop
,只好另谋方案。opensbi/lib/sbi/sbi_trap.c::216
中,终于看到了熟悉的trap handler failed
的身影,根据函数名sbi_trap_handler
以及该函数注释,不难发现该函数和熟悉的rCore上的sbi_call
完美契合。在opensbi/lib/sbi/sbi_trap.c::267
中调用了在同一个文件中的函数sbi_trap_redirect
,此后将函数的返回值作为判断条件是否进行trap_error
处理;在opensbi/lib/sbi/sbi_trap.c::sbi_trap_error
中可以发现,这里的处理即是打印各种信息,而这和 rCoremake run
之后的错误信息完全一致;此后进入sbi_hart_hang
, 该函数内部是一个while (1)
循环,这也就解释了 gdb 和 qemu 卡死的原因。因此,知道sbi_trap_redirect
的返回值代表的含义就能发现问题的原因了。sbi_trap_redirect
中,返回值只有两个0
(opensbi/lib/sbi/sbi_trap.c::194
) 和SBI_ENOTSUPP
(opensbi/lib/sbi/sbi_trap.c::98
)。而根据make run
的错误信息,以及opensbi/lib/sbi/sbi_trap.c:29
不难知道这个不是0
而是-2
,因此可以得出假设SBI_ENOTSUPP = 2
。opensbi/include/sbi/sbi.error.h:19
发现了#define SBI_ENOTSUPP SBI_ERR_NOT_SUPPORTED
,又在opensbi/include/sbi/sbi_ecall/interface.h:88
中发现#define SBI_ERR_NOT_SUPPORTED -2
。于是假设SBI_ENOTSUPP = 2
得到了证实。原本找到错误的原因应该举杯欢庆,但是对 SBI_ERR_NOT_SUPPORTED 的字面意思又难以高兴起来,其意为 rCore 中的os/src/sbi.rs::shutdown
即sbi_call(8,0,0,0)
也是不支持。和最初想要自己动手写一个sbi_shutdown
一样,openSBI v0.7 目前都不支持。被这个问题困扰了一段时间之后,接下来的思路就是再搭建一个环境。sbi_shutdown
中,对于Replacement Extension
并没有指定,因此最初重写sbi_shutdown
后,返回值表明没有实现这个是合理的。但是,在Extension ID
列中,关于sbi_shutdown
指定的值确是0x08
,而经过上面的探究已经 openSBI 也给出了不支持的回答。至此,问题似乎明晰又不明晰。在看完 SBI v0.2 文档之后,发现 HSM实现sbi_hart_stop
,根据其解释结合
sbi_shutdown
的解释似乎可以通过
sbi_hart_stop
实现sbi_shutdown
。sbi_shutdown
如下然后,用
sbi_hart_stop
替代os/src/panic.rs:26
处的shutdown
。make run
之后光标停在了src/main.rs:44: 'end of rust_main'
之后。至此,shutdown
问题得到了解决,但是不确定的是这个方案优劣几何。sbi_shutdown
中ecall
对于EID = 8
不支持,那么EID = 0
的时钟是否也不支持呢?在将os/src/mod.rs:15
的timer::init();
解除注释后,再把os/src/main.rs:44
中的panic("end of rust_main")
改为loop {}
后,make run
发现打印出各种 ticks ,说明 open SBI v0.7 对于EID = 0
情况的ecall
是支持的。涉及文件
rCore-Tutorial 的 lab-1 下
相关段落
os/src/sbi.rs
os/src/sbi.rs::panic_handler
遇到问题
对于本问题的分析如上。但是对于目前给出
shutdown
的方案仍然感到疑惑。The text was updated successfully, but these errors were encountered: