参考。 Linux kernel ARM Translation table base (TTB0 and TTB1)
我有父亲怀疑/查询上一个链接中讨论的主题:
- 0到0xbfffffff是内存的下半部分(对于用户进程)并由TTB0中的页表管理,它包含当前进程的页表
参考。 arm / include / asm / pgtable-2level.h:PTRS_PER_PGD = 2048,PTRS_PER_PMD = 1,PTRS_PER_PTE = 512
- 0xc0000000到0xffffffff是由TTBR1中的页表管理/转换的地址空间的上部(OS和存储器映射的I / O)。 TTB1表的大小和对齐是固定的(到16k)。每个1级大小的条目是32位,代表1MB页/段。这是
醇>swapper_pg_dir
(参考System.map
)页面表格,它们放置在实际文本地址以下16K
这是swapper_pg_dir = 0
中的第一个768条目(用户进程的0x0到0xbfffffff)和从768到1024的有效条目(0xc0000000到0xffffffff用于操作系统和内存映射的I / O)?< / p>
有人喜欢在内核空间(内核模块)中共享一些示例代码来浏览这个swapper_pg_dir
PGD吗?
答案 0 :(得分:6)
由于ARM MMU的设计方式,翻译表(TTB0和TTB1)都只能用于1:1映射内核映射。
大多数Linux内核都有3:1的映射(3GB用户空间:ARM的1GB内核空间)。 这意味着0-0xBFFFFFFF是用户空间,而0xC0000000 - 0xFFFFFFFF是内核空间。
现在,对于HW内存转换,仅使用TTBR0。 TTBR1仅保存初始交换器页面的地址(包含所有内核映射),并不真正用于虚拟地址转换。 TTBR0保存当前使用的页面目录的地址(HW用于翻译的页面表)。现在每个用户进程都有自己的页表,并且对于每个进程切换,TTBR0都会更改为当前用户进程页表(它们都位于内核空间中)。
例如,对于每个新用户进程,内核创建一个新的页面目录,将所有内核映射从交换器页面(页面帧从3-4GB)复制到新的页面表并清除用户页面(页面框架)从0-3GB)。然后,它将TTB0设置为此页面目录的基址,并刷新缓存以安装新的地址空间。交换器页面也始终与映射的更改保持同步。
对于你的问题:
简化,硬件方面,第一级页面有4096个条目。每个条目代表1MB的虚拟地址,总计4GB的内存。条目0-3071表示用户空间,条目3072-4095表示内核空间。
交换器页面通常位于地址0xC0004000 - 0xc0008000(4096个条目* 4字节,每个条目= 16384 = 16kb,十六进制= 0x4000)。通过检查0xc0004000-0xc0007000处的内存,您可以找到用户空间的条目(空),从0xc0007000-0xc0008000可以找到内核条目。我使用gdb和命令行x /100x 0xc0007000
来检查前100个内核条目。然后,您可以检查当前平台的技术参考手册,以便破译页表属性。
如果您想了解有关Linux内核的更多信息,我建议您使用Qemu与gdb一起模拟Beagleboard以检查和调试源代码。我这样做是为了了解内核在初始化期间如何构建页表。