本文由 简悦SimpRead 转码,原文地址 codingkaiser.blog
如果我们现在从头开始写一个新的操作系统,会发生什么?我们可以做得更好吗?我们可以改善......。
如果我们现在从头开始写一个新的操作系统,会发生什么?我们可以做得更好吗?我们可以提高安全性和稳健性吗?我们可以防止应用程序之间的意外互动?
"如果一个软件平台从头开始设计,以可依赖性为主要目标,会是什么样子?" [1]
这些都是微软研究团队在18年前试图回答的问题,就在那时,他们为自己的新操作系统想出了一个相当酷的名字--Singularity。
Singularity旨在消除现有操作系统的一些缺点,如
-
一般的安全漏洞
-
由于扩展、驱动、附加组件造成的故障。
-
应用程序之间意外的相互作用
-
缺少稳健性
-
利用安全的编程语言--不再有C语言的恶作剧,我们不想从整数中 "煮 "出指针,不再手动释放内存,不再有缓冲区溢出。
-
使用验证工具--施加约束,使验证更容易。
-
改进系统结构和设计。
Singularity提供了3个主要的抽象概念。
- 软件隔离的过程(SIPs)
- 基于合同的渠道
- 基于清单的程序(MBPs)
让我们深入了解一下这些。
软件隔离的过程
一个SIP就像一个普通的进程--持有处理资源、上下文和线程的容器。
相当令人惊讶的是,所有的SIP和内核都运行在同一个地址空间,这也意味着用户代码以全硬件权限运行。
这难道不是完全违背直觉的吗?我们刚刚提到,我们想提高安全性是我们的目标之一,而这种改变似乎使它变得更糟。
首先,让我们想一想,他们为什么要做这种改变?
它是否改善了什么?
答案是肯定的(很明显),它提高了 性能。
因为所有的SIP都在同一个地址空间,所以_上下文切换_执行得更快。
- 不需要切换页表
- 不需要使TLB失效和重新填充。
此外,系统调用 也更快。
- 我们总是处于CPL=0的状态
- 不需要加载内核堆栈
- 不需要发送中断,我们可以直接调用一个函数
在我们说服自己,有了这个变化性能会更好之后,让我们来处理这个看起来很安全的问题。
每个SIP实际上是密封的--它们不能从外部被修改。 不同的SIP之间没有共享内存,没有信号,只有明确的IPC。 也没有来自内部的代码修改--没有JIT,类加载器,动态库。
为了确保SIP是真正密封的,我们采用了以下约束条件
- 一个SIP只指向它自己的数据 - 没有指向其他SIP的指针
- 没有指向内核的指针
- SIP只能访问内核给它的内存。
- SIP不能创建新的指针 - 指针可以由可信的来源提供,如内核。
有了这些限制,虽然有一个共享的地址空间,但没有数据的共享。
基于合同的通道
我们可以把通道看作是能力。 每个SIP可以有多个通道,通过它们我们可以创建IPC(进程间通信)。 例如,一个打开的文件是一个从文件服务器收到的通道。 如果一个SIP得到这个通道,意味着它有权限访问它。
基于manifest的程序
一个清单描述了一个SIP的能力、所需资源和依赖性。 没有清单和通道,一个SIP就不能做任何事情。 安装清单时,我们要验证它是否符合所有的安全要求,是否满足所有的依赖性,并且不会与之前安装的清单产生冲突。 例如,一个驱动程序的清单提供了 "证据",证明它不会访问另一个驱动程序的硬件。
在我们分道扬镳之前,这里还有一些数字和表格,说明了奇点和其他知名操作系统之间的比较
Singularity只是众多实验性操作系统中的一个例子。 它的最后一次发布是在2008年11月,从那时起这个项目就停止了。
你可以在Github上找到源代码。 如果你想阅读更多关于这个主题的内容,这里有一些好的材料
如果你想进一步熟悉操作系统,我可以建议你使用以下材料/书籍
[1] 微软的奇点项目概述