3.1 - OS的隔离性
我们希望各个程序之间互不干扰,一个程序崩溃不会导致另外的程序错误。比如说echo炸了不会导致shell错误,这在没有OS的单片机程序上是不可能的。
OS会让每一个程序运行一段时间,一段时间后交给另外的程序运行,这样程序就看起来一起运行了
3.1.1 - 内存隔离
内存隔离:一个程序不会覆盖另外的程序
在复用时,我们需要强隔离性
Unix接口抽象了硬件,可以方便的实现复用和物理内存方面的强隔离
不直接操作CPU,不再将CPU分配到某个程序
3.2 - OS的防御性
必须设置一些东西,防止程序破坏OS,并且OS不能拒绝服务某个程序。
这意味着OS和APP之间有强隔离性,常见的有硬件隔离。
通过指令中某个0/1的不同,分为特权指令,因此用户不能执行特权代码,只能通过操作系统操作。
3.3 - 硬件对隔离的支持
强内存隔离
CPU提供虚拟内存,处理器有页表,将虚拟地址映射到物理地址。
每个进程有不同的页表,那么进程就无法访问其他进程的内存。
3.4 - User/Kernel切换
system call:ecall <n>,其中n未sys call传递的值
内核:可信任计算的基础 TCP(Trusted Computing Base)
- kernel必须没有bug,不能让攻击者找到漏洞。
- 内核必须信任程序的运行
3.5 - 宏内核与微内核
- 宏内核:将整个OS运行在内核模式。
- 不好找bug(没1000行就有bug
- 不同子模块紧密结合
- 微内核:减少内核代码,将OS的其他部分当作用户程序对待
- 保留了最主要的消息传递、虚拟内存等。文件系统等放在用户态
- echo、shell等都运行在用户态
- 不容易出bug
- uk切换问题
xv6使用宏内核
3.6 - 编译运行kernel
makefile选择一个文件,如proc.c,交给gcc编译成汇编再转成二进制的proc.o。
都生成 ***.o 之后,将这些文件链接到一起,作为机器启动时执行的第一个程序。