ARM32内存空间分配( 二 )


3. ARM32内存分布图
了解完低端内存和高端内存的概念,我们来看看我们实际上内存布局是怎么样的?Linux内核在启动时,会打印出内核内存空间的布局图,下面是ARM IMX6平台打印出来的内存空间布局图
:
:-(4 kB)
:-(3072 kB)
:-( 496 MB)
:-( 512 MB)
pkmap:-(2 MB)
:-( 14 MB)
.text :-(10208 kB)
.init :-(2048 kB)
.data :-( 467 kB)
.bss :-( 460 kB)
10
11
这部分信息是的打印是在()函数中实现的
(":\n"
": 0xlx - 0xlx(%4ld kB)\n"
#ifdef
"DTCM: 0xlx - 0xlx(%4ld kB)\n"
"ITCM: 0xlx - 0xlx(%4ld kB)\n"
#endif
": 0xlx - 0xlx(%4ld kB)\n"
": 0xlx - 0xlx(%4ld MB)\n"
": 0xlx - 0xlx(%4ld MB)\n"
#ifdef
"pkmap: 0xlx - 0xlx(%4ld MB)\n"
#endif
#ifdef
": 0xlx - 0xlx(%4ld MB)\n"
#endif
".text : 0x%p" " - 0x%p" "(%4td kB)\n"
".init : 0x%p" " - 0x%p" "(%4td kB)\n"
".data : 0x%p" " - 0x%p" "(%4td kB)\n"
".bss : 0x%p" " - 0x%p" "(%4td kB)\n",
MLK(UL(), UL() +
()),
#ifdef
MLK(, ( long) ),
MLK(, ( long) ),
#endif
MLK(, ),
MLM(, ),
MLM(, ( long)),
#ifdef
MLM(, () + () *
()),
#endif
#ifdef
MLM(, ),
#endif
(_text, ),
(, ),
(, ),
(, ));
10
11
12
13
14
15
16
17
18

ARM32内存空间分配

文章插图
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
内核image本身占据的内存空间从_text段到 _end段,并且分为如下几段
代码段:_text和 为代码段的起始和结束地址,包含了编译后的内核代码
init 段: 和 为init段的起始和结束地址,包含了大部分模块初始化的数据
数据段:和 数据段的起始和结束地址,保存大部分内核的变量
BSS段:和 为BSS段的开始和结束地址,包含了初始化为0的所有的静态全局变量
那么高端内存的起始地址是如何确定的呢?在内核初始化内存时候,在函数中确定低端内存和高端内存的起始地址
= (u64)() -+ ;
= ;
= __va( - 1) + 1;
计算出来内核线性映射512M地址空间,剩下的保留给,和高端向量表使用,内核很多驱动使用来分配连续虚拟地址内存,因为有的驱动不需要连续物理地址内存;除此之外,还可以用于高端内存的临时映射 。对于内核空间配置如下
#(8*1024*1024)
#((( long) + ) & ~(-1))
#
区域在ARM32内核中,从开始到结束,即从 - ,大小为512MB,在开始之前有一个8MB的空间,用于捕获越界访问 。
4. 总结
对于高端内存,首先我们需要明确这是一个物理内存的概念,它仅仅是内核中的内存管理模块看待物理内存的时候的概念 。在内核中,除了内存管理模块直接操作物理地址之外,其他的模块,都需要操作虚拟地址,而虚拟地址是需要内存管理模块分配和映射的 。例如,我们有一个2G的内存,现在内核模块如果想要访问物理内存1.5G的地方,应该怎么办呢?
首先,我们不能使用物理地址,你需要使用内存管理模块给你分配虚拟地址,但是虚拟地址0 ~ 3G已经被用户态进程占用去了,作为内核不能使用 。
其次,对于1.5G的地方就算映射了,也不是你真正要访问的物理内存地址,所以对于内核,能够使用虚拟内存地址,只剩下高端内存这块了 。
内核通常把物理内存低于的地址成为线性映射地址,而高于以上的成为高端内存 。由于32位系统寻址能力只有4GB,对于物理内存高于而低于4GB的情况,我们就需要从虚拟地址空间中画出一部分来用于动态映射高端内存,这样就可以访问到全部的4GB的内存 。而对于映射高端内存的虚拟地址空间,可以划分位固定映射区和临时映射区,后面章节中单独来讲解每个的功能 。对于我们现在使用的IMX6U的内核空间的内存分布图如下所示,对于途中的高端内存每个平台可能都不一样,主要是通过客户实际需要来配置