内核高内存

6
在操作系统设计中,内核大多映射到高的虚拟内存地址,从而控制了上部内存空间。留下的空间用于运行在用户空间中的应用程序,正如在“Linux 3/1 virtual address split”中以出色的方式描述的那样。
我想知道的是,为什么要做出这种设计决策,或者为什么内核不使用内存的下半部分?这对我来说并不清楚,或者我可能忽视了某些东西。
编辑:此问题涉及虚拟地址而非物理地址。

只是猜测:惯例是让人们更容易记住哪些内存部分应该受到用户空间代码的保护。 - ren
好的,但内核的内存总是有限的,或者用户空间的内存可能会被浪费。因此,当内核需要额外的内存(例如加载模块)时,它可以分配并设置特定的权限来保护它(当启用分页时)。 - Sebastian Dressler
1个回答

8
一些关于这种设计的优点/理由:
  • 应用程序不需要关心内核的大小和位置,可以假装他们是在内存中唯一的进程,从0开始向上跨度延伸,最大限度地减少或没有代码和数据重定位。这样设计应用程序更容易实现,而且可能会减少与内存管理相关的错误。
  • 应用程序可以使用更小/短的地址/指针,从而节省一些内存。
  • 在x86 CPU中,16位和32位地址空间从虚拟地址0开始,并在1MB左右结束(对于真实和虚拟8086模式)、16 MB(i80286+ 16位保护模式)和4 GB(32位模式,非真实模式)。将内核放在较低的地址会减少应用程序可用的地址范围(例如:32位模式下的16位应用程序或64位模式下的32位应用程序),并且/或者使其内存管理变得复杂。将内核移至虚拟地址空间的顶部通常在x86上是合理的。

可能还有其他原因,通常是特定于平台的。在某些平台上,两个选项之间可能没有或很少差异。但在其他情况下,首选内核位置可能在较低的虚拟地址处。细节很重要。


1
好的,现在我有点明白了。但是我的理解是这样的:内核实现了虚拟内存管理,从而为所有用户应用程序提供了在地址0x0处重定位的能力。如果是这样,那么内核在内存中的位置就不重要了,当内核是控制内存的唯一实例时。有道理吗? - Sebastian Dressler
1
不要忘记,在内核进行任何重定位之前,编译器必须生成可重定位二进制文件。如果每个应用程序都可以从 ~0 开始运行,则二进制文件中的代码可以更简单,二进制文件可能不包含任何重定位信息,编译器可以更简单或者做更少的工作。 - Alexey Frunze
1
看整个系统,内核和应用程序。通常将内核这一部分变得更加复杂以简化应用程序及其开发是有益的,也就是说,简化许多其他事情。这是有道理的,因为应用程序开发人员不应该像内核开发人员那样技术性强。正如我所说,细节很重要,包括谁做什么。 - Alexey Frunze
1
好的,根据你的评论,我找到了以下程序在内存中的解剖这篇文章,实际上是一篇很棒的文章。而引起我的注意的那句话是:“一旦启用虚拟地址,它们将应用于机器中运行的所有软件,包括内核本身。因此,必须保留一部分虚拟地址空间给内核。”我之前不知道这一点,它澄清了所有事情,所以感谢你提供的“整个系统”提示。但现在我在想是否有更好的处理虚拟内存的方法,但这不属于这里的讨论范围。 - Sebastian Dressler
1
@macs 有点偏题了,但我忍不住要分享这个好资源:mit 6.828。如果你完成实验,你将深入理解很多东西。 - ren
显示剩余6条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接