LINK主题:
- 内核系统调用API
- 细节与设计
- 隔离、多路复用与共享
- 通过
shell
说明
概述图:
- 用户/内核
- 进程 = 地址空间 + 线程
- 进程是执行中的程序
- app -> printf() -> write() -> SYSTEM CALL -> sys_write() -> ...
- 用户级库是应用的私有业务
- 用户不能调用内核的内部函数
- xv6 包含几十个系统调用;Linux 有几百个
- 讨论有关 UNIX 系统调用 API 的细节
- xv6, Linux, OSX, POSIX 的标准基础
- JOS 拥有很多不同的系统调用,将在 JOS 上构建 UNIX 调用
观察 UNIX 系统调用
将 fork/exec
指令分开似乎很浪费 —— fork
复制内存, exec
清除内存,为什么不合并这两条指令?例如 pid = forkexec(path, argv, fd0, fd1)
?
将 fork/exec
指令分开是有用的:
fork()
:I/O 重定向、并行处理
exec()
:/bin/login ... exec("/bin/sh")
exec()
or fork()
:复杂的嵌套命令;退出。( ( cmd1 ; cmd2 ) | cmd3
)
fork()
对于微程序非常高效,在“我”的机器上:
fork+exec
takes 400 microseconds (2500 / second)fork
alone takes 80 microseconds (12000 / second)
文件描述符设计:
FD 是间接层级
- 内核隐藏了进程的真实读写环境
- 预留在
fork()
和exec()
上 - 将
I/O
的建立与使用分离 - imagine
writefile(filename, offset, buf size)
FD 提高了程序的通用能力:不需要考虑具体情况 (files vs console vs pipe)
哲学:一组概念性结合得很好的简单调用
e.g. fork()
, open()
, dup()
, exec()
command-line design has a similar approach
ls | wc -l
为什么内核要支持管道,而不是让 sh
模拟,例如 ls > tempfile ; wc -l < tempfile
这一部分在课本中讨论过了,好处有:
- 管道会自动清理无用数据,而文件重定向需要在结束后手动清理
- 管道可以传递任意长度的数据流
- 管道允许并行执行
- 对于进程间的通信,管道的读写锁更高效
系统调用的接口简单到只有 int
和 char
的缓冲,为什么不使用 open
返回内核文件的指针调用?
UNIX 内核很古老,这样的思想是否很好?
非常成功,并且多年来发展良好
历史:
- 这种设计迎合了命令行和
s/w
的发展 - 系统调用接口方便程序员使用
- 命令行用户喜欢命名文件,管道,&c等
- 对开发、调试、服务器维护很重要
但 UNIX 的思想并不完美
- 对于系统调用 API,程序员的便利性价值不高
- 程序员可以使用库,例如python隐藏了系统调用
- 应用可能与文件和c无关,例如手机平台
- 一些 UNIX 抽象概念效率不高
fork
用于 multi-GB 的进程非常缓慢- FD 可能隐藏了重要的细节
- 磁盘文件的块大小
- 网络消息的时间和大小
so there has been lots of work on alternate plans
sometimes new system calls and abstractions for existing UNIX-like kernels
sometimes entirely new approaches to what a kernel should do
ask "why this way? wouldn't design X be better?"
操纵系统组织
OS organization
主要目标:隔离
处理器提供 用户模式 和 内核模式
- 内核模式:能够执行“特权”指令
- 例如:设置
kernel/user bit
- 用户模式:不能执行"特权"指令
操作系统在内核模式运行:
- 内核是可信的
- 可以设置
kernel/user bit
- 可以直接访问硬件
应用程序在用户模式运行:
- 内核设置进程间隔离的地址空间
- 系统调用在内核模式和用户模式间切换:应用程序执行特殊指令进入内核,使硬件切换至内核模式,但仅限于内核指定的调用入口。
内核中有什么?
xv6遵循传统设计:所有操作系统都以内核模式运行
- 一个巨大的,包含文件系统,驱动 和 &c 的程序
- 这种设计被称为单片内核
- 内核接口 == 系统调用接口
- 优点:
- 子系统易于协作
- 文件系统和虚拟内存共享一个缓存
- 缺点:
- 接口复杂
- 容易引发 bug
- 内核内部没有隔离
微内核设计:
- 许多系统服务以普通用户程序运行;文件系统在文件服务器内
- 内核实现了在用户空间中运行服务的最小机制
- 带存储的进程
- 进程间通信 (inter-process communication (IPC))
- 内核接口 != 系统调用接口
- 优点:多层隔离
- 缺点:也许难以实现高性能
外核心,极限内核(exokernel):没有抽象
应用程序半直接地使用硬件,但 O/S isolates
- 如:应用程序可以读写自己的页表,但需由 O/S 审核
- 如:应用程序可以读写自己的磁盘块,但 O/S 跟踪块所有者
优点:对于严格的应用程序拥有更高的灵活性
JOS 将结合 微内核 和 外内核
可以在没有h / w支持的内核/用户模式的情况下进行进程隔离吗?
是!在学期后期可以参考Singularity O / S.但是h/w 用户/内核 模式是最流行的方案