首先配置内核,使其支持导出内核页表到debugfs下面: Kernel hacking ---> ---> [*] Export kernel pagetable layout to userspace via debugfs 配置完后,重新编译内核,并用新内核启动,就会在/sys/kernel/debug下看到kernel_page_tables文件:
然后cat该文件,可以获得如下信息:
[root@vexpress debug]# cat kernel_page_tables
---[ Modules ]---
0xbfe01000-0xbfe1e000 116K RW NX SHD MEM/CACHED/WBWA
---[ Kernel Mapping ]---
0xc0000000-0xc0100000 1M RW NX SHD
0xc0100000-0xc0700000 6M ro x SHD
0xc0700000-0xc0900000 2M ro NX SHD
0xc0900000-0xf0000000 759M RW NX SHD
---[ vmalloc() Area ]---
0xf0800000-0xf0801000 4K RW NX SHD DEV/SHARED
0xf0802000-0xf0803000 4K RW NX SHD DEV/SHARED
0xf0804000-0xf0805000 4K RW NX SHD DEV/SHARED
0xf0806000-0xf0807000 4K RW NX SHD DEV/SHARED
0xf0808000-0xf0809000 4K RW NX SHD DEV/SHARED
0xf080a000-0xf080b000 4K RW NX SHD DEV/SHARED
0xf080c000-0xf080d000 4K RW NX SHD DEV/SHARED
0xf0814000-0xf0815000 4K RW NX SHD DEV/SHARED
0xf0816000-0xf0817000 4K RW NX SHD DEV/SHARED
0xf0818000-0xf0819000 4K RW NX SHD DEV/SHARED
0xf081a000-0xf081b000 4K RW NX SHD DEV/SHARED
0xf081c000-0xf085c000 256K RW NX SHD MEM/BUFFERABLE/WC
0xf085d000-0xf085e000 4K RW NX SHD DEV/SHARED
0xf085f000-0xf0860000 4K RW NX SHD DEV/SHARED
0xf0861000-0xf0862000 4K RW NX SHD DEV/SHARED
0xf0875000-0xf0876000 4K RW NX SHD DEV/SHARED
0xf0879000-0xf087a000 4K RW NX SHD DEV/SHARED
0xf087d000-0xf087e000 4K RW NX SHD DEV/SHARED
0xf0889000-0xf088a000 4K RW NX SHD DEV/SHARED
0xf088b000-0xf088c000 4K RW NX SHD DEV/SHARED
0xf088d000-0xf0898000 44K RW NX SHD MEM/CACHED/WBWA
0xf0899000-0xf08db000 264K RW NX SHD MEM/CACHED/WBWA
0xf08dc000-0xf08e7000 44K RW NX SHD MEM/CACHED/WBWA
0xf08e8000-0xf0908000 128K RW NX SHD MEM/CACHED/WBWA
0xf0909000-0xf0929000 128K RW NX SHD MEM/CACHED/WBWA
0xf092a000-0xf094a000 128K RW NX SHD MEM/CACHED/WBWA
0xf094b000-0xf096b000 128K RW NX SHD MEM/CACHED/WBWA
0xf096c000-0xf098c000 128K RW NX SHD MEM/CACHED/WBWA
0xf098d000-0xf09ad000 128K RW NX SHD MEM/CACHED/WBWA
0xf09ae000-0xf09ce000 128K RW NX SHD MEM/CACHED/WBWA
0xf09cf000-0xf09ef000 128K RW NX SHD MEM/CACHED/WBWA
0xf09f0000-0xf09f1000 4K RW NX SHD DEV/SHARED
0xf09f2000-0xf09f3000 4K RW NX SHD DEV/SHARED
0xf09f4000-0xf09f5000 4K RW NX SHD DEV/SHARED
0xf09f6000-0xf0b76000 1536K RW NX SHD MEM/BUFFERABLE/WC
0xf0b77000-0xf0b78000 4K RW NX SHD DEV/SHARED
0xf0b79000-0xf0b7a000 4K RW NX SHD DEV/SHARED
0xf0b80000-0xf1380000 8M RW NX SHD DEV/SHARED
0xf1385000-0xf1386000 4K RW NX SHD DEV/SHARED
0xf1387000-0xf1388000 4K RW NX SHD DEV/SHARED
0xf1389000-0xf138a000 4K RW NX SHD DEV/SHARED
0xf138b000-0xf138c000 4K RW NX SHD DEV/SHARED
0xf138d000-0xf138e000 4K RW NX SHD DEV/SHARED
0xf1390000-0xf13a0000 64K RW NX SHD DEV/SHARED
0xf13aa000-0xf13b5000 44K RW NX SHD MEM/CACHED/WBWA
0xf13b6000-0xf13b9000 12K RW NX SHD MEM/CACHED/WBWA
0xf1400000-0xf5400000 64M RW NX SHD DEV/SHARED
0xf5401000-0xf5425000 144K RW NX SHD MEM/CACHED/WBWA
0xf5480000-0xf7480000 32M RW NX SHD DEV/SHARED
0xf8009000-0xf800a000 4K RW NX SHD DEV/SHARED
0xf8080000-0xfc080000 64M RW NX SHD DEV/SHARED
---[ vmalloc() End ]---
---[ Fixmap Area ]---
0xffecd000-0xffecf000 8K RW NX SHD MEM/CACHED/WBWA
0xffedd000-0xffedf000 8K RW NX SHD MEM/CACHED/WBWA
0xffeed000-0xffeef000 8K RW NX SHD MEM/CACHED/WBWA
0xffefd000-0xffeff000 8K RW NX SHD MEM/CACHED/WBWA
---[ Vectors ]---
0xffff0000-0xffff1000 4K USR ro x SHD MEM/CACHED/WBWA
0xffff1000-0xffff2000 4K ro x SHD MEM/CACHED/WBWA
---[ Vectors End ]---
上面每一行的含义:被映射的虚拟地址的范围、大小以及该段内存所具备的属性
[Modules start] - [Modules end]模块加载使用到的内核空间,现在只加载了pid_page_tables.ko故只显示了三行映射数据。
[vmalloc() Area] - [vmalloc() End]所有vmalloc申请的,内核本身代码,mmap,ioremap等申请的地址空间在这一个区域。
[Fixmap start] - [Fixmap end]arm64内核启动后为了能够读取设备树所做的一段Fixmap,用于前期映射使用其中包括了设备树映射,early ioremap,fix pgd,fix pud,fix pmd等的映射。
[PCI I/O start] - [PCI I/O end]同上,专门用于PCI设备使用的地址空间,一般映射大小为16M
[vmemmap start] - [vmemmap end]对与ARM64用于page映射区,linux内核用page结构体管理所有物理内存,每一页大小为PAGE_SIZE对于arm64,可能是4K,16K,64K。而为了快速方便找到对应物理页而将所有的页帧结构体映射到此区域,后续只需使用virt_to_page, phys_to_page等宏实现虚拟地址,物理地址到对应页结构体的快速查询。
[Linear Mapping]此区域为线性映射区,所有的物理内存通过mem_map全部映射到此区域,用于伙伴系统分配,并且可使用virt_to_phys, phys_to_virt进行地址转换。
第一列 | 当前页表的映射范围地址 |
---|---|
第二列 | 代表此映射范围大小 |
PMD PUD PTE | 当标识为PMD PUD表示当前映射为block映射,如当前页表为4K,则pud的block映射一次性可映射1G范围,pmd的block映射可一次性映射2M范围。当标识为PTE表示为页表映射即PAGE_SIZE大小4K。 |
USR | AP标记,用于标识当前范围是否在用户空间还是内核空间可读可写或者仅读。 |
ro RW | 当前地址范围读写权限,ro仅读,RW可读可写 |
NX x | NX表述当前范围特权级别模式不可执行,就是内核不能执行这段地址代码。x表述当前范围特权级别模式可执行,就是内核的可执行代码段,在内核中这段一般指向内核的text*段 |
SHD | 表示可共享属性,在arm64上表述为多核之间可共享其页表可见 |
AF | 访问标志,当首次映射页表时,如果不置位,则第一次访问将会产生异常,可用于标记新页的首次访问,对于内核而言首次映射会将此bit置位。 |
NG | 此标志可用于全局一致性。表示非全局。 |
CON | 对于cpu进行地址翻译过程,为了能够避免多次的查找翻译过程,CON bit可用于标识当前映射为一个连续区域,则cpu可进行连续预取加速翻译过程。 |
BLK | 对于PUD和PMD block映射的都会被标记为BLK |
UXN MEM | 标识非特权模式是否可执行,UXN表示当前范围用户空间不可执行,MEM表示当前范围用户空间可执行。 |
NORMAL/NORMAL-NC DEVICE/DEVICE/nGnRE等 | arm64中一共标识了六种内存属性,下面说明使用到的: 对于系统RAM区,一般标识为NORMAL即普通内存可缓存,NORMAL-NC则不会经过cache cpu直接进行内存读写。 DEVICE/DEVICE/nGnRE等用于标识设备地址空间,此段空间除了不会经过cache外,cpu还会进行透传回写排序等操作限制,具体读写方式与G R E标识相关,感兴趣可参考ARMv8手册 |