xv6 中文文档
目錄
1. 介紹
2. 封面
3. 前言
4. 第零章 操作系统接口
5. 第一章 第一个进程
6. 第二章 页表
7. 第三章 陷入,中断和驱动程序
8. 第四章 锁
9. 第五章 调度
10. 第六章 文件系统
11. 附录A PC 硬件
12. 附录B 引导加载器
13. 术语
14. 勘误
2
xv6 中文文档
xv6 中文文档
xv6 是 MIT 开发的一个教学用的完整的类 Unix 操作系统,并且在 MIT 的操作系统课程 6.828 中使用。通过阅读并理解 xv6
的代码,可以清楚地了解操作系统中众多核心的概念,对操作系统感兴趣的同学十分推荐一读!这份文档是中文翻译的 MIT
xv6 文档,是阅读代码过程中非常好的参考资料。
原文在此
文中引用的 xv6 源代码
强烈推荐 xv6 源代码同本书一同阅读!原作和翻译中遇到的括号内的数字,都是指上面链接中文件的源代码行号。
同时,我们的翻译文档也可以通过 gitbook 阅读
译者
鲜染 北京大学 信息科学技术学院 计算机系
赵天雨 北京大学 信息科学技术学院 计算机系
胡树伟 北京大学 信息科学技术学院 计算机系(I guess)
胡文涛 KAUST CS
曹扬 上海交通大学 电子信息与电气工程学院 计算机系
如果你愿意贡献,你的名字也会出现在这里!
翻译状况
章节
初稿
审校
二审
封面
前言
零
一
二
三
四
五
六
附A
附B
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
参与审校
热情欢迎大家参与到审校工作中!请访问 https://github.com/Th0ar/xv6-chinese
1. Fork
介紹
3
xv6 中文文档
2. 审校并修改,保证修改后 markdown 解析正确
3. 发送 Pull Request
4. 等待你的名字(不久后)出现在译者列表中!
许可证(License)
文档中涉及到的 xv6 源代码使用 MIT 许可证。中文翻译使用 GNU GPL V3.0 许可证,在 GNU GPL V3.0 之上,转载和引用
须注明本项目 Github 地址。
介紹
4
xv6 中文文档
xv6
一个简单, 类 Unix 的教学操作系统
Russ Cox
Frans Kasshoek
Robert Morris
xv6-book@pdos.csail.mit.edu
翻译:
鲜染
xianran@pku.edu.cn
赵天雨
zhaoty.ting@gmail.com
2013年国庆
封面
5
xv6 中文文档
前言和致谢
这是一份为操作系统课编写的教学草案。它通过研究一个名为 xv6 的操作系统内核来解释操作系统中的主要概念。xv6 是
Dennis Ritchie 和 Ken Thompson 合著的 Unix Version 6(v6)操作系统的重新实现。xv6 在一定程度上遵守 v6 的结构和风
格,但它是用 ANSI C 实现的,并且是基于 x86 多核处理器的。
这本教材应该和 xv6 源代码一起阅读,这是 John Lion 在 Unix 6th Edition(Peer to Peer Communications;ISBN:1-
57398-013-7;第一版(2000年7月14日)的评注中推荐的学习方式。 参见http://pdos.csail.mit.edu/6.828 上有关于 v6 和
xv6 的资料。
我们已经在 6.828 —— MIT 的操作系统课程中使用了这本教材。我们向参与 6.828 的教职员工、助教和学生表示感谢,他们
都直接或间接向 xv6 做出了贡献。此处我们要特别感谢 Austin Clements 和 Nicholai Zeldovich。
前言
6
xv6 中文文档
第0章
操作系统接口
操作系统的工作是(1)将计算机的资源在多个程序间共享,并且给程序提供一系列比硬件本身更有用的服务。(2)管理并抽象底
层硬件,举例来说,一个文字处理软件(比如 word)不用去关心自己使用的是何种硬盘。(3)多路复用硬件,使得多个程序
可以(至少看起来是)同时运行的。(4)最后,给程序间提供一种受控的交互方式,使得程序之间可以共享数据、共同工作。
操作系统通过接口向用户程序提供服务。设计一个好的接口实际上是很难的。一方面我们希望接口设计得简单和精准,使其
易于正确地实现;另一方面,我们可能忍不住想为应用提供一些更加复杂的功能。解决这种矛盾的办法是让接口的设计依赖
于少量的机制 (mechanism),而通过这些机制的组合提供强大、通用的功能。
本书通过 xv6 操作系统来阐述操作系统的概念,它提供 Unix 操作系统中的基本接口(由 Ken Thompson 和 Dennis Ritchie
引入),同时模仿 Unix 的内部设计。Unix 里机制结合良好的窄接口提供了令人吃惊的通用性。这样的接口设计非常成功,
使得包括 BSD,Linux,Mac OS X,Solaris (甚至 Microsoft Windows 在某种程度上)都有类似 Unix 的接口。理解 xv6 是
理解这些操作系统的一个良好起点。
如图0-1所示,xv6 使用了传统的内核概念 - 一个向其他运行中程序提供服务的特殊程序。每一个运行中程序(称之为进程)
都拥有包含指令、数据、栈的内存空间。指令实现了程序的运算,数据是用于运算过程的变量,栈管理了程序的过程调用。
进程通过系统调用使用内核服务。系统调用会进入内核,让内核执行服务然后返回。所以进程总是在用户空间和内核空间之
间交替运行。
内核使用了 CPU 的硬件保护机制来保证用户进程只能访问自己的内存空间。内核拥有实现保护机制所需的硬件权限
(hardware privileges),而用户程序没有这些权限。当一个用户程序进行一次系统调用时,硬件会提升特权级并且开始执行一
些内核中预定义的功能。
内核提供的一系列系统调用就是用户程序可见的操作系统接口,xv6 内核提供了 Unix 传统系统调用的一部分,它们是:
系统调用
描述
fork()
exit()
wait()
kill(pid)
getpid()
sleep(n)
exec(filename, *argv)
sbrk(n)
第零章 操作系统接口
创建进程
结束当前进程
等待子进程结束
结束 pid 所指进程
获得当前进程 pid
睡眠 n 秒
加载并执行一个文件
为进程内存空间增加 n 字节
7
xv6 中文文档
open(filename, flags)
read(fd, buf, n)
write(fd, buf, n)
close(fd)
dup(fd)
pipe( p)
chdir(dirname)
mkdir(dirname)
mknod(name, major, minor)
fstat(fd)
link(f1, f2)
unlink(filename)
打开文件,flags 指定读/写模式
从文件中读 n 个字节到 buf
从 buf 中写 n 个字节到文件
关闭打开的 fd
复制 fd
创建管道, 并把读和写的 fd 返回到p
改变当前目录
创建新的目录
创建设备文件
返回文件信息
给 f1 创建一个新名字(f2)
删除文件
这一章剩下的部分将说明 xv6 系统服务的概貌 —— 进程,内存,文件描述符,管道和文件系统,为了描述他们,我们给出
了代码和一些讨论。这些系统调用在 shell 上的应用阐述了他们的设计是多么独具匠心。
shell 是一个普通的程序,它接受用户输入的命令并且执行它们,它也是传统 Unix 系统中最基本的用户界面。shell 作为一个
普通程序,而不是内核的一部分,充分说明了系统调用接口的强大:shell 并不是一个特别的用户程序。这也意味着 shell 是
很容易被替代的,实际上这导致了现代 Unix 系统有着各种各样的 shell,每一个都有着自己的用户界面和脚本特性。xv6
shell 本质上是一个 Unix Bourne shell 的简单实现。它的实现在第 7850 行。
进程和内存
一个 xv6 进程由两部分组成,一部分是用户内存空间(指令,数据,栈),另一部分是仅对内核可见的进程状态。xv6 提供
了分时特性:它在可用 CPU 之间不断切换,决定哪一个等待中的进程被执行。当一个进程不在执行时,xv6 保存它的 CPU
寄存器,当他们再次被执行时恢复这些寄存器的值。内核将每个进程和一个 pid (process identifier) 关联起来。
一个进程可以通过系统调用 fork 来创建一个新的进程。 fork 创建的新进程被称为子进程,子进程的内存内容同创建它的
进程(父进程)一样。 fork 函数在父进程、子进程中都返回(一次调用两次返回)。对于父进程它返回子进程的 pid,对于
子进程它返回 0。考虑下面这段代码:
int pid;
pid = fork();
if(pid > 0){
printf("parent: child=%d\n", pid);
pid = wait();
printf("child %d is done\n", pid);
} else if(pid == 0){
printf("child: exiting\n");
exit();
} else {
printf("fork error\n");
}
系统调用 exit 会导致调用它的进程停止运行,并且释放诸如内存和打开文件在内的资源。系统调用 wait 会返回一个当前
进程已退出的子进程,如果没有子进程退出, wait 会等候直到有一个子进程退出。在上面的例子中,下面的两行输出
parent: child=1234
child: exiting
第零章 操作系统接口
8