2

参考。Linux 内核 ARM 转换表库(TTB0 和 TTB1)

我对上一个链接中讨论的主题有疑问/疑问:

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

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

  2. 0xc0000000 到 0xffffffff 是由 TTBR1 中的页表管理/转换的地址空间的上部(操作系统和内存映射 I/O)。TTB1 表的大小和对齐方式是固定的(到 16k)。每个 1 级条目的大小为 32 位,代表 1MB 页面/段。这是swapper_pg_dir(参考System.map)在实际文本地址下方放置 16K 的页表
  1. swapper_pg_dir = 0 这是(0x0 到 0xbfffffff 用于用户进程)中的第一个 768 条目和从 768 到 1024(0xc0000000 到 0xffffffff 用于操作系统和内存映射 I/O)的有效条目吗?

  2. 有人喜欢在内核空间(内核模块)中分享一些示例代码来浏览这个swapper_pg_dirPGD 吗?

4

1 回答 1

7

由于 ARM MMU 的设计方式,两个转换表(TTB0 和 TTB1)都只能用于 1:1 映射内核映射。

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

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

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

对于您的问题:

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

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

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

于 2013-08-30T12:36:06.183 回答