From e75a11269dae7c1f6b3ad9ea7343244881792c68 Mon Sep 17 00:00:00 2001 From: stormckey Date: Mon, 11 Dec 2023 16:21:32 +0800 Subject: [PATCH] unify second part --- docs/blog/posts/OS_lab3.md | 7 +++---- docs/blog/posts/OS_lab4.md | 12 +++++------- 2 files changed, 8 insertions(+), 11 deletions(-) diff --git a/docs/blog/posts/OS_lab3.md b/docs/blog/posts/OS_lab3.md index 5754ff5e..7a6142c8 100644 --- a/docs/blog/posts/OS_lab3.md +++ b/docs/blog/posts/OS_lab3.md @@ -37,9 +37,8 @@ nostatistics: true 2. 注意这里跳填表要填直接映射和等值映射两段 3. 确定好不同段的物理虚拟地址和权限等,调用 creat_mapping 函数分配并填写页表,注意页表项均使用物理地址 -## 注意事项 -### 写 satp +## 写 satp 我们启用虚拟内存的那一步,也就是写 satp 的那一步只是一句`csrw`,指令写完寄存器也不会干什么额外的事情,CP 还是要继续去 PC+4 执行下一条指令. @@ -48,13 +47,13 @@ nostatistics: true 1. 有对应的映射吗,或者是用中断处理? -### 为什么第一次我们启用的页表是一级的 +## 为什么第一次我们启用的页表是一级的 文档中其实已经有链接指向了解释这一点的文档,具体而言,在这段描述转化虚拟内存的过程的[:octicons-book-16:手册](https://www.five-embeddev.com/riscv-isa-manual/latest/supervisor.html#sv32algorithm)中 仔细阅读,其中第四点提到若当前页表项的权限表明了可读或者可执行,那么就会当作是最后一级页表,否则才会把它当作某一级的页表 -### debug 注意 +## debug 注意 - 当我们按照文档修改了链接文件后,我们 gdb 中直接用符号来打断点之类的操作就都是按照修改了链接文件之后的虚拟地址了,所以启用虚拟内存之前为了在正确的物理地址打断点,需要手动输入地址. - 如果你跟我一样改完页表没事,但是一刷新 tlb 就寄了.于我的经验而言,是页表写的有问题. diff --git a/docs/blog/posts/OS_lab4.md b/docs/blog/posts/OS_lab4.md index 702be6a7..345a85e6 100644 --- a/docs/blog/posts/OS_lab4.md +++ b/docs/blog/posts/OS_lab4.md @@ -56,30 +56,28 @@ nostatistics: true 5. sepc 在__switch_to 中就已经 load 好了 6. 这里加载的 PCB 就是我们 task_init 的时候写好的,注意这里加载的 ra 我们初始化时设置为__dummy -## 注意事项 - -### uapp 的加载 +## uapp 的加载 在 vmlinux.lds 中,我们指定的 uapp.S 文件会被加载到 _sramdisk,_eramdisk 之间 - 如果 uapp.S 中我们用的是纯二进制文件,那么_sramdisk 第一行就是程序第一行 - 如果 uapp.S 中我们用的是 elf 文件,我们需要解码 elf 头来定位具体的二进制位置, 同时elf中也制定了程序入口一类的信息 -### phdr->p_flags +## phdr->p_flags 注意这一项虽然是声明权限的的但定义不等同于页表项的 perm,定义如下: ![](images/OS_lab4/2023-12-01-17-51-47.png#pic) -### 执行权限 +## 执行权限 注意设置好页表和 sstatus 保证运行用户态代码时权限检查能够通过,否则会导致 scause = 0xc 的 inst page fault 此时也许我们可以在 gdb 中读信息但是一执行就出错 -### 拷贝问题 +## 拷贝问题 虚拟内存映射是以页为单位的,比如 0x00010000 起的虚拟页映射到 0x80000000 起的物理页,如果我们的程序入口在 0x100e8,那么我们应该把这个入口拷贝至 0x800000e8 而不是 0x80000000 -### 栈切换 +## 栈切换 在_traps 中,对于一些内核线程发起的异常是不需要切换栈的,我们通过检查 sscratch 为 0 来确认这一点