Skip to content
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

翻译似乎有点和原文不符合 #67

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion content/chapter5.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ xv6 必须为进程提供互相协作的方法。譬如,父进程需要等待

接下来我们先不考察调度器调用 `swtch` 的过程,我们先回到用户进程中看看。在第3章中我们知道,有可能在中断的最后,`trap` 会调用 `yield`。`yield` 又调用 `sched`,其中 `sched` 会调用 `swtch` 来保存当前上下文到 `proc->context` 中然后切换到之前保存的调度器上下文 `cpu->scheduler`(2516)。

`swtch`(2702)一开始从栈中弹出参数,放入寄存器 `%eax` 和 `%edx`(2709-2710)中;`swtch` 必须在改变栈指针以及无法获得 `%esp` 前完成这些事情。然后 `swtch` 压入寄存器,在当前栈上建立一个新的上下文结构。仅有被调用者保存的寄存器此时需要被保存;按照 x86 的惯例即 `%ebp %ebx %esi %edi %esp`。`swtch` 显式地压入前四个寄存器(2713-2716);最后一个则是在 `struct context*` 被写入 `old`(2719)时隐式地保存的。要注意,还有一个重要的寄存器,即程序计数器 `%eip`,该寄存器在使用 `call` 调用 `swtch` 时就保存在栈中 `%ebp` 之上的位置上了。保存了旧寄存器后,`swtch` 就准备要恢复新的寄存器了。它将指向新上下文的指针放入栈指针中(2720)。新的栈结构和旧的栈相同,因为新的上下文其实是之前某次的切换中的旧上下文。所以 `swtch` 就能颠倒一下保存旧上下文的顺序来恢复新上下文。它弹出 `%edi %esi %ebx %ebp` 然后返回(2723-2727)。由于 `swtch` 改变了栈指针,所以这时恢复的寄存器就是新上下文中的寄存器值。
`swtch`(2702)一开始从栈中复制参数,放入寄存器 `%eax` 和 `%edx`(2709-2710)中;`swtch` 必须在改变栈指针以及无法获得 `%esp` 前完成这些事情。然后 `swtch` 压入寄存器,在当前栈上建立一个新的上下文结构。仅有被调用者保存的寄存器此时需要被保存;按照 x86 的惯例即 `%ebp %ebx %esi %edi %esp`。`swtch` 显式地压入前四个寄存器(2713-2716);最后一个则是在 `struct context*` 被写入 `old`(2719)时隐式地保存的。要注意,还有一个重要的寄存器,即程序计数器 `%eip`,该寄存器在使用 `call` 调用 `swtch` 时就保存在栈中 `%ebp` 之上的位置上了。保存了旧寄存器后,`swtch` 就准备要恢复新的寄存器了。它将指向新上下文的指针放入栈指针中(2720)。新的栈结构和旧的栈相同,因为新的上下文其实是之前某次的切换中的旧上下文。所以 `swtch` 就能颠倒一下保存旧上下文的顺序来恢复新上下文。它弹出 `%edi %esi %ebx %ebp` 然后返回(2723-2727)。由于 `swtch` 改变了栈指针,所以这时恢复的寄存器就是新上下文中的寄存器值。

在我们的例子中,`sched` 调用 `swtch` 切换到 `cpu->scheduler`,即 per-cpu 的调度器上下文。这个上下文是在之前 `scheduler` 调用 `swtch`(2478)时保存的。当 `swtch` 返回时,它不会返回到 `sched` 中,而是返回到 `scheduler`,其栈指针指向了当前 CPU 的调度器的栈,而非 `initproc` 的内核栈。

Expand Down