Past Phone + Present Power: Redmi 2 with Kernel 6.8 & Debian 13

红米 2

一台 2015 年初发布的手机，售价 699 元，2024 年居然还没有被遗忘？

硬实力上，红米 2 在当时就不突出。它是闻泰科技 ODM 的产品，从设计到制造都由闻泰完成，配备高通骁龙 410 SoC (MSM8916) ，1GB 运行内存，8GB 存储，4.7 寸 720P 屏幕 (312 ppi) 。MSM8916 采用 28 nm 工艺，CPU 为 4 核 1.2 GHz ARM Cortex-A53，上市之初定位便是中低端，与 2023 年的骁龙旗舰相比性能就只有可怜的 1/10 不到了。作为手机，红米 2 在 2024 年早已没有实用价值，大量红米 2 在闲鱼上的售价仅在 50-100 元之间。

软实力它却很强。红米 2 有非常丰富的第三方 Android 刷机包，出厂搭载 Android 4.4 的它能刷到 Android 10 的 Lineage OS 17.1 (Kernel Version 3.10) 。当它的性能已经不足以支撑在 Android 中多做什么时，它还可以运行接近最新主线的 Linux Kernel 和 Debian, Ubuntu 等正儿八经的 Linux 发行版。可能是得益于高通官方基于 MSM8916 推出了支持 Ubuntu Linux 的 DragonBoard 410c 开发板，也得益于后续开源社区和组织的努力，MSM8916 的主线内核功能已经比较完善，UART、USB、Storage (eMMC/SD card) 、WiFi/Bluetooth、GPU、Display (需要 panel 驱动)、Audio、Buttons、Vibration、Modem (SMS, voice calls with audio, mobile data) 等都得到了支持。

有了完善的 Linux 支持之后，红米 2 作为一个嵌入式 Linux 开发平台瞬间焕发新生。如果应用于只需要极少的 IO，不需要丰富的总线接口，需要利用 USB、 无线通信，甚至还恰好比较需要屏幕交互的场景，相比购买树莓派、香橙派等 Linux 开发板，手机运行 Linux 方案变得性价比极高。因此可以看到红米 2 仍具有很强的生命力，B 站上拿红米 2 做 Klipper 3D 打印上位机的案例非常丰富。同为 MSM8916 SoC 的一些低价随身 WiFi 也纷纷被装上 Linux 做小服务器。

制作过程

调试

没有 console log 将是调试的噩梦，能通过串口看 bootloader 和 kernel 的输出非常要紧，否则在屏幕没有成功点亮前就成了黑箱，没有排查空间。而红米 2 有完整的点位图和原理图可看，甚至预留了串口 TP，调试便完全不成问题了。

lk2nd

lk2nd 是为高通 SoC 开发的基于 Little Kernel 的二级引导程序，可以方便地引导 Linux 启动。而它本身伪装成了 Android 的 boot.img 文件，使得不必改动设备原本 bootloader 就能启动。lk2nd 提供了 fastboot 兼容，可以在电脑用 fastboot 命令实现方便的分区烧写。并且和 u-boot 类似，起到 “兜底” 的作用，不用担心烧进坏的镜像就彻底变砖。

项目地址：msm8916-mainline/lk2nd: Custom bootloader for Qualcomm MSM8916/MSM8226/MSM8974/... devices (github.com)

我们直接利用 Release 的 0.15.0 版本 lk2nd-msm8916.img 在原厂 fastboot 中通过以下命令刷入 lk2nd，开机时亮屏后按音量下键可以进入 lk2nd 的 fastboot。

Copy
fastboot flash:raw boot lk2nd-msm8916.img

运行 lk2nd 后，烧写便可以使用下面的命令：

Copy
fastboot flash boot boot.img
fastboot flash userdata rootfs.img

内核

从 msm8916-mainline/linux 获取内核，直接编译即可

Copy
export CROSS_COMPILE=aarch64-linux-gnu-
export ARCH=arm64
make msm8916_defconfig
make menuconfig
make -j8
make deb-pkg

编译完成后会生成 3 部分的文件：

arch/arm64/boot/Image.gz 压缩后的内核映像

arch/arm64/boot/dts/qcom/msm8916-wingtech-wt88047.dtb 设备树 dtb，后续需要附在内核映像后

../linux-headers-6.7.4-msm8916-dirty_6.7.4-6_arm64.deb 和 ../linux-image-6.7.4-msm8916-dirty_6.7.4-6_arm64.deb 内核头文件和内核的 deb 包，后续需要在根文件系统中安装

