我正在回想我最近对编程的介绍,并记得编写了一个故意随机读取和写入内存地址的 C++ 程序。我这样做是为了看看会发生什么。
令我惊讶的是,在我的 Windows 98 PC 上,我的程序会产生一些非常奇怪的副作用。有时它会切换操作系统设置,或创建图形故障。通常情况下,它什么也不做,或者只是让整个系统崩溃。
后来我了解到这是因为 Windows 98 没有限制用户进程可以访问的内容。我可以读写其他进程甚至操作系统使用的 RAM。
据我了解,Windows NT 改变了这种情况(尽管我认为它需要一段时间才能正确)。现在,Windows 会阻止您在不属于您的进程的 RAM 中四处寻找。
我隐约记得后来在 Linux 系统上运行我的程序并没有得到几乎那么多有趣的结果。如果我理解正确,这至少部分是由于用户和内核空间的分离。
所以,我的问题是:
有没有一段时间 Linux 没有分离用户和内核空间?换句话说,我的恶意程序是否曾经对 Linux 系统造成类似的破坏?
Linux一直通过防止用户空间直接访问它使用的内存来保护内核;它还始终保护进程不直接访问彼此的内存。程序只能通过虚拟地址空间访问内存,该地址空间可以访问内核为它们映射的内存;访问外部分配的内存会导致分段错误。(程序可以通过系统调用和驱动程序访问内核,包括臭名昭著的
/dev/mem
和/dev/kmem
;它们还可以相互共享内存。)MMU 在 Unix/Linux 内核中吗?还是只是在具有自己内存的硬件设备中?解释了当今 Linux 如何处理内核/用户分离(Linux 的早期版本对此进行了不同的处理;有关详细信息,请参阅Linux 内存管理概述和80386 内存管理)。
一些与 Linux 相关的项目消除了这种分离;例如,嵌入式 Linux 内核子集是与 8086 CPU 兼容的 Linux 子集,因此它不提供硬件强制保护。µClinux为没有内存管理单元的嵌入式系统提供支持,并且它的核心“成分”现在是主线内核的一部分,但这种配置在“PC”架构上是不可能的。
这取决于您如何定义术语“Linux”、“用户空间”和“内核空间”。
记住 Linus Torvalds 最初是如何创建 Linux 的。Linus 节省了一些钱给自己买了一台(当时最先进的)带有 Intel 80386 CPU 的 PC。他想了解 80386 的工作原理,他认为最好的方法是在 80386 汇编中编写一些低级硬件代码。同时,他也对自己用来登录大学的Minix下运行的终端仿真器的性能不满意。
因此,他决定在 80386 程序集中编写一个终端仿真器,您可以直接启动它。为此,他需要编写一个引导加载程序、一个键盘驱动程序、一个(字符)显示驱动程序、一个串行驱动程序以及一个用于他用来连接大学的任何协议的驱动程序。
很快,他发现自己也想从大学下载文件,所以他必须实现一些文件传输协议(可能是ZMODEM,但可能为了简单起见他选择了XMODEM)以及硬盘驱动程序、分区表解析器和文件系统Minix 文件系统的驱动程序。因为他还想在终端仿真器执行一些长时间运行的操作(例如文件下载)时继续工作,所以他实现了多线程。
这就是他意识到他已经实现了操作系统的一些重要部分的地方,因此他认为将终端模拟器变成一个有趣的项目将是另一个有趣的项目。
在那之后的某个时候,他不小心打错了一个命令,并用备份覆盖了他的 Minix 分区。现在他必须做出选择:重新安装 Minix 或完成他的操作系统并改用它。
当他的操作系统能够运行简单的程序时,他决定将其上传到大学的 FTP 服务器,并将其命名为 Freax(他认为以自己的名字命名某些东西是自命不凡和傲慢的)。不过,FTP 服务器的系统管理员不喜欢这个名称,并决定将文件重命名为 Linux,他认为这听起来更好。
又过了一段时间,Linus 在他的著名信息中首次公开提及 Linux,他说 Linux 与 80386 紧密相连,以至于它永远无法移植到其他任何东西上,并且他预测 Linux 永远不会大而专业。
现在,问题是:“Linux”在这个旅程的哪个时刻变成了“Linux”,在这个旅程的哪个时刻Linux变成了一个“内核”,所以谈论用户和内核空间的分离甚至是有意义的?
正如我在一开始所说:这真的取决于你如何定义这些术语。
在它的演变过程中肯定有一段时间,后来成为操作系统并且后来被称为“Linux”的软件没有保护,有足够复杂的服务,你可能会称它为“内核”并且有足够的独立性您可能会通过将这些子系统称为“程序”而逃脱的子系统。例如,在“真实”的 Unix 系统中,终端仿真器和文件传输通常是两个独立的程序,而协调这两者并包含访问串行端口、硬盘、屏幕、键盘,文件系统将是内核。
但是这个软件是“Linux”吗?我将把它留给你来决定。
是的,Linux 一直需要一个 MMU 来保护内存。很多人已经将它移植到没有 MMU 的小型嵌入式系统上,但不会再有完整的内存保护,所以一个进程几乎可以读/写所有东西