.\icu

Blog of @megakite.


January 1, 0001

# 实现应用程序

如果直接make build,则在执行qemu-riscv64用户态模拟器时会出现段错误。解决方法是将linker script中指明的段全部进行4K对齐

/* ... */
. = ALIGN(4K);
.rodata : {
/* ... */
. = ALIGN(4K);
.data : {
/* ... */
. = ALIGN(4K);
.bss : {
/* ... */

猜想可能是用户态模拟器需要利用宿主系统(Linux)本身的页保护系统,而这要求4K对齐。

# 实现批处理操作系统

关于lazy_static中奇怪的static refusers.rust-lang.org link_app.S中有一些设计:

  1. .align 3是「以$2^3=8$字节为单位」的意思。这是因为下面的数组元素长度是四字(quad)
  2. .quad app_4_end有点像\0,是用来指示终止的。

# 实现特权级的切换

sscratch寄存器在特权级切换过程中的作用如下图所示: ![[trap-restore.drawio.png]] 数据分布和完整的数据流及控制流如图所示: ![[trap-restore-flow.drawio.png]]

# 练习

# 课后练习

4 原来$time的读取在riscv::asm里有接口,是我大意了。

# 实验练习

这个说实话有点坑。框架里实际上是划了一块长度为0x4000(16384)的堆空间给buffered println!用的,这就导致如下两个问题:

  1. 由于堆空间是在user/中指定的,而user/的linker script起始地址是0x80400000,和程序空间事实上产生了重叠!也就是说,你往里头分配点东西,这程序就没了;
  2. buffer的位置在0x80406000,这个地址长于两个程序各自的长度,会直接导致我们设计的地址检查机构失效;再者与1中情况类似:就算不失效,也很难保证buffer的写入不会对程序本身造成破坏。 反正就是,你为啥要在ch2-lab里给我这么一个诡异的东西呢?解决办法就是把println!替换成write()系统调用,一切都安静了。