您现在的位置: 主页 > 嵌入式操作系统 > armlinux > ARM64与ARM32 的Linux程序区别在哪里
本文所属标签:
为本文创立个标签吧:

ARM64与ARM32 的Linux程序区别在哪里

来源: 网络用户发布,如有版权联系网管删除 2020-04-16 

ARM64与ARM32 的Linux程序区别在哪里 当ARM为其架构引入64位支持时,它旨在与以前的32位软件兼容。但对于Linux程序员来说,仍然存在一些可能影响代码行为的重大差异。以下是我们发现的一些内容以及我们为他们开发的解决方法。

我本来打算将这篇文章称为“ARMv8 for Linux程序员的新功能?”然而,我认为“有什么不同”更为贴切。而且,仅仅为了记录,“ARMv8-A”是指AArch64,带有A64指令集,也称为arm64或ARM64。我在示例中使用了AArch64寄存器,但我所描述的许多问题也发生在ARMv8-A 32位执行状态。

为了帮助构建此处讨论的问题,让我开始通过给出一些我们在撤销时所拥有的代码库的背景知识。我们的核心技术是记录和重放引擎,它通过将所有非确定性输入记录到程序并使用即时编译(JIT)来跟踪程序状态来工作。我们的技术始于x86(32和64)当我们开始调整它以适应AArch64时,我已经在ARM 32位上获得了相当完整,成熟的支持。几乎所有的低悬的水果都被抓住了之后我加入了公司(以及很多相当高的树,为了公平)我们在转向ARMv8时遇到了一些棘手的问题。

这让我想到了我的第一个简单但可能有用的观察结果:ARM64与ARM 32位(又名AArch32)相比,与x86更相似。 ARM64仍然非常RISC(尽管加密加速指令确实导致RISC架构中的眉毛抬起)。所以我不打算试图涵盖x86和ARM版本之间的许多差异。我也不想重新审视AArch32和AArch64之间的差异 - 已经有很好的资源来探索这些差异。

此外,许多ARM与ARM64资源都集中在指令集和架构差异上。这些差异与大多数Linux用户空间应用程序开发人员并不十分相关,超出了非常明显的范围,例如“你的指针更大。”但是,正如我们发现的那样,对于Linux用户空间开发人员来说存在重要差异,其中四个我将会在这里讨论。这些差异分为几类,一些属于多个类别。类别是:

由于迁移使用相当新的内核版本而产生的差异。

由于体系结构和指令集(这与用户空间程序员有关)的差异。

Ptrace 差异。我们经常使用 ptrace ,所以这对我们来说非常重要。

我将在下一节中尝试使用以下格式:

该区域的简要说明。

有什么不同?为什么会有所不同?(有时通过查看一些装配说明比通过罗嗦的描述更容易理解行为的变化,所以我会提供那段代码。)

我们是如何遇到它的?

我们是如何克服它的?

在哪里可以找到更多信息。

1。对 ptrace 的更改

ptrace 为用户空间程序提供了进程跟踪功能。

有一个编号对 ptrace()接受的请求的更改。这些更改产生了最令人愉快的所有不兼容性:编译错误。我们的错误报告是针对未定义的符号PTRACE_GETREGS(对于通用寄存器),PTRACE_GETFPREGS(对于浮点和SIMD寄存器),以及PTRACE_GETHBPREGS(对于硬件断点寄存器),以及这些请求的SET版本。

ptrace 的 man 页面在解决方面毫无帮助这些错误,所以我们挖得更深。我们看了一下内核源代码,结果发现通常存在独立于体系结构的 ptrace 代码路径(kernel/ptrace.c中的ptrace_request()),以及独立的体系结构依赖路径(例如arch/arm/kernel/ptrace.c中的arch_ptrace()。虽然arm64版本有一个用于AArch32应用程序的compat_arch_ptrace,但arm64 arch_ptrace()直接调用ptrace_request()并且不添加任何其他 ptrace 请求类型。

解决方案是使用PTRACE_GETREGSET和PTRACE_SETREGSET具有各种不同的参数来读取这些寄存器。

这是GETREGS样式请求和最接近的等效GETREGSET请求的表。通过 addr ptrace()参数的不同参数获取不同的REGSET。

ARM 32位 AArch64
GETREGS NT_PRSTATUS
GETFPREGS NT_PRFREG
GETHPBREGS NT_ARM_HW_BREAK
NT_ARM_HW_WATCH


表1. ARM 32位和最接近的等效AArch64 ptrace请求。

请注意,NT_ARM_HW_BREAK和NT_ARM_HW_WATCH在GETREGSET请求中的行为相同。

使用GETREGSET并不像使用GETREGS那么简单。对于像这样的GETREGS请求:

ptrace(PTRACE_GETREGS,0,0,regs);

GETREGSET看起来像这样:

struct {void * buf; size_t len;} my_iovec = {regs,sizeof(* regs)};
ptrace(PTRACE_GETREGSET,0,(void *)NT_PRSTATUS,& my_iovec);

注意也是我已经说过“最接近的等效GETREGSET请求。”当然,AArch64寄存器组与ARM 32位寄存器不同,但两者之外的寄存器组之间存在更多差异。



              查看评论 回复



嵌入式交流网主页 > 嵌入式操作系统 > armlinux > ARM64与ARM32 的Linux程序区别在哪里
 

"ARM64与ARM32 的Linux程序区别在哪里"的相关文章

网站地图

围观()