如何使用armv7用户空间在aarch64硬件上对arm64 GCC进行沙盒式处理

原文链接:How to Sandbox an arm64 GCC on aarch64 Hardware with armv7 Userspace 由Jean-Luc Aufranc撰写。

人生苦短,在我们所关注的领域里,行业进步似乎永远都不够快。这是我们大多数人都熟知的观感。有人会认为现在大多数的aarch64桌面应用都可在arm64环境下运行,并在需要时提供多架构支持。

可是令人失望的是,截至2019年底,aarch64上的chromeOS仍在发布aarch64架构内核和armhf用户空间。尽管优秀的chromebrew开发人员做的工作很好,但在开发模式下的arch64 chromeOS系统–一个本来优秀的公路骑行勇士,却被32位armhf所束缚。有人可能会问,这是一个问题吗?是的,aarch64 客观上是 MCU 之外更好的 arm ISA,从通用代码到各种 ISA 扩展方面都是,尤其是 SIMD。这主要体现在当代编译器支持和代码生成质量的差异上。特别是鉴于2019年为 aarch64 和 Thumb2 引入了 ILP32 ABI,尽管它在 aarch64 下不受支持,目前却没有充分的理由寄希望于近期可以在 aarch64 机器上构建 aarch32 代码。

Arm64 GCC Armv7 用户空间

作为一个长期的arm chromebook用户,我一直在我的chromebook上使用沙盒式arm64编译器。最近我像往日一样离家骑行时,发生的一件事故,由于我的马虎,那个沙盒一不小心损坏了,所以我不得不使用昂贵的移动数据从头再做一遍。不过这促使我记录下了建立沙盒所必需的最少步骤,现在将这些步骤与各位分享。请注意,这些步骤对任何3.7或更新的arch64内核和armhf用户空间的设置都是有效的,但在chromeOS的情况下,有一些额外的限制–严格限制用户对根系统文件进行更改。

在chromeOS开发模式下,/usr/local目录下有一个可写的系统文件空间,因此我们将在此处设置沙箱。


我们需要选择一个好的arm64软件包来源–一些软件包的最新基础发行版就可以了。这意味着Debian或Ubuntu符合–我们选择了软件包新率更好的后者。接下来需要决定要哪个版本的编译器,因为这将决定我们需要哪些系统库。由于个人原因,我决定使用gcc 8.2.0。以下是选择的gcc软件包版本列表,需要从http://ports.ubuntu.com/ubuntu-ports/pool/main/下载:


如果在主Ubuntu存储库中定位这些软件包有困难,可以使用全局注册http://ports.ubuntu.com/ubuntu-ports/ls-lR.gz

接下来 “部署”这些软件包。我们可以逐个进行,例如想检查每个软件包中的内容:


或者很多:


该步骤简单直接,但是接下来的步骤就不那么简单了。

aarch64 内核在本地运行静态链接的二进制文件,OK,这没什么问题。不过,此类二进制文件在Linux桌面应用上很少见——你将遇到的或自己编译的大多数二进制文件都属于动态链接。对于平台支持的每个架构,都必须有对应的动态加载器。目前,应通过如下命令行构建ARM多架构:


分别对aarch64和armhf架构,自然只有一个单架构;如果你查询任何给定的动态链接二进制文件,通过如下命令行,你会看到在ELF类型之后立即报告所加载的信息:


上面的命令行“dynamically linked, interpreter /lib/ld-linux-armhf.so.3”,告诉我们应该用什么动态加载器来启动每个二进制文件,包括路径和所有内容。由于不能在chromeOS上修改/lib,不能在那里放置arch64加载器,所以我们需要返回到其他方式。

正如许多人所熟知的那样,gcc 的二进制文件只是一个门面模式,它调用大量现有商业二进制文件来进行构建。在我们的沙盒环境中,命令行如下:


现在,前两行命令行所需文件由.deb软件提供,而后两行命令行通常只是现有arch64-linux-gnu-*二进制文件的符号链接,但我们没有这些链接,而且反正我们也不需要这些作为符号链接。

每次arm64 gcc尝试执行其中一个时,它都会由于缺少aarch64 的系统级加载程序而失败。那么我会如何解决呢?很容易——通过手动指定应该与想要运行的任何给定arm64二进制文件一起使用的加载程序。因此,按我们的要求通过一些同名脚本隐藏这些二进制文件,同时将cc1和collect2的原始二进制文件作为.bak 文件保留在其原始位置:


最终,我们希望在下面相应目录位置分别有以下脚本:

  • /usr/local/root64/usr/lib/gcc/aarch64-linux-gnu/8/cc1:

  • /usr/local/root64/usr/lib/gcc/aarch64-linux-gnu/8/collect2:

  • /usr/local/root64/usr/bin/as:

  • /usr/local/root64/usr/bin/ld:


最后,同样很重要的一点。我们需要一个 gcc 顶层脚本来为我们设置一些内容最好放在目录PATH中的某个位置:

  • gcc-8.sh:


让我们用以下示例命令行测试一下这个新沙盒装置:


首先,使用系统自带的armhf gcc-8.2.0编译器,这由chromebrew提供


接下来使用我们刚刚设置的arm64 gcc-8.2.0:


请注意,由于我们还没有导出arm64支持的LD_LIBRARY_PATH路径,我们必须在调用aarch64加载器之前在命令行中指定它。

Arm64 GCC Armv7 用户空间

图片描述:Chromebrew Arm64 gcc命令行代码

好吧!伙计们,以上就是全部步骤。我希望这些对aarch64+armhf用户能够有用。

分享这篇文章
订阅评论
提醒
0 评论
内联反馈
查看所有评论