如果一个系统中有两个处理器,如果第二个处理器具有不同的体系结构,是否可以对其进行控制?

时间:2016-11-02 15:10:05

标签: x86 arm 64-bit cpu-architecture arm64

假设我的计算机有2个处理器,一个使用x64,另一个使用ARM。 x64 Linux内核是否能够控制第二个(ARM)处理器?

1 个答案:

答案 0 :(得分:0)

我认为(有大量的软件工程繁忙,但我没有看到任何难以逾越的障碍)你可以在一个假设的缓存一致的机器上运行一个ARM + x86 Linux内核,混合使用ARM + x86内核,例如。

这些不存在;同一系统中不同体系结构的多个CPU总是在做不同的工作,并连接到不同的RAM,并通过某些总线进行通信,如SATA或PCIe。 我回答了问题的这个方面,因为它是唯一一个有趣/不重要的人。

整个系统共享一个共享内存池,因此内存基本上可以在ARM和x86进程之间进行竞争性共享,而不必对其进行静态分区。 pagecache(也称为磁盘缓存)也将与其他缓存(如VFS目录条目/ inode)共享。

内核中的大多数CPU内部交互只是通过写入内存并等待另一个内核上的内核代码来注意它。 (例如,如果进程启动一个新线程并继续运行,则内核只是将新任务放入任务列表中,运行调度程序的另一个核心会注意到它。启动一个新线程不会导致当前核心寻找线程运行的核心,而核心查看任务列表并选择接下来要做的事情。)

因此,只要缓存一致的共享内存正常运行,并且x86和ARM进程可以通过内存屏障等同步,我就不明白为什么它不可能在理论

驱动程序必须在SMP系统上工作,因此只要锁定正常工作以排除其他线程(无论它们是ARM还是x86),事情都应该有效。

您需要:

  • 内核中的函数指针。每个内核函数指针都需要有一个x86和一个ARM版本。 Linux大量使用函数指针来分派给正确的驱动程序,例如:一个文件系统。废话,我在写完大部分其余答案之后就想到了这个,它可能是一个表现。我可以想象使用C ++编译器来编译内核,因此您可以使用具有两个指针空间的模板包装器替换每个结构中的函数指针,并且取消引用为该体系结构选择正确的指针。但是使用函数的地址将函数指针存储到结构中意味着ARM代码需要知道要分配的x86指针是什么,反之亦然。

    或者可能如果你疯了,你可以设置内存映射和二进制布局,所以x86内核在与ARM内核相同的虚拟地址上看到x86版本的函数请参阅该函数的ARM版本。你只需要这个函数来获取它们的地址,但它听起来很疯狂,并且因为不同的体系结构将具有不同的机器代码大小,因此需要花费很多时间才能让链接器为此留下足够的填充量。相同的功能。

    由于灵活性较低的内核没有将如此多的函数指针放入不同文件系统的ops结构中,这将更容易。

    也许你可以拥有每个ops结构的ARM和x86版本,并且编写者必须设置两者,但读者只能阅读他们想要的那个。我认为它们并不经常设置,主要是在安装新的FS或插入新设备时。

  • 所有结构布局必须兼容(可能需要大量工作才能实现,或者只是通过调整ABI获得一些编译器帮助)。

  • 调度程序需要知道它应该只在ARM内核上运行ARM进程,在x86内核上运行x86进程。

  • 系统需要能够以某种方式启动,并从加载到内存中的相同源构建两个内核映像。这将是一项重大挑战,因为可能存在关于内核所在的物理/虚拟地址的假设。启动过程必须加载内核代码的两个副本,但只有一个只读数据副本和静态非 - 恒定数据。 (并且这两段代码必须具有所有这些东西的正确地址。)

  • 内存管理:ARM和x86使用不同的页表格式。读取ARM进程的/proc/<pid>/maps的x86进程可能会导致内核查看其他体系结构进程的页表。 (或者Linux可能会将这些信息保存为映射开始/长度格式以及实际页面表格。)不过,我仍然可以想象这是一个问题。

    管理系统范围的内存池的内核也可能很棘手,如果有关于内核代码所在位置的假设,那么加载了两个不同版本就会违反内核。

  • 线程:如果要将系统中的所有x86 + ARM内核用于共享内存任务,则必须使用映射某些共享内存的两个进程来执行此操作。另一种方法是编写一个新的系统调用,让x86进程启动一个ARM线程,就像内核工作方式一样,但是这个可能需要做很多工作。这绝对是单独的页面表格式问题所在的地方,因为进程中的所有线程通常共享相同的页表。

  • 内存屏障宏等必须以与在其他架构的内核上运行的代码同步的方式实现。据推测,x86内核仍然会服从x86内存模型,其中商店在程序顺序等方面全局可见(请参阅标签wiki以获取有关x86内存模型的更多信息的链接)。

    类似地,ARM内核将遵循通常的ARM内存模型,因此如果它们不使用障碍或获取负载,它们的负载可能会无序地全局可见,无论产生数据的核心是否是ARM或x86。

    内存排序完全取决于核心在其专用L1缓存上的操作顺序(与系统中的所有其他数据缓存一致)。存储缓冲区允许不可见的重新排序,但是一旦将某些内容写入L1缓存,无论谁阅读它,它都是全局可见的。这就是缓存一致的意义。

    所以问题是任何同步习语是否依赖于关于另一个线程的假设,如果它使用不同的内存模型则可能不正确。,例如ARM内核锁定需要从关键部分排除x86线程,反之亦然。我认为这应该主要起作用,但这是我到目前为止所认为的那个我不确定的领域。它可能需要调整一些Linux inline-asm宏。 Linux提取了大量内容,供内核中与arch无关的部分使用,因此,如果需要,它可以很好地设置smp_wmb()(写内存屏障)。