独行穿落叶,闲坐数流萤。

授权品牌卖家

  • 16800988

    总访问

  • 24388

    文章数量

外贸加速器苹果客户端

我们不仅仅支持移动客户端,还有Windows,Mac,Linux版本。拥有多快,可以在所有的设备上使用 简单好用 多平台覆盖 多种协议
立即下载

作者 | AsahiLinux.org

译者 | 弯月

出品 | CSDN(ID:CSDNnews)

以下为译文:

欢迎各位阅读我们的第一份《Asahi Linux 进度报告》!文本将向你播报该项目的最新进展的。

支持新型的 Linux 系统芯片绝非易事!我们希望通过本文,各位能够了解为了让 Linux 在新设备上运行,我们在幕后付出的艰辛。

术语说明

在这篇报告中,我们会提到一系列的术语:AArch64、ARM64 和 ARMv8-A。

这些术语的含义略有不同,但是在文本中,你可以将它们全部理解为“ 64位ARM”。

Asahi Linux 项目于今年年初正式启动,但当时我们都在等待一个关键的部分:在苹果芯片系统上引导其他内核的支持。虽然该功能早已进入开发文档,而且大部分都已实现,但还缺少最后一个关键部分:对于 kmutil configure-boot命令的支持,只有通过这个命令才能安装非苹果内核。但这个问题未能阻止我们前进,为了将操作系统移植到一个没有文档记录的平台,第一步要做的就是建立文档记录!

搭载苹果芯片 Macs 的启动方式与传统 PC 完全不同。它的工作方式更类似于嵌入式平台(比如安卓手机,iOS 设备等),但是引入了许多特别的机制。然而,苹果已经采取了一些措施,让启动过程更贴近英特尔芯片的 Mac 操作系统,因此人们对实际的运转方式充满了困惑。例如,根据传统的经验来看,搭载苹果芯片 Mac根本不能通过外的存储启动。搭载苹果芯片 Mac 的引导程序也无法显示图形用户界面,并且“引导程序选择器”实际上是一个全屏的 macOS 应用,而不是引导程序的一部分。

因此,为了在这些计算机上运行自己的内核,首先我们必须确认启动过程的工作方式,内部 SSD 上分区和卷的布局方式,并找出与 PC 的区别。该文档不仅对我们的项目有帮助,而且也可以作为希望更好地了解计算机工作原理的所有 macOS 用户的参考文档。

