Linux 内核 ARM 转换表库(TTB0 和 TTB1) [英] Linux kernel ARM Translation table base (TTB0 and TTB1)

查看:42
本文介绍了Linux 内核 ARM 转换表库(TTB0 和 TTB1)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

为 ARMv7 (Cortex-a8) 编译 Linux 内核 2.6.34.3

Compiled Linux kernel 2.6.34.3 for ARMv7 (Cortex-a8)

我查看了内核代码,看起来 Linux 内核为 TTB1(转换表基础)上的内核地址空间(0xC0000000 以上的所有内容)和 ttb0 上的用户进程(0xC0000000 以下的所有内容)设置了硬件页表,其中每个进程上下文切换都会发生变化.这样对吗?我仍然很困惑 MMU 如何知道要查看哪个 ttb 进行翻译?

I looked into the kernel code and it looks like the Linux kernel sets the hardware page tables for the kernel address space (everything over 0xC0000000)on TTB1 (translation table base) and the user process on ttb0 (everything under 0xC0000000) which changes for every process context switch. Is this correct? I'm still confused how the MMU knows which ttb to look at for translations?

我读到 TTBCR(转换表基控制寄存器)决定了在未找到 MVA 时要走的 ttb 寄存器,但是该寄存器始终读取 0,这意味着在 ARM 体系结构参考手册中始终使用 TTBR0.这怎么可能?谁能给我解释一下 Linux 内核是如何使用这两个 ttb 的?

I read that the TTBCR (translation table base control register) determines which of the ttb register to walk when an MVA is not found, however the register always reads 0 which means always use TTBR0 in the ARM architecture reference manual. How is that possible? Can anyone explain to me how the Linux kernel uses these two ttbs?

我从本网站阅读了 ttb 的工作原理 https://www.cs.rutgers.edu/~pxk/416/notes/10-paging.html 但我还是不明白内核是如何使用这两个 ttbs 的

I read how the ttb works from this site https://www.cs.rutgers.edu/~pxk/416/notes/10-paging.html but I still dont understand how the kernel use the two ttbs

(仔细检查了内核代码,由于某种原因,ttb0 和 ttb1 都被设置了,但似乎从未使用过 ttb1,我将 TTB1 寄存器设置为 0,Linux 内核继续照常运行)

(Double checked the kernel code, for some reason both ttb0 and ttb1 is set, but it seems like ttb1 is never used, i set the TTB1 register to 0 and the Linux kernel continue to run as usual)

推荐答案

TTBR 寄存器一起用于确定完整 32 位或 40 位地址空间的寻址.通过 TTBCR 中的 tXsz 位控制哪个寄存器用于哪些地址范围.t0sz对应TTBR0,t1sz对应TTBR1.

The TTBR registers are used together to determine addressing for the full 32-bit or 40-bit address space. Which register is used for what address ranges is controlled via the tXsz bits in the TTBCR. There is an entry for t0sz corresponding to TTBR0 and t1sz for TTBR1.

每个 TTBRx 寄存器寻址的页表是独立的,但您通常会发现大多数 Linux 实现只使用 TTBR0.Linux 希望能够使用 ARM 不支持的 3G/1G 地址空间分区方案.如果您查看 ARMv7 架构参考手册的第 B3-1345 页,您会看到 t0sz 和 t1sz 的值分别决定了 TTBR0 和 TTBR1 支持的地址范围.为了增加迷失方向的混乱,甚至可能有不连续的地址空间,其中 TTBR0 和 TTBR1 支持不连续的范围,从而导致系统地址空间中出现空洞.好时光!

The page tables addressed by each TTBRx register are independent, but you typically find most Linux implementations just use TTBR0. Linux expects to be able to use a 3G/1G address space partitioning scheme, which is not supported by ARM. If you look at page B3-1345 of the ARMv7 Architecture Reference Manual, you'll see that the value of t0sz and t1sz determine the address ranges supported by TTBR0 and TTBR1 respectively. To add confusion to disorientation, it is even possible to have disjoined address spaces where TTBR0 and TTBR1 support ranges that are not contiguous, resulting in a hole in the system address space. Good times!

不过,要回答您的主要问题,ARM 建议使用 TTBR0 将偏移量存储到 USER 进程使用的页表,而 TTBR1 用于存储到 KERNEL 使用的页表的偏移量.我还没有看到真正做到这一点的单一实现.在所有情况下几乎只使用 TTBR0,TTBR1 包含 L1 表的副本.

To answer your main question though, it is recommended by ARM that TTBR0 be used to store the offset to the page tables used by USER processes, and TTBR1 be used to store the offset to the page tables used by the KERNEL. I have yet to see a single implementation that actually does this. Almost exclusively TTBR0 is used in all cases, with TTBR1 containing a duplicate copy of the L1 tables.

那么这是如何工作的呢?TTBR 的值作为进程状态的一部分存储,并且在每次进程退出时简单地恢复.这就是它的工作方式.最初,TTBR1 将为内核表保存一个常量值并且永远不会被替换或换出,而 TTBR0 将在每次进程之间进行上下文切换时更改.显然,ARM 的大多数 Linux 实现都决定基本上消除使用 TTBR1,并坚持使用 TTBR0.

So how does this work? The value of TTBR is stored as part of the process state and simply restored each time a process with switched out. This is how it is expected to work. Originally, TTBR1 would hold a constant value for the kernel tables and never be replaced or swapped out, whereas TTBR0 would be changed each time you context switch between processes. Apparently most Linux implementations for ARM have decided to just basically eliminate the use of TTBR1 and stick to using TTBR0 for everything.

如果您想在您的设备上测试此理论,请尝试敲击 TTBR1 并观察无任何反应.然后尝试重击 TTBR0 并观察您的系统崩溃.我还没有遇到过没有导致完全相同结果的单个实例.长话短说,TTBR1 对 Linux 没有用处,而 TTBR0 几乎是专门使用的,只是简单地换掉了.

If you want to test this theory on your device, try whacking TTBR1 and watch nothing happen. Then try whacking TTBR0 and watch your system crash. I've yet to encounter a single instance that didn't result in this exact same result. Long story short, TTBR1 is useless by Linux, and TTBR0 is used almost exclusively and simply swapped out.

现在,一旦您获得 LPAE 支持,就抛开所有这些,重新开始.在这个实现中,您将开始看到 t0sz 和 t1sz 的值不是零,因此也是 N.

Now, once you get to LPAE support, throw all this away and start over again. This is the implementation where you will start to see the value of t0sz and t1sz being something other than zero, and hence N as well.

这篇关于Linux 内核 ARM 转换表库(TTB0 和 TTB1)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