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

2020-08-03来源: elecfans关键字: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
GETREGSNT_PRSTATUS
GETFPREGSNT_PRFREG
GETHPBREGSNT_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位寄存器不同,但两者之外的寄存器组之间存在更多差异。


图图1示出了从ARM 32位GETREGS和AArch64 GETREGSET指令返回的寄存器的图。

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

图1. GETREGS和GETREGSET。


熟悉AArch64的人可能会注意到GETREGSET我们已经获得了“cpsr”注册,但硬件架构没有。 GETREGSET返回的内容已经从AArch64上可单独访问的字段合成为类似cpsr的布局。


两者之间更显着的差异是GETREGSET缺少orig_r0(或orig_x0)。这种缺乏与系统调用有关。在ARM 32位上,系统调用编号放在r7中,并且系统调用参数在系统调用(SVC)指令之前放在参数寄存器r0-r3中。从系统调用返回的值位于r0(根据通常的APCS,在特殊情况下为r7)。内核从 syscall 返回后,orig_r0将原始的第一个参数提供给 syscall (已被返回值覆盖)。


I实际上不知道“正常”应用程序应该使用什么用于这个原始的第一个参数。我们使用它来支持 restart_syscall ,其中返回值为ERESTART_RESTARTBLOCK。


不幸的是,缺乏orig_x0对我们来说是个问题,我们还没有在任何情况下解决。如果我们已经记录了系统调用的条目,那么我们就拥有了所需的所有信息。但是,如果我们在 restart_syscall 期间附加了,那么我们就不知道x0的原始值。我们唯一的选择是允许内核重新启动 syscall ,但这次重启对我们来说是低效的,因为我们无法优化系统调用的录制。

回到GETREGS与GETREGSET的主题:GETHBPREGS和NT_ARM_HW_BREAK也有很大不同。对于GETHBPREGS请求,使用 ptrace 调用中的 addr 字段来请求特定的硬件断点寄存器。 NT_ARM_HW_BREAK返回所有硬件断点寄存器。

关键字:ARM64  ARM32  Linux程序 编辑:什么鱼 引用地址:http://news.eeworld.com.cn/mcu/ic505108.html 本网站转载的所有的文章、图片、音频视频文件等资料的版权归版权所有人所有,本站采用的非本站原创文章及图片等内容无法一一联系确认版权者。如果本网所选内容的文章作者及编辑认为其作品不宜公开自由传播,或不应无偿使用,请及时通过电子邮件或电话通知我们,以迅速采取适当措施,避免给双方造成不必要的经济损失。

上一篇:基于FPGA的ARM并行总线和端口设计
下一篇:基于ARM的嵌入式操作系统该如何设计

关注eeworld公众号 快捷获取更多信息
关注eeworld公众号
快捷获取更多信息
关注eeworld服务号 享受更多官方福利
关注eeworld服务号
享受更多官方福利

推荐阅读

