hisi3519 内核虚拟内存布局原理图

1. 用户空间与内核空间分段式布局如下截图:
在这里插入图片描述
对于pkmap / modules 与fixmap关系,这地方可能比较难以理解,请参考这三篇文章:

https://www.veryarm.com/119846.html
https://blog.csdn.net/michaelcao1980/article/details/43308811
https://www.cnblogs.com/arnoldlu/p/8068286.html

PKMAP_BASE是永久映射区的起始范围是[PAGE_OFFSET – 2MB,PAGE_OFFSET],对这里的arm设备就是[0xBFE00000,0xC0000000]
highmem pkmap虚拟空间共享模块区域的末端

swapper_pg_dir用于存放内核PGD页表的地方,赋给init_mm.pgd。

swapper_pg_dir被定义了绝对地址,在arch/arm/kernel/head.S中有如下定义。

swapper_pd_dir的大小为16KB,对应的虚拟地址空间是从0xc0004000 - 0xc0008000,物理地址空间是0x6000400~0x60008000

ZONE_DMA的范围是0~16M,该区域的物理页面专门供I/O设备的DMA使用。之所以需要单独管理DMA的物理页面,是因为DMA使用物理地址访问内存,不经过MMU,并且需要连续的缓冲区,所以为了能够提供物理上连续的缓冲区,必须从物理地址空间专门划分一段区域用于DMA。

  1. hisi3519内核布局图如下:
    在这里插入图片描述

这里面的地址都是虚拟地址,其中lowmem是线性映射区。
线性映射区的意思是0xc0000000 -0xef800000这段虚拟地址,和0x60000000 - 0x8f800000这段物理地址是一一对应的。
.text、.init、.data、.bss都属于lowmem区域,也即ZONE_NORMAL;vector、fixmap、vmalloc属于ZONE_HIGHMEM区域。
pkmap、modules属于用户空间(属于3G区间的内存布局范围)
pkmap : 0xbfe00000 - 0xc0000000 ( 2 MB)
modules : 0xbf000000 - 0xbfe00000 ( 14 MB)

永久映射区始于PKMAP_BASE,但并非结束于FIXADDR_START,在文件arch/arm/include/asm/highmem.h中描述> 了永久映射区到底是在哪里:

#define PKMAP_BASE (PAGE_OFFSET - PMD_SIZE)

PKMAP_BASE是永久映射区的起始,在这里的arm设备中,PKMAP_BASE是在内核用户分界点之下2MB处,下面这个宏LAST_PKMAP标识永久映射区有多少个条目,注意每个条目是可以映射1页:

#define LAST_PKMAP PTRS_PER_PTE

在这里的arm设备中,LAST_PKMAP值为512,即512个条目,每个条目映射一页,即可最多映射4KB * 512 =
2MB大小,所以永久映射区的范围是[PAGE_OFFSET –
2MB,PAGE_OFFSET],对这里的arm设备就是[0xBFE00000,0xC0000000];这也证明了前面文章说的,高端内存空间不一定就是在high_memory之上的地址空间;

在这里插入图片描述
其中:boot占用1M, kernel占用4M, rootfs 占用59M

内存信息
在这里插入图片描述
在这里插入图片描述

物理地址空间的顶部以下一段空间,被PCI设备的I/O内存映射占据,它们的大小和布局由PCI规范所决定。640K~1M这段地址空间被BIOS和VGA适配器所占据。

Linux系统在初始化时,会根据实际的物理内存的大小,为每个物理页面创建一个page对象,所有的page对象构成一个mem_map数组。

进一步,针对不同的用途,Linux内核将所有的物理页面划分到3类内存管理区中,如图,分别为ZONE_DMA,ZONE_NORMAL,ZONE_HIGHMEM。

ZONE_DMA的范围是0~16M,该区域的物理页面专门供I/O设备的DMA使用。之所以需要单独管理DMA的物理页面,是因为DMA使用物理地址访问内存,不经过MMU,并且需要连续的缓冲区,所以为了能够提供物理上连续的缓冲区,必须从物理地址空间专门划分一段区域用于DMA。

ZONE_NORMAL的范围是16M~896M,该区域的物理页面是内核能够直接使用的。

ZONE_HIGHMEM的范围是896M~结束,该区域即为高端内存,内核不能直接使用。

在这里插入图片描述

在kernel image下面有16M的内核空间用于DMA操作。位于内核空间高端的128M地址主要由3部分组成,分别为vmalloc
area,持久化内核映射区,临时内核映射区。

由于ZONE_NORMAL和内核线性空间存在直接映射关系,所以内核会将频繁使用的数据如kernel代码、GDT、IDT、PGD、mem_map数组等放在ZONE_NORMAL里。而将用户数据、页表(PT)等不常用数据放在ZONE_
HIGHMEM里,只在要访问这些数据时才建立映射关系(kmap())。比如,当内核要访问I/O设备存储空间时,就使用ioremap()将位于物理地址高端的mmio区内存映射到内核空间的vmalloc
area中,在使用完之后便断开映射关系。

在这里插入图片描述

发布了95 篇原创文章 · 获赞 14 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/ding283595861/article/details/104891448