哪些数据结构使用128MB的1GB Linux内核空间?
在几乎所有关于Linux内核中的HIGHMEM的书籍和文章中,他们都说在使用3:1分割时,并不是所有的1GB都可用于内核映射。 通常它的大小为896MB左右,其余部分用于内核数据结构,内存映射,页表等。
我的问题是,这些数据结构究竟是什么? 页表通常通过页表地址寄存器访问,对吧? 并且页表的基地址通常被存储为物理地址。 现在为什么需要为整个表预留虚拟地址空间?
同样,我读了关于占用空间的内核代码本身。 这与虚拟地址空间有什么关系? 这不是用于存储代码的物理内存吗?
最后,这些数据结构为什么要保留128MB空间? 为什么不能按照需要在整个1GB地址空间中使用它们,就像内核中的任何其他正常数据结构一样?
我已经通过了LDD3,专业Linux内核架构和几处贴子溢出(如:为什么Linux内核ZONE_NORMAL被限制为896 MB?)和一个较旧的LWN文章,但没有找到相同的具体信息。
关于页表,毫无疑问,MMU不会在意页表本身是否未映射到虚拟地址空间中 - 为了地址转换的目的,这可以。 但是,当内核需要修改页表时,它们确实需要映射到虚拟地址空间中 - 而内核不能仅仅在“及时”映射它们,因为它需要修改页表本身来做那。 这是一个鸡与鸡蛋的问题,这意味着页表需要始终保持映射。
内核代码存在类似的问题。 对于要执行的代码,它必须映射到虚拟地址空间中 - 如果执行页表修改的代码本身不存在,那么我们会遇到类似的鸡与蛋问题。 考虑到这一点,将内核代码的全部内容随时映射,以及内核模式堆栈和任何内核数据结构通过代码进行访问会更容易,因为您不希望发生页面错误。 这种数据结构的一个大例子是struct page
结构数组,代表每个物理内存页面。
128MB储备不适用于特定的数据结构,它总是使用它。
它是虚拟内存,为各种用户保留,可能会使用它。 通常情况下,并未全部使用。
关于物理和虚拟内存:每个分配需要三件事 - 一个物理页面,一个虚拟页面以及连接两者的映射。 Linux几乎不会直接使用物理地址,它总是通过虚拟地址转换。
对于大多数内核内存分配(称为lowmem),这种转换非常简单 - 从虚拟地址减去一些常量以获得物理内存。 但是,仍然使用虚拟地址。
Linux的内存管理是在虚拟内存空间(4GB)比物理内存大得多的时候编写的,即使在最大的机器上也是如此。 在这种情况下,浪费虚拟地址不是问题。 今天,当物理内存很大时,这会导致效率低下和问题。
vmalloc
虚拟地址范围由vmalloc
的任何调用者使用。 例如:
1.加载内核驱动程序(使用modprobe
或insmod
)。
2.内核模块通常使用vmalloc
分配。 替代函数kmalloc
过去被限制为128K,并且它的大小增加到2的幂,所以vmalloc
通常是大分配的首选。
上一篇: What data structures use 128MB of 1GB Linux kernel space?