作者:新浪微博(@NP等不等于P)
计算机学习微信公众号(jsj_xx) 内存管理是操作系统核心功能,尽管有点老(过时),我们还是以经典的32位x86为例(之后会分析x86_64),看看linux内核的内存管理。参考linux kernel source code 4.0,为之后分析x86_64版本的内存管理做热身(如有错误,还望指正,谢谢)! 1 内存区划分 有三种类型内存区(假设物理内存大于896M):
其中,ZONE_DMA和ZONE_NORMAL称为低端内存,ZONE_HIGHMEM称为高端内存(后面会详述高端内存)。 2 内存的申请使用 有三种申请函数:
在申请时,有三种标志(属性):
我们关注一下kmalloc():
3 高端内存 32bit x86的内存管理中,很重要的就是高端内存的概念,我们详细讨论一下。 3.1 高端内存基础
内核一般不用高端内存,除非装载模块时可能会用到vmalloc()。
注意,这里只是高端映射,有可能映射到低端内存。 直白地理解,就是:内核用1G空间管理4G空间,自然不够,所以从中留128M做动态反复使用。 3.2 结合源码理解高端内存 下面,我们结合源码(linux kernel souce code 4.0)看看。 以下参考find_low_pfn_range(): 先说大于896M的场景,此时896M和实际物理内存之间的就属于高端内存。不管是否打开CONFIG_HIGHMEM,都会设置低端内存为896M:(MAXMEM_PFN即896M)
但是,如果不打开CONFIG_HIGHMEM,就会无视高端内存:
这样,如果内存高于896M,但是不打开CONFIG_HIGHMEM,就只能使用896M以内的内存了,真是浪费! 需要注意的是,高端内存区间不能容纳超过此范围的内存空间,否则忽略并报错: 再看物理内存小于896M的场景,此时真的没有高端内存的概念了么?首先,不管是否打开CONFIG_HIGHMEM,都会设置低端内存为实际物理内存大小(小于896M的一个值):
如果没打开CONFIG_HIGHMEM,确实没有高端内存的事了。但是,如果打开CONFIG_HIGHMEM,则在低端内存(max_low_pfn)留出部分空间(假定依然128M),此空间就还是高端内存的概念: 总结就是:
注意,此处的高端内存是从物理内存角度说的,要与内核虚拟空间的角度(1G空间的128M)分开理解。 可见,VMALLOC_START其实就是高端内存地址加上8M的间隔。我的理解:VMALLOC区不是固定从896M开始,而是从高端内存开始的,VMALLOC_END是固定的,这样,VMALLOC区间完全可能大于128M(考虑实际物理内存小于896M且打开CONFIG_HIGHMEM的场景下,最大可达1G-64M=960M)!想想,其实很好理解,VMALLOC区间诞生的背景是物理内存远大于内核空间,而如果内核空间远大于物理内存呢? 4 总结 就x86 32bit版来说,主要是要搞清高端内存的含义,需要从物理内存角度和内核虚拟空间角度两个角度去结合理解。其存在的意义,就是为了将更大的内存映射进内核空间!下次分析64bit版本(相当于,64T取代896M),因为32bit版本已经老去。。。
|
|