我回想起最近的编程入门,记得编写了一个 C++ 程序,该程序故意随机读取和写入内存地址。我这样做是为了看看会发生什么。
令我惊讶的是,在我的 Windows 98 PC 上,我的程序会产生一些非常奇怪的副作用。有时它会切换操作系统设置,或产生图形故障。通常它不会执行任何操作或只是使整个系统崩溃。
后来我了解到这是因为 Windows 98 没有限制用户进程可以访问的内容。我可以读取和写入其他进程甚至操作系统使用的 RAM。
据我了解,随着 Windows NT 的出现,这种情况发生了变化(尽管我认为花了一段时间才得到纠正)。现在,Windows 会阻止您查看不属于您的进程的 RAM。
我依稀记得后来在 Linux 系统上运行我的程序并没有得到那么多有趣的结果。如果我理解正确的话,这至少部分是由于用户空间和内核空间的分离造成的。
所以,我的问题是:
Linux 是否曾一度没有将用户空间和内核空间分开?换句话说,我的流氓程序是否曾经对 Linux 系统造成过类似的破坏?
我想尝试编译无 mmu 的内核。从我在配置中发现的情况来看,没有这样的选择。有没有可能做到?
今天几乎所有内核都使用 MMU 提供的虚拟内存。他们使用全局页表(其地址位于 CPU 寄存器中)和页到进程的页管理器/映射器来实现这一点。vmlinuz
例如,中的“vm”表示 linux 内核支持虚拟内存。
所有这一切都是可能的,因为 MMU 将连续的内存地址映射到 x86 架构能够理解的内存段。
最初的 UNIX 内核确实有一个vmunix
版本,我相信它一定使用了类似的技术。然而,最初的 UNIX 内核是在 MMU 可用之前编写的。如果我没有记错的话,最初的 UNIX 内核(简称unix
)是在 x86 体系结构存在之前编写的。从历史上看,它确实在 PDP-9 和 PDP-11 上运行。
该内核如何执行内存寻址和管理?它是基于段的寻址(两个数字)还是全内存寻址(单个数字)?它如何在处理之间分离内存?