2021年2月版的《苹果平台安全指南》(https://support.apple.com/en-ca/guide/security/welcome/web)中记载了部分功能及其基本原理。

搭载苹果芯片的 Mac 启动过程没有遵循任何现有标准。它是定制的苹果机制,从 iOS 设备的早期阶段慢慢发展起来的。

而在苹果之外,64 位 ARM 世界基本上可以分成两大互相竞争的标准:UEFI + ACPI(主要在运行Windows或Linux的服务器上使用)和 ARM64 Linux 引导协议+ 设备树(在小型系统上使用,并得到了U-Boot等的支持)。我们需要为Asahi Linux 选择其中一种标准,并找到一种方法在苹果和我们的世界之间架起桥梁。

UEFI 和 ACPI 是非常复杂的庞然大物,通常仅适用于大型 ARM 系统。这些标准主要由 UEFII 论坛的委员会控制。x86 PC 世界比较单一,但 ARM 世界则极为多样化,系统芯片拥有各种各样的设计,为的是满足其上硬件的不同要求。因此,如果想增加对新 SoC 的支持,则必须修改这些标准,给那些特殊的硬件添加“绑定”。对于 ACPI 而言,这项工作既昂贵又缓慢,这就是为什么 ACPI 几乎从来不在 Windows 以外的小型嵌入式系统上使用。对于我们来说,这个选择行不通。

各种各样的小型嵌入式 ARM Linux 系统几乎都采用了设备树(DeviceTree)标准,比如大多数安卓设备的启动都采用了这种方式。设备树比 ACPI 简单得多,因为设备树纯粹是一堆描述硬件的数据,而 ACPI 表则结合了数据和代码。如今,设备树绑定的权威是 Linux 内核树内部维护的文档,这意味着我们可以在编写Linux驱动程序本身的同时,修改这些标准。因此,Asahi Linux 的启动过程也采用了这种模型。

有意思的是,苹果针对苹果芯片的设备建立了苹果版的设备树,名叫苹果设备树(Apple Device Tree)!这是因为苹果和开放的设备树标准都建立在开放固件规范(包括旧款 Mac 在内的许多 PowerPC 系统都采用了该规范)之上。不幸的是,尽管这意味着 ADT 对于嵌入式 Linux 开发人员来说并不陌生,但我们还是不能直接使用它们,原因在于二进制格式不同,而且如果没有关于数据含义的高级信息,两种格式之间就无法自动转换。而在规范之上,各个设备的实际绑定完全不一样。虽然 Linux 和 macOS 在 PowerPC Mac 上的工作方式相同,并且可以兼容,但 Linux 和苹果在 ARM 领域已经分别发展了十多年。试图统一苹果和 Linux 处理设备树的方式将是一场噩梦。

为了让苹果使用设备树,我们正在开发 m1n1,这是一款苹果芯片电脑的引导程序。它的目标是尽可能多地处理“苹果风格”的东西,减轻 Linux 或其他下游产品的负担。

你可以将 m1n1 添加到 Linux 内核的前面(对于最简单的固定内核,只需要运行cat m1n1.macho initrd.bin devicetree.dtb Image.gz > m1n1-kernel.macho即可),然后使用苹果的工具 kmutil 将其安装到 Mac 上,它就会负责启动 Linux 所需的一切处理。使用 m1n1 引导 Linux 的大致过程如下:

“旋转表”(spin-table)是 ARM 版 Linux 在设备树的世界中启动额外的 CPU核心的两种标准之一。不依赖于平台特定的驱动的标准方法有两种,所有平台都要使用两者之一。最简单的一种叫做旋转表,其做法是让引导程序事先启用所有CPU 核心,然后让它们在一个循环中等待(叫做“旋转”)。为了从循环中释放CPU,Linux 需要向内存写入一个值,告诉 CPU 从何处跳转到内核。对于简单的平台来说这完全没问题,唯一的限制就是没有办法完全停止 CPU,因为从引导程序中接管 CPU 是一次性的。不过可以通过其他机制让 CPU 进入各种省电模式。我们目前采用了这种方式,有可能以后也会一直延续下去。

另一种方法叫做“PSCI”,这是一个 ARM 标准,是系统固件提供的服务,即使在Linux运行时,也可以利用它同时控制所有 CPU。通常,该操作需要运行在 “EL3”(即安全固件,又称TrustZone)上的代码来实现,或者通过运行在“EL2”上的虚拟机监控程序来实现。而操作系统通常运行在 EL1 上。但是,在ARMv8-A 的 CPU 中,EL3和EL2都是可选的,而且事实证明 M1 并不支持EL3。M1支持EL2,但是我们希望能在Linux下运行虚拟机,这就要求 Linux 本身需要运行在 EL2 中,因此没办法在 EL2 中运行一个监控程序。这就意味着我们现在还不能使用 PSCI,因为 PSCI 的标准接口不满足我们的需求。以后也许能够出现其他标准方法。也许,只有采用其他方法,才能支持整个系统的睡眠功能,尽管如果细粒度的电源管理足够好的话,我们也许不需要“真正”的全系统睡眠模式,就能获得不错的待机时间(现代设备对于更细粒度的睡眠模式的支持非常好)。不过这个领域仍然在发展,所以只能拭目以待了。

虽然我说过我们要使用设备树,但这并不意味着我们不能使用 UEFI!ARM64系统能够同时使用 UEFI 和设备树进行引导,而且只有这样做,才能像 PC 那样通过 GRUB 等引导程序和通用的流程安装和升级内核。但是 m1n1 并不支持这样做,那么怎么办呢?幸好还有其他途径:U-Boot。U-Boot 可以像 Linux 内核一样引导,所以只需从 m1n1 中引导 U-Boot,然后 U-Boot 就可以为GRUB 和 Linux 提供良好的 UEFI 环境。

因此,最终 Asahi Linux 的引导链大致如下:

m1n1 → U-Boot → GRUB → Linux

结合苹果特有的引导链,整个引导过程大致如下:

对于***惯了 PC 的人来说,这个过程可能有点不可思议,但在嵌入式系统中,这种很长的引导链是十分常见的(而且实际上,即使在普通的 PC 上,UEFI 也包含多个阶段,只不过最终用户看不到而已)。例如,DragonBoard 410c(一款基于高通的平台)的引导链可能如下:

PBL→SBL→QSEE→QHEE→LK→U-Boot→GRUB→Linux

注意,我们没办法替换 iBoot2(它需要苹果的签名),但最终用户的安装过程会自动设置一个最小化的“macOS”,其中包含 iBoot2 和所有必须的支持文件,为的就是解决这个问题。这些足够让苹果的引导过程将其识别为可引导的OS(只不过没有真正的macOS内核和文件系统)。我们还没有实现安装程序,所以目前开发人员只能通过先整安装 macOS,再替换内核的方式来尝试 m1n1和LInux。我们编写了一个手把手的快速入门指南(https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart),供想尝鲜的人使用。

目前,我们主要的开发工作是从直接 m1n1 中加载 Linux,不过 Mark Kettenis 在负责 U-Boot 和 OpenBSD 的支持工作。

但是 m1n1 不仅仅是运行 Linux。实际上,它本身甚至不是引导程序!

m1n1 诞生于 mini,后者是我为任天堂 Wii 的安全 CPU 编写的一个最小化环境。它很适合拿来做各种试验,以及作为 BootMii 的后端。如果你手里有Wii,而且还听说过 BootMii,那么当你在 BootMii 的菜单中时,ARM CPU上运行的就是 mini。

那么,这跟苹果芯片上的引导程序有什么关系呢?实际上,mini 只不过是在32位裸金属 ARM 系统上运行的一个非常简单的软件,不包含任何外部库和依赖。因此,它非常适合构建裸金属代码,于是我们将其移植到了 AArch64 和苹果芯片上,并改名为 m1n1。但更重要的是,mini 和 m1n1 都有一个秘密武器:由于 mini 作为固件在一个单独的处理器上运行,而这个处理器需要主 CPU 负责控制,而且根据以前针对 Wii 的硬件研究成果,mini 内置了一个 RPC ***,可以通过串口访问。这就意味着你可以从一台开发计算机上对 mini 和m1n1进行“远程控制”,甚至可以从交互式的shell中进行(https://github.com/AsahiLinux/docs/wiki/Developer-Quickstart#playground-shell)。所以更恰当的描述是,m1n1 是一个硬件实验工具,恰好能作为 Linux 引导程序使用。

所以说,这个平台特别适合硬件学***,而且适合寻找苹果的私有特征。例如,

将一台 M1 Mac Mini 引导至 m1n1 需要大约 7 秒,而且所有这些脚本都可以交互式运行,无需重启(除非你把机器搞崩溃了)。m1n1 还能加载自身,所以 m1n1 的开发***期非常快:只需用 kmutil 安装一次 m1n1,以后重启后只需加载最新的 m1n1 即可。

我们使用 m1n1 为苹果的自定义 ARM 指令集、苹果专用的系统寄存器以及苹果中断控制器等硬件建立了文档。

以后,我们会继续给 m1n1 添加更多特性,让它成为更强大的研究工具。其中一个特别激动人心的目标就是,将其变成一个非常薄的虚拟机监控程序,能够启动 macOS,并拦截 macOS 对于 M1 硬件的访问。如此一来,我们无需反编译,就能调查苹果的驱动程序的工作方式,还能通过合法的渠道进行调查,而且比跟踪复杂的私有驱动程序的代码效率高很多。一些人可能知道这种方法,因为之前 nouveau 就成功地通过此方法,对 NVidia 的 GPU 进行了逆向工程,但当时
标签

加速器

发布日期

2021年10月21日

阅读次数

785