您的位置 首页 应用

Arm Linux 内核页表的段式映射

Linux启动之初,内核为自己建立的是段式内存映射,而不是页式映射。映射表(PGD)从虚拟地址0xc0004000开始,每项4字节,每项对应1M内存空间…

Linux发动之初,内核为自己树立的是段式内存映射,而不是页式映射。

映射表(PGD)从虚拟地址0xc0004000开端,每项4字节,每项对应1M内存空间,每项的高12位便是这1M内存的高12位地址。
一开端,内核不会为一切内存树立映射,只会映射必要的一部分,这部分代码在arch/arm/kernel/head.S中由汇编代码完结。
以S3C6410为例,下面是在刚刚进入start_kernel()后打印出来的一段内核映射表。留意内核本身的映射表项是从0xc0007000地址开端。由于从0xc0004000开端的是整个4G空间的表,内核内存只占最高的那1G,所以要加一个偏移量:3G/1M * 4bytes = 0x3000。
c0007000:0e 0c 00 50 0e 0c 10 50 0e 0c 20 5000 00 00 00
c0007010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0007020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0007030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
由于字节序的原因,上面的每一个表项应该倒置一下次序来看,以第一项为例,应该是:
50000c0e
高12位地址是0x500,由于s3c6410的内存物理地址便是从0x50000000开端。
发动到C函数start_kernel()之后,在arch_setup()中会重写映射表,映射一切内存。这时的页表会如下所示:
c0007000:0e 04 00 500e 04 10 50 0e 04 20 50 0e 04 30 50
c0007010: 0e 04 40 50 0e 04 50 50 0e 04 60 50 0e 04 70 50
c0007020: 0e 04 80 50 0e 04 90 50 0e 04 a0 50 0e 04 b0 50
c0007030: 0e 04 c0 50 0e 04 d0 50 0e 04 e0 50 0e 04 f0 50
……
留意,每一个表项的最终两个bit指明晰映射方法,00表明段式映射。在内存从头映射之后,这一映射方法并没有改变。
再来看一段应该程序的pgd表内容,这段内容是从其pgd表开端方位打印的,所以是为用户程序虚拟进程空间树立的映射:
c0d98000:31 c8 d8 5031 cc d8 50 00 00 00 00 00 00 00 00
c0d98010: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0d98020: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0d98030: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
能够看到,表项最终两位是01,这已经是二级页式映射了。
这说明,虽然内核为应用程序树立的是二级粗粒度页式映射,但Linux内核本身一直是运行在段映射形式下。两种映射在同一张pgd表里边能够一起运用,映射方法不用全表一致。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/277023.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部