這事以前也干過,也寫過一篇文章。不過是三年前了。最近又折騰了一次,發現三年變化還是蠻大的,決定再寫一篇。(還是 ArchlinuxARM)
首先用 CPU-Z 查看一下(已 root 的) Android 設備的硬件架構,然后到官網上下載一個對應架構的 base system 的 tarball. 然后在設備上弄個 ext3/ext4 文件系統,把它解壓到里面。
有外置 SD 卡的話,直接分出一個 ext3/ext4 分區給 Linux 用就行了。沒有的話,就只能用 loopback. 下面以使用 loopback 的情況為例進行講解。
所謂使用 loopback, 就是把系統裝在一個文件里。先創建文件:
$ dd if=/dev/zero of=./archlinux_arm bs=4M count=1024
這就創建了一個 4GiB 的文件。再小些也可以,不過 2GiB 或者更小就不大夠用(如果裝的軟件較多的話)。
接下來,把這個文件格式化為 ext3 文件系統:
$ mkfs.ext3 ./archlinux_arm
掛載這個文件到 /mnt :
$ mount -o loop ./archlinux_arm /mnt
解包 base system:
$ cd /mnt
[/mnt] $ tar -vxapf ~/Downloads/ArchLinuxARM-aarch64-latest.tar.gz
修改 /mnt/etc/group , 添加以下兩行,以便上網(Android 進行了某種限制,即使 root 也得添加到某些 group):
inet:x:3003:root net_raw:x:3004:root
再寫一個腳本,用於自動化 chroot:
$ cd - $ umount /mnt $ "$EDITOR" run_chroot.sh
run_chroot.sh 內容如下:
1 #!/system/bin/sh 2 3 ROOT="/system/mnt" 4 5 if [ -d "$ROOT/usr" ]; then 6 echo "Filesystems already mounted." 7 else 8 echo "Mounting loopback..." 9 mount -t ext3 -o loop /sdcard/archlinux_arm "$ROOT" 10 echo "Mounting API filesystems..." 11 mount -o bind /dev "$ROOT/dev" 12 mount -o bind /proc "$ROOT/proc" 13 mount -o bind /sys "$ROOT/sys" 14 echo "Binding SD Card..." 15 mount -o bind /sdcard "$ROOT/sdcard" 16 fi 17 18 echo "Executing chroot..." 19 LD_PRELOAD="" LD_LIBRARY_PATH="$ROOT/usr/lib" "$ROOT/usr/lib/"ld-*.so "$ROOT/usr/bin/chroot" "$ROOT" /usr/bin/su -l
(最后一行為何這么長?——設備上萬一沒有 chroot 命令,就必須借用 GNU/Linux 里面的程序了)
其中 mount -o bind /sdcard "$ROOT/sdcard" 是為了方便在 chroot 環境中訪問外部文件。
把文件發到設備上(如果能直接在電腦上掛載設備,就不需要這步):
$ adb push archlinux_arm /sdcard/ $ adb push run_chroot.sh /sdcard/
$ rm archlinux_arm
$ rm run_chroot.sh
連接到設備,開始配置:
$ adb shell (device) $ su (device) # mount -o remount,rw /system (device) # mkdir /system/mnt (device) # cp /sdcard/run_chroot.sh /system/bin/arch (device) # chmod 755 /system/bin/arch
進入 chroot 環境:
(device) # arch (chroot) #
搞定!
弄完了之后,可以換個快些的軟件源(例如 USTC 的),裝點亂七八糟的軟件(比如 gcc, make, cmake, vim, emacs, octave, maxima... ),滾一下系統……