基于Halium 9为小米平板4移植Ubuntu Touch:内核适配与驱动调试实战
1. 项目概述与动机
折腾老旧安卓设备,给它们刷上各种第三方ROM,是很多搞机爱好者的日常。但不知道你有没有想过,能不能在这些基于安卓内核的设备上,运行一个完全不同的操作系统,比如一个真正的Linux桌面发行版?这听起来像是天方夜谭,但Halium项目让这件事成为了可能。Halium本质上是一个中间层,它把安卓内核的硬件支持能力“翻译”成标准Linux发行版能听懂的语言,从而让我们可以在手机、平板上安装Ubuntu Touch、postmarketOS这类移动Linux系统。
我手头有一台闲置已久的小米平板4,骁龙660的芯片,3GB内存,放在今天性能确实落伍了,但硬件本身并不过时。让它继续吃灰太可惜,刷个LineageOS似乎也缺乏新意。于是,我决定拿它来“尝鲜”Halium 9,目标是为它移植一个能基本运行的Ubuntu Touch基础系统。这不仅仅是为了“点亮屏幕”,更是一个深入理解安卓硬件抽象层(HAL)、Linux内核驱动以及系统启动流程的绝佳实践。整个过程充满了挑战,从内核配置、设备树编译,到解决显示屏、触摸、Wi-Fi等硬件的驱动问题,每一步都需要大量的调试和试错。这个系列文章,就是我记录这次移植过程的详细笔记,希望能为同样想折腾的朋友提供一份切实可行的参考。
2. 核心思路与准备工作
2.1 Halium 9 与项目选型解析
Halium项目目前有几个主要版本分支,其中Halium 9基于Android 9.0(Pie)的底层。选择Halium 9而不是更新的版本,主要出于稳定性和社区支持的考虑。对于小米平板4(代号clover)这类发布于2018年的设备,其官方内核源码和供应商驱动(Vendor Blobs)大多围绕Android 8.1/9.0开发,与Halium 9的兼容性理论上最好。社区里针对clover的LineageOS 16.1(基于Android 9.0)移植已经相当成熟,这为我们提供了至关重要的内核源码基础和硬件配置参考。
我们的核心思路是“站在巨人的肩膀上”。具体来说,分为以下几个步骤:
- 基础确定:使用小米官方开源的内核源码,或者更常见的,使用
clover设备上经过社区充分测试的LineageOS 16.1内核源码作为起点。这个内核已经包含了针对骁龙660(MSM8953)平台和clover特定硬件的所有驱动和配置。 - Halium化改造:这不是简单地编译内核,而是需要对内核进行一系列修改和打补丁,使其满足Halium运行环境的要求。例如,需要启用特定的内核配置选项、修改初始化进程(init)的启动逻辑、调整文件系统挂载点等。
- 构建系统集成:我们需要一套构建系统来组织内核、Halium中间层、硬件适配层(hybris)和根文件系统。这里通常选择基于Debian/Ubuntu的
rootfs,并通过debootstrap来构建。 - 硬件启用:这是最耗时的一环。即使内核启动了,显示屏、触摸屏、音频、Wi-Fi、蓝牙、传感器等都可能无法工作。我们需要逐一调试,通过分析内核日志(dmesg)、检查设备节点、甚至修改设备树(Device Tree)或驱动源码来解决问题。
2.2 环境搭建与工具链准备
工欲善其事,必先利其器。一个稳定、高效的编译环境是成功的第一步。我强烈推荐使用一台运行Ubuntu 20.04 LTS或22.04 LTS的物理机或配置充足的虚拟机(至少分配8核CPU、16GB内存和200GB SSD空间)。在Windows下通过WSL2进行编译理论上可行,但在处理大型源码和复杂的依赖时,可能会遇到文件系统性能或兼容性问题,增加不必要的调试成本。
首先,安装所有必需的软件包:
sudo apt update sudo apt install -y git-core gnupg flex bison build-essential zip curl zlib1g-dev \ gcc-multilib g++-multilib libc6-dev-i386 libncurses5 lib32ncurses5-dev \ x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev libxml2-utils \ xsltproc unzip fontconfig python3 android-tools-adb bc imagemagick ccache \ schedtool squashfs-tools pngquant rsync schedtool libssl-dev libelf-dev \ patchelf binutils-multiarch vboot-utils vboot-kernel-utils lz4接下来是获取源码。我们需要三块主要的代码:
- 内核源码:从LineageOS的Git仓库获取为
clover适配的内核。
git clone https://github.com/LineageOS/android_kernel_xiaomi_clover -b lineage-16.1 kernel/xiaomi/clover- Halium 9 移植脚本与配置:Halium项目提供了用于构建的
halium-boot和halium-install等工具。
git clone https://github.com/Halium/android -b halium-9.0 halium- 设备树(Device Tree)和硬件配置:这部分通常包含在设备的
device/仓库中,定义了硬件的物理连接和资源分配。对于clover,我们需要找到或自己整理一份。
# 这是一个示例,实际路径可能需要根据社区现有工作调整 git clone https://github.com/your-username/device_xiaomi_clover_halium -b halium-9 device/xiaomi/clover注意:编译内核需要对应的交叉编译工具链。对于高通骁龙平台,通常使用AOSP预编译的GCC工具链。我们需要根据内核源码中
build.config文件的指示,下载正确版本的工具链,并设置好环境变量(如CROSS_COMPILE)。
3. 内核配置与Halium补丁应用
3.1 内核源码的初步配置
进入内核源码目录后,第一步是获取当前设备的默认配置。对于高通平台设备,这通常由一个defconfig文件定义。
cd kernel/xiaomi/clover export ARCH=arm64 export SUBARCH=arm64 # 使用 clover 的默认配置 make clover_defconfig执行make menuconfig进入内核配置界面。这里是我们需要根据Halium要求进行修改的关键步骤。Halium运行一个完整的GNU/Linux用户空间,因此需要内核提供比标准安卓内核更丰富的特性支持。以下是一些必须检查或启用的选项(路径可能因内核版本略有不同):
- General setup -> Control Group support:必须启用,且需要开启
Cpuset support、CPU controller、Memory controller等,这是系统资源管理的基础。 - Device Drivers -> Character devices -> /dev/mem virtual device support:建议启用,某些调试工具可能需要。
- Device Drivers -> Generic Driver Options -> Maintain a devtmpfs filesystem:必须启用,并勾选
Automount devtmpfs at boot。 - File systems -> The Extended 4 (ext4) filesystem:确保支持,这是根文件系统常用的格式。
- File systems -> FUSE (Filesystem in Userspace) support:启用,某些用户空间文件系统会用到。
- Networking support -> Networking options -> Unix domain sockets和TCP/IP networking:必须启用。
- Security options -> Different security models和Enable different security models:如果使用AppArmor等安全模块,需要相应配置。
修改完成后,保存配置为.config文件。
3.2 应用Halium特定补丁
纯安卓内核无法直接启动Halium系统,因为两者的初始化流程和所需服务不同。Halium社区提供了一系列内核补丁,主要解决以下问题:
- init进程替换:安卓使用
init来启动zygote和服务。Halium需要内核最终跳转到标准的/sbin/init(通常是systemd或sysvinit)。 - 文件系统挂载:修改根文件系统、
/system、/vendor等分区的挂载逻辑,使其符合Linux发行版的期望。 - SELinux调整:在启动初期禁用或调整SELinux策略,避免其阻止Halium服务的启动。
- Hybris兼容性:一些补丁用于改善
libhybris(一个允许GNU/Linux程序使用安卓驱动库的兼容层)的运行环境。
应用补丁需要格外小心。通常,Halium的android/仓库下会有针对不同内核版本的补丁集。我们需要找到与clover内核版本(如4.4.x)匹配的补丁。应用命令如下:
# 假设补丁文件在 halium/patches/kernel/4.4/ 目录下 for patch in /path/to/halium/patches/kernel/4.4/*.patch; do patch -p1 < $patch done实操心得:应用补丁时很可能遇到失败(
Hunk FAILED)。这通常是因为我们的内核源码与补丁所基于的版本有细微差异。此时需要手动合并(git apply --reject),然后仔细检查.rej文件,根据上下文手动修改代码。这是移植过程中最考验耐心和代码阅读能力的环节之一。建议每成功应用一个补丁就git commit一次,方便回溯。
4. 构建启动镜像与系统根文件
4.1 编译内核与生成DTB
配置和补丁都完成后,就可以开始编译内核了。我们使用之前设置好的交叉编译工具链。
export CROSS_COMPILE=aarch64-linux-android- export PATH=/path/to/your/toolchain/bin:$PATH make -j$(nproc) Image.gz-dtb-j$(nproc)表示使用所有CPU核心并行编译以加快速度。编译成功后,会在arch/arm64/boot/目录下生成Image.gz-dtb文件。这个文件包含了压缩的内核镜像(Image)和编译好的设备树二进制文件(DTB),是启动系统的核心。
对于小米平板4这类高通平台设备,通常不是使用单一的DTB文件,而是使用dtbo(设备树叠加层)或打包成dtb.img。我们需要确认clover的启动引导程序(bootloader)期望的格式。根据LineageOS的编译脚本,它很可能需要生成一个dtb.img。我们可以使用mkdtboimg工具来制作:
# 首先,编译出所有的 .dtb 文件 make -j$(nproc) dtbs # 然后,使用 mkdtboimg 打包 (工具可能需要从AOSP源码中获取) mkdtboimg create dtb.img arch/arm64/boot/dts/qcom/*.dtb4.2 制作Halium根文件系统与启动镜像
仅有内核还无法启动,我们需要一个根文件系统(rootfs)。对于Ubuntu Touch,我们可以使用Ubuntu Base来构建一个最小的文件系统。
sudo debootstrap --arch=arm64 --variant=minbase focal ./rootfs http://ports.ubuntu.com/ubuntu-ports这里我们为64位ARM架构构建了一个基于Ubuntu 20.04 (Focal)的最小系统。构建完成后,需要chroot进入这个rootfs,安装Halium运行所需的核心包,如systemd、ofono(电话相关)、pulseaudio(音频)、network-manager等,以及hybris相关的库。
接下来,我们需要将内核、dtb.img和rootfs打包成一个可以被安卓bootloader识别的启动镜像(boot.img)。这需要使用mkbootimg工具。我们需要创建一个boot.img的配置文件,例如bootimg.cfg:
pagesize = 4096 base = 0x80000000 kernel_offset = 0x00008000 ramdisk_offset = 0x01000000 second_offset = 0x00f00000 tags_offset = 0x00000100 board = cmdline = androidboot.hardware=qcom androidboot.console=ttyMSM0 androidboot.memcg=1 lpm_levels.sleep_disabled=1 video=vfb:640x400,bpp=32,memsize=3072000 msm_rtb.filter=0x237 ehci-hcd.park=3 service_locator.enable=1 androidboot.bootdevice=7824900.sdhci earlycon=msm_serial_dm,0x78af000 firmware_class.path=/vendor/firmware_mnt/image loop.max_part=7 androidboot.usbconfigfs=true androidboot.selinux=permissive其中,cmdline(内核命令行参数)至关重要。它需要传递正确的硬件信息、控制台设置、以及**androidboot.selinux=permissive**这一条。在Halium启动初期,将SELinux设置为宽容模式可以避免大量权限错误,是调试阶段的必备选项。
然后,将rootfs制作成cpio格式的initrd(初始内存磁盘):
cd rootfs find . | cpio -o -H newc | gzip > ../initrd.img cd ..最后,使用mkbootimg打包:
mkbootimg --kernel arch/arm64/boot/Image.gz-dtb --ramdisk initrd.img --pagesize 4096 --base 0x80000000 --kernel_offset 0x00008000 --ramdisk_offset 0x01000000 --tags_offset 0x00000100 --cmdline "$(cat cmdline)" -o boot.img至此,我们得到了一个关键的boot.img文件。
5. 刷入设备与首次启动调试
5.1 刷机准备与引导
小米平板4需要解锁Bootloader才能刷入自定义镜像。解锁过程需要通过小米官方申请,此处不再赘述。解锁后,设备进入fastboot模式(关机状态下按住音量减 + 电源键)。
刷入我们自制的boot.img:
fastboot flash boot boot.img刷入后,执行fastboot reboot。此刻心情是最紧张的,你将看到小米的Logo,然后……很可能是一片黑屏,或者卡在Logo处。别担心,这完全正常。首次启动失败是移植的“标配”。
5.2 内核日志获取与分析
调试的黄金钥匙是内核日志。我们需要通过串口(UART)或者安卓的adb来获取。幸运的是,大部分现代安卓设备在内核中启用了CONFIG_ANDROID_BINDER_IPC和CONFIG_ANDROID_LOGGER,即使系统未能完全启动,只要内核还在运行,就有可能通过adb连接到adbd(安卓调试守护进程)来获取日志。
在设备黑屏时,尝试用USB连接电脑,并执行:
adb logcat -b kernel如果能看到滚动的内核日志,那恭喜你,调试的大门已经打开。如果adb没反应,那么串口调试是必须的。这需要拆机并焊接出UART引脚(TX, RX, GND),连接到USB转TTL模块,在电脑上用串口终端软件(如picocom,minicom)查看输出。对于小米平板4,串口引脚的位置通常可以在XDA开发者论坛或相关拆解图中找到。
分析内核日志是解决问题的核心。你需要关注以下几个关键点:
- 启动到哪一步卡住了?最后几条日志是什么?是触发了
panic还是停在了某个驱动的probe函数? - 设备树(DTB)加载是否正确?查找
OF:(Open Firmware,即设备树)相关的日志,看是否成功找到了compatible为"xiaomi,clover"的节点。 - 关键驱动是否加载?查看
msm_drm(显示驱动)、i2c(触摸屏、传感器通常通过I2C连接)、wcnss(Wi-Fi/BT)、snd_soc_msm(音频)等驱动是否成功初始化。 - 文件系统挂载是否成功?查找
mount、initrd、switch_root等关键词。如果根文件系统挂载失败,系统自然无法启动。
5.3 常见启动问题与排查实录
以下是我在小米平板4上遇到的一些典型问题及解决思路,整理成排查表:
| 现象 | 可能原因 | 排查与解决思路 |
|---|---|---|
| 卡在小米Logo,无任何日志 | 1. 内核镜像损坏或格式错误。 2. 设备树(DTB)未正确打包或设备不识别。 3. 内核命令行参数(cmdline)错误,特别是内存地址相关参数。 | 1. 检查mkbootimg命令参数是否正确,特别是--base和偏移量。与LineageOS的boot.img对比。2. 确认使用的 dtb文件是否针对clover。尝试用dtc工具反编译dtb.img,检查内容。3. 对照原厂内核或LineageOS内核的 cmdline进行修正。可尝试从正常启动的系统中提取:cat /proc/cmdline。 |
| 内核panic,错误与MMU或内存相关 | 内核配置中内存管理相关选项与硬件不匹配,或内核地址空间布局错误。 | 检查内核配置CONFIG_ARM64_VA_BITS、CONFIG_ARM64_PAGE_SHIFT等。确保与芯片架构(如Cortex-A73/A53)和平台(MSM8953)一致。参考原版内核配置。 |
| 显示驱动初始化失败,屏幕黑屏但有日志 | 1. DRM驱动(msm_drm) probe失败。2. 显示面板的电源序列或复位GPIO配置错误(在设备树中)。 3. 背光驱动未加载。 | 1. 查看内核日志中msm_drmprobe的详细错误,常与时钟(clk)、电源(regulator)、GPIO有关。2. 仔细核对设备树中 dsi_panel节点的配置,包括qcom,mdss-dsi-*系列属性,与原厂驱动或Panel数据手册对比。3. 检查背光( backlight)节点是否正确定义并关联到Panel。 |
| 触摸屏完全无响应 | 1. I2C总线通信失败。 2. 触摸IC驱动未加载或probe失败。 3. 设备树中触摸屏节点 compatible不匹配或中断(IRQ)配置错误。 | 1. 使用i2cdetect工具(需编译进内核)查看I2C总线上是否有设备响应。2. 确认触摸IC型号(如 fts_ts),确保对应驱动(drivers/input/touchscreen/)已编译进内核。3. 核对设备树中 i2c节点下的触摸屏子节点,检查reg(地址)、interrupt-parent和interrupts属性。 |
| Wi-Fi无法打开 | 1.wcnss(无线协处理器)固件加载失败。2. prontoPCIe驱动初始化问题。3. 缺少正确的Wi-Fi校准数据( calibration文件)。 | 1. 检查内核日志中wcnss相关的错误,确保/vendor/firmware目录下有正确的固件(如wlan/prima/WCNSS_qcom_cfg.ini等)。2. 确认设备树中 wcnss节点的状态(status = "okay")。3. 从原厂ROM或可工作的LineageOS系统中提取 /persist分区下的Wi-Fi校准文件(如/persist/WCNSS_qcom_wlan_nv.bin),并放入根文件系统的对应位置。 |
| adb可以连接,但无法获取shell或系统卡住 | init进程启动失败。可能是根文件系统内的/sbin/init(或/init)不存在、没有执行权限,或者它依赖的库在rootfs中缺失。 | 1. 在rootfs中检查/sbin/init的链接和权限。2. 使用 chroot进入rootfs,用ldd /sbin/init检查动态链接库是否齐全。3. 查看 adb logcat中init的日志,看是否在切换根文件系统(switch_root)后报错。 |
6. 硬件驱动的深度适配与调试
6.1 显示屏与背光调试实战
让屏幕亮起来是移植成功的第一个视觉标志。小米平板4采用了一块8英寸的LCD屏幕,驱动涉及msm_drm(内核显示框架)、MIPI DSI控制器和具体的面板驱动。
首先,确保内核配置启用了所有必要选项:
CONFIG_DRM=y CONFIG_DRM_MSM=y CONFIG_DRM_MSM_DSI=y CONFIG_DRM_PANEL_SIMPLE=y (或具体的面板驱动,如 CONFIG_DRM_PANEL_XIAOMI_CLOVER) CONFIG_BACKLIGHT_CLASS_DEVICE=y CONFIG_BACKLIGHT_GENERIC=y (或 CONFIG_BACKLIGHT_LM3630A 等具体芯片驱动)关键中的关键,是设备树(DTB)中关于显示部分的配置。这通常定义在arch/arm64/boot/dts/qcom/msm8953-xiaomi-clover.dtsi这样的文件中。你需要找到一个名为dsi_panel的节点,它描述了面板的时序参数。一个典型的配置片段如下:
&dsi0 { status = "okay"; #address-cells = <1>; #size-cells = <0>; panel@0 { compatible = "xiaomi,clover-panel"; // 必须与驱动匹配 reg = <0>; vddio-supply = <&pm8953_l6>; // IO电压 vddpos-supply = <&lab_regulator>; // 正电压 vddneg-supply = <&ibb_regulator>; // 负电压 backlight = <&pmi8950_wled>; // 关联背光 ports { port { panel_in: endpoint { remote-endpoint = <&dsi0_out>; }; }; }; }; };如果屏幕不亮,首先用万用表或通过内核GPIO调试接口,检查面板的电源(vddio,vddpos,vddneg)是否已经按序列上电。然后检查背光(backlight)节点是否被正确引用,背光驱动是否成功probe。可以在内核命令行中添加drivers.debug=7来获得更详细的驱动加载日志。
6.2 触摸屏与传感器适配
触摸屏通常通过I2C总线连接。首先使用i2cdetect工具扫描总线,确认触摸IC的地址能被识别。如果识别不到,检查设备树中该I2C控制器的status是否为"okay",以及触摸屏子节点的reg地址是否正确。
触摸屏驱动probe成功后,会在/dev/input/下生成eventX设备节点。在Halium的根文件系统里,需要确保有udev规则或相应的服务(如ofono或qt5-feedback)来正确识别并设置这个输入设备。有时,触摸坐标可能不准确或方向不对,这需要在用户空间进行校准或通过内核驱动传递正确的转换矩阵(通过设备树的touchscreen-size-x/y,touchscreen-inverted-x/y等属性)。
对于加速度计、陀螺仪、光线距离传感器等,调试流程类似:确认I2C/SPI通信 -> 检查驱动probe -> 验证/sys/bus/iio/devices/下是否出现相应节点 -> 在用户空间测试数据读取。
6.3 Wi-Fi与蓝牙的固件之困
高通平台的Wi-Fi和蓝牙通常由独立的协处理器(如WCNSS)处理,内核驱动主要负责PCIe/SDIO通信和固件加载。Wi-Fi无法工作的最常见原因是固件缺失或错误。
固件提取:从一个能正常开机(如原厂系统或LineageOS)的小米平板4中,提取以下关键文件:
/vendor/firmware/wlan/prima/下的所有文件(如WCNSS_qcom_cfg.ini,WCNSS_wlan_dictionary.dat等)。/persist/分区下的WCNSS_qcom_wlan_nv.bin。这个文件包含设备的唯一校准数据,至关重要。- 蓝牙固件可能位于
/vendor/firmware/或/lib/firmware/下,如BCM.hcd(如果是博通芯片)。
固件放置:将这些文件放入Halium根文件系统的对应路径。通常,Linux系统将固件放在
/lib/firmware/下。你需要创建对应的子目录,例如/lib/firmware/wlan/prima/,并将文件复制进去。同时,确保内核配置CONFIG_EXTRA_FIRMWARE包含了固件文件名,或者内核能通过udev在运行时加载它们。权限与SELinux:在
rootfs中,确保固件文件的权限正确(通常为644)。如果SELinux已启用,可能需要额外的策略文件允许内核读取这些固件。在调试阶段,保持androidboot.selinux=permissive可以绕过此问题。调试命令:系统启动后,可以通过命令检查Wi-Fi状态:
dmesg | grep wcnss # 查看驱动加载日志 ip link show # 查看是否有wlan0网络接口 rfkill list # 查看无线设备是否被软/硬阻塞
7. 系统集成与用户体验优化
7.1 基础系统服务配置
当内核稳定启动,主要硬件驱动工作后,下一步是让Halium系统层面的服务跑起来。这主要涉及systemd单元文件的配置。
首先,需要确保/sbin/init正确链接到systemd。然后,检查必要的systemd服务是否启用:
systemd-networkd或NetworkManager:用于网络管理。systemd-resolved:DNS解析。ofono:负责调制解调器管理(对于平板,可能主要用于蓝牙电话功能)。pulseaudio或pipewire:音频服务。upower:电源管理。geoclue:地理位置服务。
对于Ubuntu Touch,其特有的服务如mir(显示服务器)、unity8(桌面环境)、libertine(容器化安卓应用支持)等也需要正确安装和配置。这些通常可以通过在rootfs中安装ubuntu-touch相关的元数据包来完成。
一个常见的坑是依赖缺失。在chroot环境中使用apt安装软件时,可能会因为架构(arm64)或仓库源的问题,导致某些依赖无法满足。这时需要手动下载.deb包,或者寻找替代的PPA源。使用dpkg -i --force-depends有时可以强制安装,但可能带来不稳定。
7.2 电源管理与性能调优
安卓内核的电源管理(如CPU调频、睡眠唤醒)已经相当成熟,但Halium的用户空间电源管理策略可能需要调整。
- CPU调频器:检查
/sys/devices/system/cpu/cpu*/cpufreq/scaling_governor。通常interactive或schedutil是较好的选择,在性能和功耗间取得平衡。可以创建systemd服务或udev规则,在启动时设置。 - GPU调频:类似地,高通的Adreno GPU也有调频接口。不当的设置可能导致性能低下或过热。
- 睡眠/唤醒:测试合盖(如果有)或按下电源键时,设备是否能正常进入睡眠(
suspend-to-ram)并唤醒。唤醒失败是常见问题,可能与某个外设驱动未正确处理唤醒中断有关。需要仔细分析睡眠/唤醒过程中的内核日志(dmesg)。 - 热管理:监控
/sys/class/thermal/thermal_zone*/temp,确保设备不会过热降频或关机。可能需要配置thermald服务。
7.3 音频路由与多媒体支持
音频是提升用户体验的关键。小米平板4通常使用高通的msm8953-snd-card-mtp这类音频编解码器。内核驱动加载后,会在/dev/snd/下生成设备节点。
在用户空间,需要配置PulseAudio或PipeWire。重点在于音频路由。平板可能有多个音频通路:扬声器、听筒、耳机、蓝牙音频。你需要创建或修改PulseAudio的配置文件(如/etc/pulse/default.pa或/usr/share/pulseaudio/alsa-mixer/profile-sets/下的文件),定义正确的源(source)和汇(sink),并映射到正确的ALSA设备。
测试音频可以使用命令:
# 播放测试音 speaker-test -t wav -c 2 # 录制测试 arecord -d 5 test.wav如果音频播放无声或杂音,检查alsamixer,确保所有通道未被静音(MM),且音量适中。更复杂的问题可能需要调整设备树中音频路由(audio-routing)的配置,或内核驱动中的dai-link设置。
最后,图形加速(GPU)的支持对于流畅的UI至关重要。确保Mesa驱动已为Adreno GPU正确编译和安装。对于Ubuntu Touch,可能需要使用freedreno(开源驱动)的特定版本。可以通过glxinfo命令检查OpenGL渲染器是否正确识别为freedreno。