其他
将 Linux 移植到 M1 Mac 真的太难了!
AArch64 指的是 64 位 ARM 体系结构指令集; ARM64 是 Linux 为 64 位 ARM 提供的支持; ARMv8-A 是包含 AArch64 的 ARM CPU 体系结构规范。
01
02
连接两个世界的桥梁
初始化主 CPU,并应用 chicken bit 设置,使其正常工作。 读取苹果引导加载程序 iBoot 提供给它的引导信息:其中包括可用的内存量以及内存帧缓冲区(屏幕上显示的视频的内存)的地址。 初始化内存管理单元。为了能够使用 CPU 缓存,这一步是必需的,否则,一切运行速度都会非常慢。 在屏幕上显示 Asahi Linux 的标志,代替苹果的标志。 禁用 watchdog timer。如果没有这一步,Mac 会在大约一分钟后自发重启,因为它以为启动过程被卡住了。 找出需要启动的程序:Linux 内核、设备树以及(可选的)包含启动时应用程序的 initramfs ramdisk(如果已将它们附加到启动时的话)。 初始化所有其他 CPU 核心,并应用必要的 chicken bit,然后让它们在“旋转表”中等待 Linux 的接管。 从苹果的设备树中获取信息,并修改设备树模板,使二者匹配。这一步是为了修改不同的计算机以及苹果 iBoot 固件不同版本的设置,例如内存大小、有关帧缓冲区的信息、初始化 Linux 随机数生成器的种子等。此外, m1n1 还添加了一些自己的信息,例如旋转表的详细信息以及内核的命令行参数(视情况而定)。 跳转到 Linux,或下一步。
在冷启动时,M1芯片内的 SecureROM 启动,并从NOR闪存中加载iBoot1。 iBoot1 读取内置 SSD 中的引导配置,验证系统引导策略,然后选择一个“操作系统”进行引导。在我们看来,Asahi Linux / m1n1 对于 iBoot1而言就像一个操作系统分区。 iBoot2(操作系统引导程序,它需要位于被引导的操作系统分区内)加载固件供内置设备使用,设置苹果设备树(ADT),并引导一个 Mach-O 内核(对于我们,就是m1n1)。 m1n1 解析 ADT,配置更多设备,让整个环境更像 Linux,然后设置 FDT(展平后的设备树,即二进制格式的设备树),然后引导 U-Boot。 U-Boot(其驱动程序位于内置SSD中)读取其配置和下一阶段的代码,然后提供UEFI服务(其中包括转发来自m1n1的设备树)。 GRUB作为标准的UEFI应用,从磁盘分区中引导,就像 PC 上的 GRUB 一样。有了 GRUB,Linux 发行版就可以通过惯常的方式,使用 grub-mkconfig 和 /etc/default/grub 等管理内核。 最后,引导 Linux 内核,所需的信息由从 m1n1 传过来的设备树提供。
03
处理硬件问题
这段脚本(https://github.com/AsahiLinux/m1n1/blob/main/proxyclient/fptest.py)测试了一个特殊的苹果特性:给 CPU 添加一些 x86 专有的浮点配置比特,用于加速 Rosetta x86 模拟。 这个脚本(https://github.com/AsahiLinux/m1n1/blob/main/proxyclient/find_all_regs.py)能够搜索所有苹果定制的 CPU 寄存器,并输出它们的值和访问限制。 这个脚本(https://github.com/AsahiLinux/m1n1/blob/main/proxyclient/hacr_trap_bits.py)能够自动找出怎样通过苹果专有的监控程序配置寄存器来实施这些访问限制。 当然,还有这个脚本(https://github.com/AsahiLinux/m1n1/blob/main/proxyclient/linux.py)能够引导Linux内核,并通过串口输出。
04
05
CPU 内存管理单元(MMU) 中断控制器 系统时钟 某种控制台,在这里是串口控制台
06
07
G(Gather):将多个写操作收集到一个写操作中。例如,CPU 可以将两个相邻的8位写操作合并成一个 16 位写操作。 R(Re-order):对写操作重新排序。如果依次向两个相距很远的地址写入,那么CPU可能会用相反的顺序写入。 E(Early):提前写入。系统可能会在数据到达目标设备之前就告诉 CPU写入完成,从而让 CPU 继续执行后面的代码。在 x86 的世界中这个操作称为“posted write”。
引入ioremap_np()。在所有架构上,通常Linux都会使用通用的ioremap()函数映射 MMIO 设备内存。还有一些不十分严格的其他变种,例如ioremap_wt()。我们添加了一个新的变种,能特别低指定请求 non-posted 内存映射。 实现 ioremap_np() 在 ARM64 上使用 nGnRnE 模式(其他架构目前不会实现该模式,尽管这种模式对它们也许也有用。) 引入 nonposted-mmio 设备树属性。这也可以用来将设备树中的特定总线标记为需要 ioremap_np()。 让 Linux 设备树子系统在查找设备时自动选择 nonposted-mmio模式,并将其变成一个描述MMIO资源结构(IORESOURCE_MEM_NONPOSTED)中的一个标志。 编写两个高层 APIdevm_ioremap_resource()和of_iomap(),自动解释该标志,并将其“升级”成一个 ioremap_np()。 修改需要在 M1 系统芯片上使用的驱动程序,确保它们调用这些API,而不是调用原始的 ioremap()。
08
这就是AIC
09
过度繁琐的 FIQ
10
历史遗留下来的问题
11
终于能见到企鹅了!
董明珠如何看待加班?
↓↓↓
每天送出 红包/编程书籍
推荐阅读:
为了写论文给 Linux “投毒”,导致整个大学都被 Linux 拉黑!