关于在iOS装置跑Linux系统的尝试,我之前讨论过iSH Shell终端、 UTM虚拟机的作法,现在我要来尝试直接在iPhone装Linux系统。
1. 背景#
chem8可说是Apple近年来最大的漏洞,搭配checkra1n软件,能够在开机之前完成越狱操作。 2020年,有神人搞了Project Sandcastle,成功在iPhone 7跑Android 10,作者也着手移植Linux核心,尽管差点被Apple告了,这个项目依然继续开发。
几年后,更多开发者尝试在其他iPhone上跑Linux。 checkm8仰赖的漏洞仅支持A7 ~ A11芯片,也就是iPhone 5S ~ iPhone X的装置,更旧或更新的装置都不行。
理想上iPhone 7是目前状态相对好的装置,能够在AFPS挂载postmarketOS开机,甚至有开发者让它能跑Wayland了。 可惜我没有这台。
我有两台支持checkm8的旧iOS装置,分别为iPhone SE (iOS 15)和iPod touch 6 (iOS 12)。 网络上有许多成功启动Linux的案例,但没写他们的iOS版本。 iOS 15以上只能用palera1n越狱,得用指令启动pongoOS Shell,但我测试过有其他问题。 所以改用iPod touch 6测试,这台的处理器跟iPhone 6相仿,理论上可行。paleran1 -p -f
至于要怎么跑Linux呢? 首先要通过checkra1n进入pongoOS Shell,再引导Linux开机。
要选哪个Linux发行版呢? 虽然论坛有人成功编译Ubuntu开机,社交平台也有人跑起Asahi Linux(见文末参考资料),但是postmarektOS Wiki上面有更多人成功的照片,加上这个社群是比较关注Linux行动装置议题的,所以我以这个发行版为基础下去尝试。
后续有二种作法,一是将Linux编译成ramdisk开机,重开机后资料就会消失。
二是利用 pmbootstrap提供的Netboot功能,进行网络开机,重开机后资料依然会消失,不过rootfs会留在电脑上。
嗯,所以严格说来这些都不是真正的「装」Linux系统到 iPhone 上,系统没有真正写入到 iPhone 磁盘,只是暂时用 Linux 开机而已。 目前不论用什么方法,都得依赖电脑引导才能开机进入Linux。
2. 准备项目#
- Linux或Mac电脑,我使用Ubuntu 24.04
- 支持checkra1n的iOS设备,也就是A7 ~ A11芯片,iPhone 5S ~ iPhone X的装置。 我使用iPod touch 6,系统版本iOS 12.5.7。
- Lightning to USB OTG转接器,鼠标和键盘。 因为Linux没有触控驱动,所以iPhone开机后得用键盘鼠标控制。 若熟悉使用SSH指令控制X11的话不要也罢。
3. 编译pongoOS#
pongoOS是在加载iOS XNU核之前执行的程序。
- 编译pongoOS之前,需要依赖checkr1an。 (paler1an不需要编译pongoOS)
- 到 官网下载checkra1n执行文件,并塞到系统目录
wget https://assets.checkra.in/downloads/linux/cli/x86_64/dac9968939ea6e6bfbdedeb41d7e2579c4711dc2c5083f91dced66ca397dc51d/checkra1n
sudo mv checkra1n /usr/bin/
- Linux安装Clang 11
sudo apt install clang-11 xdd
- 从checkra1n的套件库安装ld64和cctools-strip,其他发行版需要针对新版Clang手动编译。
echo 'deb https://assets.checkra.in/debian /' | sudo tee /etc/apt/sources.list.d/checkra1n.list
sudo apt-key adv --fetch-keys https://assets.checkra.in/debian/archive.key
sudo apt update
sudo apt install ld64 cctools-strip
- 取得pongoOS源代码并编译,使用konradybcio的fork。
git clone https://github.com/konradybcio/pongoOS
cd pongoOS
LD_LIBRARY_PATH="/usr/lib/llvm-11/lib/" EMBEDDED_CC="/usr/bin/clang-11" EMBEDDED_LDFLAGS=-fuse-ld=/usr/bin/ld64 STRIP=cctools-strip make all
注:pongoOS源码太久没更新了,有时会编译失败。 你也可以用macOS虚拟机编译。 以下为在macOS Ventura用Xcode编译的指令:
xcode-select --install
git clone https://github.com/konradybcio/pongoOS
cd pongoOS
make all
最终会得到。build/Pongo.bin
4. 编译Linux核心#
- 安装编译依赖套件
sudo apt install build-essential clang libncurses5 flex git bc bison
- 取得konradybcio提供的linux-apple核心源代码
git clone https://github.com/konradybcio/linux-apple
cd linux-apple
- 取得SoMainline提供的defconfig
wget https://raw.githubusercontent.com/SoMainline/linux-apple-resources/master/example.config -O ./.config
- 调整PAGESIZE
make ARCH=arm64 LLVM=1 menuconfig
- 按搜索,输入,按1
/
_PAGE
- PAGESIZE,A8处理器设置4K,A9处理器以上设置为16K。 之后按下Exitt,储存.config。
- 编译核心
make ARCH=arm64 LLVM=1 -j$(nproc) Image.lzma dtbs
- 最终会得到
arch/arm64/boot/Image.lzma
- 取得dtbpack指令稿,放到Linux核心所在目录
wget https://raw.githubusercontent.com/SoMainline/linux-apple-resources/master/dtbpack.sh
chmod +x dtbpack.sh
- 生成dtbpack
./dtbpack.sh
5. 编译postmarketOS的rootfs#
- 安装 pmbootstrap
- 初始化,机型选apple-iphone6。 桌面环境选xfce4。
pmbootstrap init
- 建立rootfs
pmbootstrap install
6. 开机进入Linux#
- 设置 libimobiledevice,确认Linux认得到iPhone。
- 将iPhone插上电脑,手动进入DFU模式:关机,等5秒。 按住电源键3秒,接着按电源键+Home键10秒,然后松开电源键,继续按着Home键。
- 确认进入DFU后,在pongoOS源代码的目录开启终端机,用checkra1n进入pongoOS Shell
cd pongoOS
sudo checkra1n -v -V -p -c -k ./build/Pongo.bin
- 此时iOS设备的屏幕会看到pongoOS Shell
- 启动postmarketOS的neboot
pmbootstrap initfs hook_add netboot
pmbootstrap export
- 将Linux的initramfs传到iOS装置
cd pongoOS
python3 scripts/load_linux.py -k "linux-apple核心目錄/arch/arm64/boot/Image.lzma" -d "linux-apple核心目錄/dtbpack" -r /tmp/postmarketOS-export/initramfs
- 等待Linux开机… 结果kernel panic,干。
- 如果正常开机的话,再传送Netboot的rootfs,即可进入Linux系统。
pmbootstrap netboot serve
ssh user@172.16.42.1
7. 总结#
每次干这种事的时候我就会想到这首歌。 It’s all a waste of time again.
目前没有实用性,有点像是驱动支持度差的Android机硬要刷postmarketOS那样。 最大问题还是驱动程序支持度差,看 SoMainline提供的表格就知道,几乎全部的硬件功能都是打叉的。
而Apple设备的驱动程序又有谁有办法逆向工程出来呢? 有像Asahi Linux那样热忱的开发者吗? 况且启动Linux还是靠硬件漏洞实现的。
除了能开机跑些Linux程序外没什么发展性。
比较现实的策略,可能还是在 iOS 设备跑 JIT 加速的 UTM 虚拟机,再于里面跑 Linux 虚拟机较为实用。