将设备树 dtb，附在内核映像后

Copy
cat Image.gz msm8916-wingtech-wt88047.dtb > kernel-dtb

Debian rootfs

首先尝试利用 debootstrap 创建一个 debian 的根文件系统。由于制作所用主机为 amd64 架构，而目标设备为 arm64 架构，需要利用 debootstrap 的 —foreign 选项，并准备 qemu-aarch64-static 用于模拟 arm64 指令集。

Copy
apt-get install debootstrap qemu-user-static binfmt-support
debootstrap --arch arm64 --foreign bookworm rootfs http://mirrors.tuna.tsinghua.edu.cn/debian
cp -a /usr/bin/qemu-aarch64-static rootfs/usr/bin/qemu-aarch64-static

然后 chroot 进入刚刚制作的根文件系统，完成 debootstrap 的第二阶段、安装 kernel-image 和 kernel-header，并自由定制自己的根文件系统

Copy
mount --bind /dev rootfs/dev
mount --bind /dev/pts rootfs/dev/pts
mount --bind /proc rootfs/proc
chroot rootfs bash

/debootstrap/debootstrap --second-stage
dpkg-reconfigure locales
dpkg -i *.deb #事先拷进来的linux-headers和linux-image
apt update
apt install usbutils network-manager sudo fdisk vim nano openssh-server iputils-ping wget curl iproute2 dialog locales kmod zip unzip u-boot-tools initramfs-tools net-tools htop screenfetch phosh
adduser debian
exit

在安装新 Linux 内核包时，包管理器会调用 update-initramfs 来生成与新内核匹配的 initrd.img 文件，initrd 包含一个临时的根文件系统，运行在内存中负责初始化系统并切换到最终的根文件系统。我们需要拷贝位于 /boot 目录下的 initrd.img-xxx 文件制作进 boot.img 中。

打包 rootfs.img

Copy
umount rootfs/dev/pts
umount rootfs/dev
umount rootfs/proc
dd if=/dev/zero of=rootfs.ext4 bs=1M count=4096
mkfs.ext4 rootfs.ext4
mkdir /mnt/rootfs_dd
mount rootfs.ext4 /mnt/rootfs_dd
cp -a rootfs/. /mnt/rootfs_dd/
sync
umount /mnt/rootfs_dd/
img2simg rootfs.ext4 rootfs.img # convert to sparse image

打包 boot.img。在 kernel cmdline 中，通过 UUID 指定 rootfs 分区较为保险，UUID 可以通过file mkfs.ext4命令查看

Copy
mkbootimg --base 0x80000000 \
--kernel_offset 0x00080000 \
--ramdisk_offset 0x02000000 \
--tags_offset 0x01e00000 \
--pagesize 2048 \
--second_offset 0x00f00000 \
--ramdisk initrd.img \
--cmdline "earlycon console=tty0 console=ttyMSM0,115200 root=UUID=b0167571-46ab-432c-9923-46772affcb75 rw loglevel=7"\
--kernel kernel-dtb -o boot.img

Mobian rootfs

自制的 debian rootfs 可以启动，但图形界面中缺少的东西实在太多，因此转向修改其他机型的 mobian rootfs。mobian 官网下载目前前最新的镜像，得到 mobian-qcom-phosh-20240211.rootfs.img，主要安装上 linux-headers 和 linux-image 即可。

Copy
simg2img mobian-qcom-phosh-20240211.rootfs.img mobian-rootfs.img
mount mobian-rootfs.img /mnt/rootfs_dd/
sudo mount --bind /proc /mnt/rootfs_dd/proc
sudo mount --bind /dev /mnt/rootfs_dd/dev
sudo mount --bind /dev/pts /mnt/rootfs_dd/dev/pts
sudo mount --bind /sys /mnt/rootfs_dd/sys
cp linux-headers-6.7.4-msm8916-dirty_6.7.4-6_arm64.deb /mnt/rootfs_dd/tmp/
cp linux-image-6.7.4-msm8916-dirty_6.7.4-6_arm64.deb /mnt/rootfs_dd/tmp/
sudo chroot /mnt/rootfs_dd/
dpkg-reconfigure locales
apt remove qcom-support
dpkg -l | grep -E "linux-headers|linux-image" |awk '{print $2}'|xargs dpkg -P
cd /tmp
dpkg -i *.deb
exit

同样的流程打包 rootfs.img 和 boot.img，烧录即可。

