提交 bacee597 编写于 作者: chyyuu1972's avatar chyyuu1972

Merge branch 'main' into deploy

......@@ -228,9 +228,9 @@ Qemu 模拟器安装
.. code-block:: bash
# 请注意,qemu-5.0.0 的父目录可以随着你的实际安装位置灵活调整
export PATH=$PATH:/home/shinbokuow/Downloads/built/qemu-5.0.0
export PATH=$PATH:/home/shinbokuow/Downloads/built/qemu-5.0.0/riscv64-softmmu
export PATH=$PATH:/home/shinbokuow/Downloads/built/qemu-5.0.0/riscv64-linux-user
export PATH=$PATH:$HOME/qemu-5.0.0
export PATH=$PATH:$HOME/qemu-5.0.0/riscv64-softmmu
export PATH=$PATH:$HOME/qemu-5.0.0/riscv64-linux-user
随后即可在当前终端 ``source ~/.bashrc`` 更新系统路径,或者直接重启一个新的终端。
......
......@@ -106,7 +106,7 @@
系统调用
^^^^^^^^^^^^^^^^^^^^^^
在子模块 ``syscall`` 中我们作为应用程序来通过 ``ecall`` 调用批处理系统提供的接口,由于应用程序运行在用户态(即 U 模式), ``ecall`` 指令会触发 名为 *Environment call from U-mode* 的异常,并 Trap 进入 S 模式执行批处理系统针对这个异常特别提供的服务代码。由于这个接口处于 S 模式的批处理系统和 U 模式的应用程序之间,从上一节我们可以知道,这个接口可以被称为 ABI 或者系统调用。现在我们不关心底层的批处理系统如何提供应用程序所需的功能,只是站在应用程序的角度去使用即可。
在子模块 ``syscall`` 中,应用程序通过 ``ecall`` 调用批处理系统提供的接口,由于应用程序运行在用户态(即 U 模式), ``ecall`` 指令会触发 名为 *Environment call from U-mode* 的异常,并 Trap 进入 S 模式执行批处理系统针对这个异常特别提供的服务代码。由于这个接口处于 S 模式的批处理系统和 U 模式的应用程序之间,从上一节我们可以知道,这个接口可以被称为 ABI 或者系统调用。现在我们不关心底层的批处理系统如何提供应用程序所需的功能,只是站在应用程序的角度去使用即可。
在本章中,应用程序和批处理系统之间按照 API 的结构,约定如下两个系统调用:
......
......@@ -291,7 +291,7 @@ Rust 编译器提示我们 ``RefCell<i32>`` 未被标记为 ``Sync`` ,因此 R
.. _term-dcache:
.. _term-icache:
注意第 7 行我们插入了一条奇怪的汇编指令 ``fence.i`` ,它是用来清理 i-cache 的。我们知道缓存是存储层级结构中提高访存速度的很重要一环。而 CPU 对物理内存所做的缓存又分成 **数据缓存** (d-cache) 和 **指令缓存** (i-cache) 两部分,分别在 CPU 访存和取指的时候使用。在取指的时候,对于一个指令地址, CPU 会先去 i-cache 里面看一下它是否在某个已缓存的缓存行内,如果在的话它就会直接从高速缓存中拿到指令而不是通过总线访问内存。通常情况下, CPU 会认为程序的代码段不会发生变化,因此 i-cache 是一种只读缓存。但在这里,我们将修改会被 CPU 取指的内存区域,这会使得 i-cache 中含有与内存中不一致的内容。因此我们这里必须使用 ``fence.i`` 指令手动清空 i-cache ,让里面所有的内容全部失效,才能够保证CPU访问内存数据和代码的正确性。
注意第 7 行我们插入了一条奇怪的汇编指令 ``fence.i`` ,它是用来清理 i-cache 的。我们知道缓存是存储层级结构中提高访存速度的很重要一环。而 CPU 对物理内存所做的缓存又分成 **数据缓存** (d-cache) 和 **指令缓存** (i-cache) 两部分,分别在 CPU 访存和取指的时候使用。在取指的时候,对于一个指令地址, CPU 会先去 i-cache 里面看一下它是否在某个已缓存的缓存行内,如果在的话它就会直接从高速缓存中拿到指令而不是通过总线访问内存。通常情况下, CPU 会认为程序的代码段不会发生变化,因此 i-cache 是一种只读缓存。但在这里,OS将修改会被 CPU 取指的内存区域,这会使得 i-cache 中含有与内存中不一致的内容。因此OS在这里必须使用 ``fence.i`` 指令手动清空 i-cache ,让里面所有的内容全部失效,才能够保证CPU访问内存数据和代码的正确性。
.. warning::
......
......@@ -296,7 +296,7 @@ Trap 处理的总体流程如下:首先通过 ``__alltraps`` 将 Trap 上下
- 第 12 行,我们准备在内核栈上保存 Trap 上下文,于是预先分配 :math:`34\times 8` 字节的栈帧,这里改动的是 sp ,说明确实是在内核栈上。
- 第 13~24 行,保存 Trap 上下文的通用寄存器 x0~x31,跳过 x0 和 tp(x4),原因之前已经说明。我们在这里也不保存 sp(x2),因为我们要基于它来找到每个寄存器应该被保存到的正确的位置。实际上,在栈帧分配之后,我们可用于保存 Trap 上下文的地址区间为 :math:`[\text{sp},\text{sp}+8\times34)` ,按照 ``TrapContext`` 结构体的内存布局,基于内核栈的位置(sp所指地址)来从低地址到高地址分别按顺序放置 x0~x31这些通用寄存器,最后是 sstatus 和 sepc 。因此通用寄存器 xn 应该被保存在地址区间 :math:`[\text{sp}+8n,\text{sp}+8(n+1))` 。
为了简化代码,x5~x31 这 27 个通用寄存器我们通过类似循环的 ``.rept`` 每次使用 ``SAVE_GP`` 宏来保存,其实质是相同的。注意我们需要在 ``Trap.S`` 开头加上 ``.altmacro`` 才能正常使用 ``.rept`` 命令。
为了简化代码,x5~x31 这 27 个通用寄存器我们通过类似循环的 ``.rept`` 每次使用 ``SAVE_GP`` 宏来保存,其实质是相同的。注意我们需要在 ``trap.S`` 开头加上 ``.altmacro`` 才能正常使用 ``.rept`` 命令。
- 第 25~28 行,我们将 CSR sstatus 和 sepc 的值分别读到寄存器 t0 和 t1 中然后保存到内核栈对应的位置上。指令 :math:`\text{csrr rd, csr}` 的功能就是将 CSR 的值读到寄存器 :math:`\text{rd}` 中。这里我们不用担心 t0 和 t1 被覆盖,因为它们刚刚已经被保存了。
- 第 30~31 行专门处理 sp 的问题。首先将 sscratch 的值读到寄存器 t2 并保存到内核栈上,注意: sscratch 的值是进入 Trap 之前的 sp 的值,指向用户栈。而现在的 sp 则指向内核栈。
- 第 33 行令 :math:`\text{a}_0\leftarrow\text{sp}`,让寄存器 a0 指向内核栈的栈指针也就是我们刚刚保存的 Trap 上下文的地址,这是由于我们接下来要调用 ``trap_handler`` 进行 Trap 处理,它的第一个参数 ``cx`` 由调用规范要从 a0 中获取。而 Trap 处理函数 ``trap_handler`` 需要 Trap 上下文的原因在于:它需要知道其中某些寄存器的值,比如在系统调用的时候应用程序传过来的 syscall ID 和对应参数。我们不能直接使用这些寄存器现在的值,因为它们可能已经被修改了,因此要去内核栈上找已经被保存下来的值。
......
......@@ -122,7 +122,7 @@
当一个应用的地址空间比较大的时候,页表中的项数会很多(事实上每个虚拟页面都应该对应页表中的一项,上图中我们已经省略掉了那些未被使用的虚拟页面),导致它的容量极速膨胀,已经不再是像之前那样数个寄存器便可存下来的了,CPU 内也没有足够的硬件资源能够将它存下来。因此它只能作为一种被内核管理的数据结构放在内存中,但是 CPU 也会直接访问它来查页表,这也就需要内核和硬件之间关于页表的内存布局达成一致。
由于分页内存管理既简单又灵活,它逐渐成为了主流的内存管理机制,RISC-V 架构也使用了这种自己。后面我们会基于这种机制,自己动手从物理内存抽象出应用的地址空间来。
由于分页内存管理既简单又灵活,它逐渐成为了主流的内存管理机制,RISC-V 架构也使用了这种机制。后面我们会基于这种机制,自己动手从物理内存抽象出应用的地址空间来。
.. note::
......
此差异已折叠。
......@@ -2,7 +2,7 @@
==============================================
.. toctree::
:maxdepth: 4
:maxdepth: 5
0intro
1rust-dynamic-allocation
......@@ -11,6 +11,7 @@
4sv39-implementation-2
5kernel-app-spaces
6multitasking-based-on-as
7exercise
7more-as
8exercise
.. chyyuu 添加扩展阅读 虚拟内存超越物理内存,通过换页机制???
\ No newline at end of file
此差异已折叠。
第五章:进程及进程管理
第五章:进程
==============================================
.. toctree::
......@@ -8,6 +8,7 @@
1process
2core-data-structures
3implement-process-mechanism
4exercise
4scheduling
5exercise
.. chyyuu 有一节来 回顾,归纳总结进程 抽象/虚拟???
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册