ARM Linux内核页表

参考。 Linux内核ARM翻译表格库(TTB0和TTB1)

我有以前的链接中讨论过的话题的父亲怀疑/查询:

  1. 0到0xbfffffff是内存的下半部分(用于用户进程),由TTB0中的页表pipe理,它包含当前进程的页表

    参考。 arm / include / asm / pgtable-2level.h:PTRS_PER_PGD = 2048,PTRS_PER_PMD = 1,PTRS_PER_PTE = 512

  2. 0xc0000000到0xffffffff是由TTBR1中的页表pipe理/转换的地址空间的上部(OS和存储器映射I / O)。 TTB1表固定在大小和alignment(到16K)。 大小的每个1级条目都是32位,代表1MB的页面/段。 这是放在实际文本地址下面16K的swapper_pg_dir (ref System.map )页表
  1. 那是swapper_pg_dir = 0 (用户进程的0x0到0xbfffffff)中的第一个768条目,并且从768到1024(0xc0000000到0xffffffff是针对OS和内存映射的I / O)的有效条目?

  2. 任何人都喜欢在内核空间(内核模块)共享一些示例代码来浏览这个swapper_pg_dir PGD​​?

Solutions Collecting From Web of "ARM Linux内核页表"

由于ARM MMU的设计方式,翻译表(TTB0和TTB1)只能用于1:1映射内核映射。

大多数Linux内核具有3:1映射(3GB用户空间:1GB用于ARM的内核空间)。 这意味着0-0xBFFFFFFF是用户空间,而0xC0000000 – 0xFFFFFFFF是内核空间。

现在对于硬件存储器转换,仅使用TTBR0。 TTBR1仅保存初始交换页面(包含所有内核映射)的地址,并不真正用于虚拟地址转换。 TTBR0保存当前使用的页面目录(硬件用于翻译的页面表)的地址。 现在每个用户进程都有自己的页表,对于每个进程切换,TTBR0切换到当前的用户进程页表(它们都位于内核空间中)。

例如,对于每个新的用户进程,内核创建一个新的页面目录,将所有内核映射从交换页面(3-4GB的页面框架)复制到新的页面表,并清除用户页面(从0- 3GB)。 然后将TTB0设置为该页面目录的基地址,并刷新缓存以安装新的地址空间。 交换页面也随时更新映射。

对于你的问题:

  1. 简化,硬件方面,第一级页面有4096个条目。 每个条目代表1MB的虚拟地址,总计4GB的内存。 条目0-3071代表用户空间,条目3072-4095代表内核空间。

  2. 交换页面通常位于地址0xC0004000-0xc0008000(4096个条目* 4bytes每个条目= 16384 = 16kb在十六进制= 0x4000)。 通过检查内存在0xc0004000-0xc0007000你可以找到用户空间的条目(空),从0xc0007000-0xc0008000你可以找到内核条目。 我使用gdb与命令行x /100x 0xc0007000来检查前100个内核条目。 然后,您可以检查当前平台的技术参考手册,以解密页表属性。

如果您想了解更多关于Linux内核的知识,我建议您使用Qemu和gdb一起模拟Beagleboard来检查和调试源代码。 我这样做是为了了解内核在初始化过程中如何构建页表。