ARM中TPIDR_EL0/TPIDR_EL1等线程ID寄存器的用途是什么?

ARM中TPIDR_EL0/TPIDR_EL1等线程ID寄存器的用途是什么?,arm,kernel,cpu,armv8,fuchsia,Arm,Kernel,Cpu,Armv8,Fuchsia,根据,线程ID寄存器如TPIDR_EL0或TPIDR_EL1 提供存储软件线程和进程ID的位置 用于操作系统管理目的。这些寄存器对系统没有影响 处理器行为 为什么有人要将线程ID存储在一个特殊的寄存器中?ARM处理器是否像MMU一样要求线程在内存中具有特殊结构?一根线对ARM来说是什么特别的东西,ARM希望在某处找到的东西吗?或者我可以在根本不使用这个寄存器的情况下(高效地)实现线程吗 我这么问是因为我在Fuchsia OS的锆石内核上发现了以下代码: static inline void ar

根据,线程ID寄存器如
TPIDR_EL0
TPIDR_EL1

提供存储软件线程和进程ID的位置 用于操作系统管理目的。这些寄存器对系统没有影响 处理器行为

为什么有人要将线程ID存储在一个特殊的寄存器中?ARM处理器是否像MMU一样要求线程在内存中具有特殊结构?一根线对ARM来说是什么特别的东西,ARM希望在某处找到的东西吗?或者我可以在根本不使用这个寄存器的情况下(高效地)实现线程吗

我这么问是因为我在Fuchsia OS的锆石内核上发现了以下代码:

static inline void arch_set_current_thread(Thread* t) {
  __arm_wsr64("tpidr_el1", (uint64_t)&t->arch_.thread_pointer_location);
  __isb(ARM_MB_SY);
}

在启动时,它创建一个线程并将其指针存储在
tpidr\u el1

用户空间中与线程本地存储相关的所有内容都需要保存在每个线程的结构中。您需要将此结构的地址保留在某个位置。在armv8中,
TPIDR_EL0
可用于此目的。在x86_64中,通常将
fs
段寄存器重新用于此用途

Fuchsia’s在他们的网站上有记录

在fuchsia,
TPIDR_EL0
将为您提供。有关如何分配部分内存的信息,请参阅

一个使用示例(线程局部变量除外)是,它在pthread结构中存储第二个堆栈指针

对于内核,在armv8中,
TPIDR_EL1
用于类似的目的,为内核保存指针


注意,在armv8中,有一个用于
EL0
(用户空间)和
EL1
(内核空间)的寄存器。在x86-64中,没有分离,处理也有点笨拙:内核有一个内部位置来存储gs寄存器的“内核版本”,并使用
swapgs
指令在用户空间和内核空间gs寄存器之间进行更改。

操作系统需要记住当前在给定寄存器中运行的线程/进程(逻辑)CPU。它需要一个CPU寄存器,只能在管理模式下更改,并且可以指定内存区域。在x86上,它是
fs
gs
寄存器,ARM具有
TPIDR\u ELx
。每个CPU内存区域都是必需的,因为内核代码要在任何CPU上平等运行(因此代码相同,但指针不同)@MargaretBloom完全有道理,thanksThread本地数据可以通过EL1进行索引。就像“PIC”一样,您可以使用“静态基址”代码。其中所有全局值都是相对于固定寄存器引用的。线程的实现类似于“静态基址”。但是,进程中的所有线程都可以对全局值使用绝对寻址(在线程之间共享),但它们使用EL1作为“线程本地”变量。切换线程只涉及更改此寄存器(可以在用户空间中完成),但操作系统需要在上下文切换上记录活动线程。涉及虚拟机监控程序时,必须捕获它。