January 1, 0001
# 实现应用程序
如果直接make build
,则在执行qemu-riscv64
用户态模拟器时会出现段错误。解决方法是将linker script中指明的段全部进行4K对齐。
/* ... */
. = ALIGN(4K);
.rodata : {
/* ... */
. = ALIGN(4K);
.data : {
/* ... */
. = ALIGN(4K);
.bss : {
/* ... */
猜想可能是用户态模拟器需要利用宿主系统(Linux)本身的页保护系统,而这要求4K对齐。
# 实现批处理操作系统
关于lazy_static
中奇怪的static ref
:users.rust-lang.org
link_app.S中有一些设计:
.align 3
是「以$2^3=8$字节为单位」的意思。这是因为下面的数组元素长度是四字(quad)。.quad app_4_end
有点像\0
,是用来指示终止的。
# 实现特权级的切换
sscratch
寄存器在特权级切换过程中的作用如下图所示:
![[trap-restore.drawio.png]]
数据分布和完整的数据流及控制流如图所示:
![[trap-restore-flow.drawio.png]]
# 练习
# 课后练习
4
原来$time
的读取在riscv::asm
里有接口,是我大意了。
# 实验练习
这个说实话有点坑。框架里实际上是划了一块长度为0x4000
(16384)的堆空间给buffered println!
用的,这就导致如下两个问题:
- 由于堆空间是在
user/
中指定的,而user/
的linker script起始地址是0x80400000
,和程序空间事实上产生了重叠!也就是说,你往里头分配点东西,这程序就没了; - buffer的位置在
0x80406000
,这个地址长于两个程序各自的长度,会直接导致我们设计的地址检查机构失效;再者与1中情况类似:就算不失效,也很难保证buffer的写入不会对程序本身造成破坏。 反正就是,你为啥要在ch2-lab
里给我这么一个诡异的东西呢?解决办法就是把println!
替换成write()
系统调用,一切都安静了。