ARM64位开发板上兼容ARM32位的可执行程序
程序:(arch/arm64/Kconfig中)config COMPAT    bool "Kernel support for 32-bit EL0"    depends on ARM64_4K_PAGES || EXPERT    select COMPAT_BINFMT_ELF if BINFMT_ELF    select HAVE_UID16    select OLD_SIGSUSPEND3    select COMPAT_OLD_SIGACTION    help
发表于 2019-12-25
在<font color='red'>ARM</font>64位开发板上兼容<font color='red'>ARM32</font>位的可执行程序
服务器芯片战火将起 ARM64位芯片叫板英特尔
据国外媒体报道,英特尔在服务器芯片领域具有绝对的主导地位,服务器芯片占到营收的约20%,提高了其营收的稳定性。但是,未来64位ARM服务器芯片将对英特尔在服务器芯片市场上的地位形成威胁。 ARM VS. 英特尔 投资者应当注意的是,英特尔服务器芯片的原始处理能力高于ARM芯片,原因是英特尔芯片提供一定的硬件定义功能,应用方式更为灵活。 但是,这些硬件功能的实现需要晶体管,ARM芯片没有硬件功能,这也是英特尔芯片晶体管数量是ARM芯片3倍的原因。更多的晶体管数量有助于提高芯片性能,但它们会消耗能源,这也是ARM芯片能源使用效率高于英特尔芯片的原因。 迄今为止,英特尔和AMD是仅有的两家X86架构服务器芯片厂商。最近数年AMD的皓
发表于 2014-08-11
服务器芯片战火将起 ARM64位芯片叫板英特尔
据国外媒体报道,英特尔在服务器芯片领域具有绝对的主导地位,服务器芯片占到营收的约20%,提高了其营收的稳定性。但是,未来64位ARM服务器芯片将对英特尔在服务器芯片市场上的地位形成威胁。 ARM VS. 英特尔 投资者应当注意的是,英特尔服务器芯片的原始处理能力高于ARM芯片,原因是英特尔芯片提供一定的硬件定义功能,应用方式更为灵活。 但是,这些硬件功能的实现需要晶体管,ARM芯片没有硬件功能,这也是英特尔芯片晶体管数量是ARM芯片3倍的原因。更多的晶体管数量有助于提高芯片性能,但它们会消耗能源,这也是ARM芯片能源使用效率高于英特尔芯片的原因。 迄今为止,英特尔和AMD是仅有的两家X86架构服务器芯片厂商。最近数年AMD的皓龙
发表于 2014-08-07
LCD的ARM编程方式,LCD Linux程序如何写入?
比间接控制方式更精简一些,程序的运行效率也较高。本文中的程序采用C语言编写,通用性强、移植方便。该方法及程序在系统显示部分中,显示清晰、工作稳定。具有模块化结构和代码可移植性,且通用性较好,在嵌入式系统中有一定代表性和广泛用途。  怎样写 Linux LCD 驱动程序:  基本原理  通过 framebuffer ,应用程序用 mmap 把显存映射到应用程序虚拟地址空间,将要显示的数据写入这个内存空间就可以在屏幕上显示出来;  驱动程序分配系统内存作为显存;实现 file_operations 结构中的接口,为应用程序服务;实现 fb_ops 结构中的接口,控制和操作 LDC 控制器;  驱动程序将显存的起始地址和长度传给 LCD
发表于 2020-09-23
LCD的ARM编程方式,LCD <font color='red'>Linux</font><font color='red'>程序</font>如何写入?
ARM Linux各种驱动的中断服务程序工作在ARM的IRQ模式吗?
大家都知道,ARM有IRQ, FIQ, USR,SVC,ABORT等各种模式。当系统收到IRQ的时候,会进入ARM的IRQ模式。那么,ARM Linux各种驱动的中断服务程序工作在ARM的IRQ模式吗?答案是否定的。我们加一段汇编来读CPSR:然后我们随便找一个ARM Linux的中断服务程序去打印CPSR:然后我们发现打印出来的值是:cpsr:40000193低8位的二进制是10010011那么对应ARM CPSR的查询,可以看出CPU处于ARM的SVC模式(低5位是10011),而且I bit被设置(第7位是1),所以是禁止IRQ的。模式表:可见,ARM Linux最初进入IRQ模式后,比较快速地从IRQ模式切换
发表于 2020-08-26
ARM <font color='red'>Linux</font>各种驱动的中断服务<font color='red'>程序</font>工作在ARM的IRQ模式吗?
ARM-Linux开发与MCU开发有何不同?
针对ARM-Linux程序的开发,主要分为三类:应用程序开发、驱动程序开发、系统内核开发,针对不同种类的软件开发,有其不同的特点。今天我们来看看ARM-Linux开发和MCU开发的不同点,以及ARM-Linux的基本开发环境。  1.  ARM-Linux应用开发和单片机开发的不同这里先要做一个说明,对于ARM的应用开发主要有两种方式:一种是直接在ARM芯片上进行应用开发,不采用操作系统,也称为裸机编程,这种开发方式主要应用于一些低端的ARM芯片上,其开发过程非常类似单片机,这里不多叙述。还有一种是在ARM芯片上运行操作系统,对于硬件的操作需要编写相应的驱动程序,应用开发则是基于操作系统的,这种方式
发表于 2020-07-12
小广播
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
电子工程世界版权所有 京ICP证060456号 京ICP备10001474号 电信业务审批[2006]字第258号函 京公海网安备110108001534 Copyright © 2005-2020 EEWORLD.com.cn, Inc. All rights reserved