前段时间偶然得到一部战损版一加6T,屏幕严重老化(怀疑是抖音水军使用)。
众所周知,一加手机对bootloader锁的限制非常宽松,于是我产生了对它爆改的想法。但是刷安卓感觉起来又有点无聊,遂尝试直接上Linux。

RVQFQJHR6$5%7B%7BTN1FT.png)
如果你手上刚好也有一台一加6T,可以点这里下载镜像刷着玩。初始密码为1234。
前置知识
安卓系统启动流程
- 上电当设备上电时,硬件会进行初始化。
- Bootloader硬件初始化、内存映射、加载内核、传递启动参数……
- Linux内核
- init进程启动
要使Bootloader引导Linux,主要就是要替换第3步和第4步。将安卓的Linux内核替换,最终唤起根文件系统中的init(systemd),从而进入Linux。
对于一加6T
Linux主线内核对部分设备有支持,而且PostMarketOS
(一款移动平台的Linux发行版)对一加6T有相当完善的支持,因此可以以此为基础,制作用于刷机的镜像。
制作boot镜像
环境准备
我这里使用amd64版Ubuntu进行交叉编译,因此需要事先准备交叉编译环境。可以参考:
sudo apt install build-essential openssl pkg-config libssl-dev libncurses5-dev pkg-config minizip libelf-dev flex bison libc6-dev libidn11-dev rsync bc liblz4-tool
sudo apt install gcc-aarch64-linux-gnu dpkg dpkg-dev git debhelper
后续制作rootfs所需环境:
sudo apt install arch-install-scripts qemu-user-static android-platform-system-core mkbootimg
编译内核
下载内核源码以及配置文件
从PostMarketOS的wiki站中,可以找到sdm845
(一加6T所使用的CPU)的主线支持,下载其中的Linux内核源码以及配置文件。
#内核源码
git clone --branch sdm845-6.16-rc2-4 --depth 1 https://gitlab.com/sdm845-mainline/linux.git
mv linux linux-sdm845-6.16-rc2-4
#配置文件
wget https://cloud.athbe.cn/f/D3Uq/sdm845.config
下载脚本对配置文件进行处理,使用处理后的配置进行编译才能生成所需要的格式。
wget https://cloud.athbe.cn/f/2MTG/check.sh
sudo chmod +x check.sh
./check.sh sdm845.config -w
mv sdm845.config linux-sdm845-6.16-rc2-4/.config #将处理结果覆盖默认配置
编辑配置。
cd linux-sdm845-6.16-rc2-4
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- menuconfig
找到Device Drivers > USB support > USB Gadget Support > USB Gadget precomposed configurations > Serial Gadget (with CDC ACM and CDC OBEX support)
将其设置为<*>
启用此选项后,可以实现当手机通过USB连接电脑,通过串行端口进入控制台。
退出menuconfig
,开始编译
编译内核
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)
这个过程可能会有点长,编译完成后,arch/arm64/boot
下会生成vmlinuz
,这是压缩后的内核,是我们所需的格式,捞出备用。
生成boot镜像
我们已经有了Linux内核,为了正常启动,还需要一个.dtb
设备树文件。可以直接从pmOS的boot镜像中提取。
这里直接使用我提取的设备树。
mkdir mkboot && cd mkboot
wget https://cloud.athbe.cn/f/WEhm/OnePlus6T.dtb
将编译生成的vmlinuz
复制到此目录。
cp ../linux-sdm845-6.16-rc2-4/arch/arm64/boot/vmlinuz .
将vmlinuz
和OnePlus6T.dtb
组合为一个文件,供后续使用。
cat vmlinuz OnePlus6T.dtb > kernel-dtb
Linux内核启动后,会首先唤起initrd
中的init
,因此我们还需要一个initrd
。
直接使用GitLab仓库中的生成工具。
git clone https://gitlab.com/sdm845-mainline/initrd.git
cd initrd
./build.sh
mv initrd.cpio.gz ..
cd ..
现在所需的文件已经准备完毕,但是还缺一些启动参数。可以通过解包pmOS的boot镜像获取。
下面通过解包得到的参数制作boot镜像
mkbootimg \
--base 0x00000000 \
--kernel_offset 0x00008000 \
--ramdisk_offset 0x01000000 \
--tags_offset 0x00000100 \
--pagesize 4096 \
--second_offset 0x00f00000 \
--ramdisk initrd.cpio.gz \
--cmdline "earlycon=tty0 earlyprintk root=/dev/sda17 rootfstype=ext4 rootwait=10 loglevel=3 debug rw splash" \
--kernel kernel-dtb \
-o boot.img
其中root
为根文件系统所处的分区,对于一加6T,一般为/dev/sda17
,其它设备可以通过blkid
查询分区的UUID作为参数。
命令执行完毕后,得到boot.img
,捞出备用。
制作rootfs
创建根文件系统
下载ubuntu-base
,可以下载任意版本,这里选择了25.04
。
wget https://cdimage.ubuntu.com/ubuntu-base/releases/25.04/release/ubuntu-base-25.04-base-arm64.tar.gz
生成磁盘镜像并格式化为ext4
,用于储存rootfs。
dd if=/dev/zero of=ubuntu.img bs=1G count=10 #分配了10G,实际上不需要这么多
mkfs.ext4 ubuntu.img
mkdir ubuntu
sudo mount ubuntu.img ubuntu
cd ubuntu
sudo tar -xpvf ../ubuntu-base-25.04-base-arm64.tar.gz
配置chroot环境
cd ..
sudo mount --bind /dev ubuntu/dev
sudo mount -t devpts devpts ubuntu/dev/pts -o gid=5,mode=620
sudo mount -t proc proc ubuntu/proc
sudo mount -t sysfs sysfs ubuntu/sys
sudo mount -t tmpfs tmpfs ubuntu/run
sudo rm -rf ubuntu/etc/resolv.conf && sudo cp /etc/resolv.conf ubuntu/etc/
sudo chroot ubuntu
基础系统配置
apt update
apt install ca-certificates dialog locales nano apt-utils -y
nano /etc/apt/sources.list #换为国内镜像源,加快下载速度
apt update
apt upgrade -y
#生成本地化
locale-gen en_US.UTF-8
locale-gen zh_CN.UTF-8
#设置设备名
echo 'OnePlus6T' > /etc/hostname
#安装必要软件包
apt install man-db sudo openssh-server net-tools network-manager iputils-ping bash-completion kmod busybox-initramfs cpio initramfs-tools initramfs-tools-bin initramfs-tools-core linux-base netplan.io git wget ntp systemd-resolved --no-install-recommends -y
exit
安装内核模块
sudo make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=~/ubuntu modules_install
sudo make ARCH=arm64 INSTALL_PATH=~/ubuntu/boot install
安装固件
这里我直接使用了从PostMarketOS的/lib/firmware
中获取的固件。
wget https://cloud.athbe.cn/f/6nSr/firmware.tar.gz
sudo tar -xzvf firmware.tar.gz
sudo mv firmware ubuntu/lib/
编辑配置
sudo chroot ubuntu
nano /usr/share/initramfs-tools/hooks/qcom-firmware
脚本内容
#!/bin/sh
set -e
PREREQS=""
case $1 in
prereqs) echo "${PREREQS}"; exit 0;;
esac
. /usr/share/initramfs-tools/hook-functions
add_firmware qcom/sdm845/oneplus6/a630_zap.mbn
add_firmware qcom/sdm845/oneplus6/ipa_fws.mbn
添加执行权限
chmod +x /usr/share/initramfs-tools/hooks/qcom-firmware
安装qrtr/rmtfs/pd-mapper/tqftpserv
https://cloud.athbe.cn/f/mJuG/qrtr%2Ctqftpserv%2Crmtfs%2Cpd-mapper.zip
下载解压所有deb文件到rootfs的/root
目录下。
cd ~
dpkg -i *.deb
apt --fix-broken install
systemctl enable qrtr-ns tqftpserv rmtfs pd-mapper
安装桌面环境
可以任选,这里我选了gnome。
apt install ubuntu-desktop -y
创建新用户
adduser athbe
usermod -aG sudo athbe
usermod -aG adm athbe
usermod -aG dialout athbe
usermod -aG cdrom athbe
usermod -aG floppy athbe
usermod -aG audio athbe
usermod -aG dip athbe
usermod -aG video athbe
usermod -aG plugdev athbe
激活声音
echo 'snd-soc-tfa98xx' > /etc/modules-load.d/snd-soc-tfa98xx.conf
cd
git clone https://gitlab.com/sdm845-mainline/alsa-ucm-conf.git -b op6-earpiece
cd /usr/share/alsa
rm -rf ucm*
cp -r ~/alsa-ucm-conf/ucm* .
rm -rf /root/alsa-ucm-conf
apt-mark hold alsa-ucm-conf
几个实用服务
串口控制台
下载脚本并复制到/usr/local/bin
wget https://cloud.athbe.cn/f/7BHR/ttygs0-console.sh
chmod +x ttygs0-console.sh
mv ttygs0-console.sh /usr/local/bin/
nano /etc/systemd/system/oneplus6t-console.service
编辑服务配置。
[Unit]
Description=OnePlus6T USB Console Service
After=syslog.target
After=systemd-modules-load.service
After=systemd-udevd.service
Wants=systemd-modules-load.service
Wants=systemd-udevd.service
[Service]
Type=simple
ExecStart=/usr/local/bin/ttygs0-console.sh
Restart=always
RestartSec=10
StandardOutput=syslog
StandardError=syslog
SyslogIdentifier=oneplus6t-console
[Install]
WantedBy=multi-user.target
防止关机崩溃
nano /etc/systemd/system/shutdown-modem.service
内容如下。
[Unit]
Description=Poweroff modem remoteproc to prevent wlan fw crash
DefaultDependencies=no
Before=shutdown.target
[Service]
Type=oneshot
# remoteproc2 is always the modem on SDM845
ExecStart=echo stop | tee /sys/class/remoteproc/remoteproc*/state
[Install]
WantedBy=shutdown.target
启动时分配MAC地址,以使蓝牙可用
git clone https://gitlab.postmarketos.org/postmarketOS/bootmac.git
cd bootmac
mv bootmac /usr/bin/
mv bootmac-bluetooth.service /etc/systemd/system/
启用服务
systemctl enable oneplus6t-console.service shutdown-modem.service bootmac-bluetooth.service
清理缓存并退出
cat /dev/null > ~/.bash_history && history -c
exit
生成镜像
sudo umount ubuntu/{run,sys,proc,dev/pts,dev} ubuntu
img2simg ubuntu.img rootfs.img
Comments NOTHING