第6阶段:完善GPU

目标

Y927 用的 GPU 是 Adreno 306(来自 MSM8916 SoC,Qualcomm A3xx 系列),主线 freedreno 驱动支持得很好。整体比 WiFi
简单一档——没有协处理器、没有 RF 校准。

之前dmesg里可以看到有

1
[0.505468] msm_mdp 1a01000.display-controller: no GPU device was found

本章将启用GPU驱动,让Y927能够识别到GPU设备,使该错误消失。

DTS 改动分析

1
2
3
&gpu {
status = "okay";
};

内核配置

1
2
3
4
cd ~/y927/linux
./scripts/config --enable DRM_MSM
./scripts/config --enable CONFIG_DRM_MSM_GPU_STATE
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- olddefconfig

编译 Linux 内核

1
2
cd ~/y927/linux
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc) Image.gz dtbs

GPU 固件

Adreno 306 需要两份微码固件:

文件 大小 作用
a300_pm4.fw 9220 字节 PM4 命令解析器微码
a300_pfp.fw 1156 字节 Prefetch Parser 微码

跟 WCNSS 不一样,这两个不是 RF 校准、不需要从手机自己提取——Qualcomm 已经 GPL 释放、收进 linux-firmware 主线,所有 Adreno 3xx 设备共用一份:

1
2
3
4
5
6
7
8
9
mkdir -p ~/y927/firmware-gpu && cd ~/y927/firmware-gpu

# 直接从 cgit 拉文件(推荐,4 KB+ 就两个文件)
curl -fO 'https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/qcom/a300_pm4.fw'
curl -fO 'https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git/plain/qcom/a300_pfp.fw'

# 验证大小
ls -la a300_pm4.fw a300_pfp.fw
# 期望:9220 / 1156 字节

制作initramfs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
BUSYBOX_BINARY=~/y927/busybox-1.38.0/busybox
EVTEST_BINARY=~/y927/evtest/src/evtest
PHASE_ID=6
cd ~/y927/initramfs
rm -rf phase-$PHASE_ID
mkdir -p phase-$PHASE_ID && cd phase-$PHASE_ID
INITRAMFS=~/y927/initramfs/phase-$PHASE_ID
FIRMWARE_GPU=~/y927/firmware-gpu

# 创建 initramfs 目录结构
mkdir -p bin dev proc sys lib/modules lib/firmware/qcom

# 复制 BusyBox 到 initramfs
cp $BUSYBOX_BINARY bin/
cp $EVTEST_BINARY bin/
cp $FIRMWARE_GPU/a300_pm4.fw $INITRAMFS/lib/firmware/qcom/
cp $FIRMWARE_GPU/a300_pfp.fw $INITRAMFS/lib/firmware/qcom/

# 创建基础命令的软链接
cd bin
for cmd in sh mount ls cat sleep exec echo; do
ln -sf busybox $cmd
done
cd ..

# 创建 /init 脚本
cat > init << 'EOF'
#!/bin/sh
mount -t proc proc /proc
mount -t sysfs sys /sys
mount -t devtmpfs dev /dev
echo "===== Phase 1: kernel booted! ====="
echo "Serial: $(cat /proc/cmdline)"
sleep 5
exec sh </dev/ttyGS0 >/dev/ttyGS0 2>&1
EOF
chmod +x init

# 打包
find . | cpio -o -H newc | gzip > ../initramfs-phase-$PHASE_ID.cpio.gz

构建 boot.img 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cd ~/y927/linux
PHASE_ID=6

# 拼接内核 + DTB
cat arch/arm64/boot/Image.gz \
arch/arm64/boot/dts/qcom/msm8916-vivo-y927.dtb \
> vmlinuz-dtb

~/y927/lk2nd/lk2nd/scripts/mkbootimg \
--kernel vmlinuz-dtb \
--ramdisk ~/y927/initramfs/initramfs-phase-$PHASE_ID.cpio.gz \
--cmdline "console=tty0 console=ttyMSM0,115200 panic=1 initcall_blacklist=simpledrm_platform_driver_init" \
--base 0x80000000 \
--kernel_offset 0x00008000 \
--ramdisk_offset 0x01000000 \
--second_offset 0x00f00000 \
--tags_offset 0x00000100 \
--pagesize 2048 \
--header_version 0 \
--output boot-phase-$PHASE_ID.img

刷入 boot.img 文件

1
2
3
PHASE_ID=6
fastboot flash boot boot-phase-$PHASE_ID.img
fastboot reboot

测试

查看dmesg可以看到,dmesg 把整条链路都给你串起来了:

1
2
3
4
5
6
7
[0.184758] platform 1c00000.gpu: Adding to iommu group 0          ← GPU 平台设备出现
[0.472922] adreno 1c00000.gpu: supply vdd not found, using dummy regulator
[0.473105] adreno 1c00000.gpu: supply vddcx not found, using dummy regulator
[0.476582] msm_mdp 1a01000.display-controller: bound 1c00000.gpu ← GPU 跟 MDP 绑定
[0.519229] [drm] Initialized msm 1.13.0 ... on minor 0 ← DRM 完成初始化
[0.519932] [drm:adreno_request_fw] loaded qcom/a300_pm4.fw ← PM4 微码加载
[0.520223] [drm:adreno_request_fw] loaded qcom/a300_pfp.fw ← PFP 微码加载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
busybox ls /dev/dri/
# 期望: card0 renderD128

busybox ls /sys/class/devfreq/
# 期望多一项: 1c00000.gpu

busybox cat /sys/class/devfreq/1c00000.gpu/cur_freq
# 期望: 50000000 (50 MHz, 空闲)

busybox cat /sys/class/devfreq/1c00000.gpu/available_frequencies
# 期望: 19200000 400000000 (Hz)

# 看 IOMMU 分组
busybox ls /sys/kernel/iommu_groups/
# 期望至少有 0 / 1

busybox ls /sys/kernel/iommu_groups/0/devices/
# 期望: 1c00000.gpu