启动后会发现无线不工作，还有屏幕不显示 GUI 但有终端显示的问题。究其原因是缺少了私有的 firmware， 这个部分也容易解决，从其他同机型 rootfs 镜像中直接拷贝即可。GPU Firmware 文件为 a300_pm4.fw 和 a300_pfp.fw, 无线部分有一系列 .mbn 文件和 .bxx 文件。启动后，网络和 GUI 也得以工作。

真正的主线

msm8916-mainline/linux 这份内核虽然很接近主线，却还不是真正的主线内核 torvalds/linux, 有很多没有合并到主线的修改，版本也略有落后。那么 torvalds/linux 能否跑起来呢，有问题的话能否自行解决修复呢。

通过 git 镜像获取，并安装一些必要的包

Copy
git clone https://mirrors.tuna.tsinghua.edu.cn/git/linux-stable.git
git checkout v6.8.0
apt update
apt install -y gcc make gcc-aarch64-linux-gnu binutils-aarch64-linux-gnu libncurses5-dev build-essential pkg-config libc6-dev bison flex libelf-dev lz4 qemu-user-static bc libssl-dev debhelper

主线的内核有 wt88047 的设备树，首先尝试根据msm8916-mainline/linux项目的 msm8916_defconfig 配置内核，编译出一份内核，尝试启动，发现串口能够进入终端，但是屏幕没有正常显示。通过对比 msm8916-mainline/linux 与同版本的 torvalds/linux 之间差距，除了大量的设备树 dts 文件添加与修改，还主要包含了：

显示面板驱动 drm/panel 添加与修改

drm 和 dsi 部分关于启用禁用逻辑的调整

touchscreen, pmic 等外围设备的驱动添加

高通 SoC 外设驱动和配置调整，包括 qdsp6, memshare, cpuidle 等

着重添加好面板驱动和显示部分的逻辑，编译内核，用此内核启动后便可以正常看到 phosh 界面了。

总结

在前人的努力下，在红米 2 上跑起一个比较新的 Linux 系统变得异常轻松，离主线非常近，一切驱动、设备树、config 都已经就绪，只要编译就行，甚至连报错都不带报的。

手机 SoC 的快速迭代实在让人感叹，手机芯片性能已经远甩开嵌入式 Linux 开发中常用的芯片。一个 RK3399 就传了多少年，才有了 RK3588，另外即使是最新的树莓派性能也差强人意，对比一下飞速进步的手机芯片，仿佛不在一个世界。开源的力量也令人倾佩，手机厂商对于手机系统的更新精力有限，老机型没有新机型更新积极几乎必然。更别提支持周期结束之后，不负优化、计划报废就不错了。这在商业上无可厚非。但这也使得手机即使性能硬实力没有太落后，也很难不提早迎来生命的终结。而开源和社区的力量似乎提供了一条让手机发挥更大价值的道路，就如红米 2、一加 6T 等至今依然活跃的老机型，不仅作为手机的生命周期得到延长，甚至还开拓了更加广阔的应用场景，这何尝不是一种更高级的 “环保” 呢。好兆头是，以往芯片公司们常常将资料藏着掖着，而似乎一些公司已在开源方面有了一些动作，骁龙 845、865 等处理器都有了较好的主线内核支持，FOSDEM 2024 中也提到 Linaro 对于高通新旗舰芯片主线支持得越来越快，开放的美好未来似乎就在眼前。

参考资料

Qualcomm Snapdragon 410/412 (MSM8916) - postmarketOS

DragonBoard 410c - Qualcomm Developer Network

自己 DIY 一个 pinephone——debian 与主线 linux 在红米 2（msm8916）上的移植_红米 2 arm linux-CSDN 博客

自己 DIY 一个 pinephone——debian 与主线 linux 在红米 2（msm8916）上的移植 (二)-CSDN 博客

debootstrap 制作 arm64 位根文件系统 - 掘金 (juejin.cn)

debootstrap 制作根文件系统_debootstrap 嵌入式 - CSDN 博客

随身 wifi 的 Debian 系统固件编译 (knightli.com)

编译内核（debian）・OpenStick 项目・看云 (kancloud.cn)

打造最便宜的骁龙 625Linux 手机 —— 红米 4 移植主线 Linux Mobian Kali Ubuntu_哔哩哔哩_bilibili

ITOP4412---- 尝试使用 debootstrap 构建文件系统。 - 代码先锋网 (codeleading.com)

Project-DragonPi/mobian-wt88047: A unoffical release of mobian.Include a lots of stuff from project dragonpi. (github.com)

记一个老年机的逆向工程与主线 linux 移植 （一）—— 信息收集与 Bootloader 移植_msm8909 lk2nd-CSDN 博客