编辑
2025-01-22
记录知识
0

在调试内核时,我们有时候需要更详细的内容展示,这时候crash工具就上场了,crash工具在RK平台默认是不可用的,本文主要说明在rk平台上麒麟系统开启crash工具的基本方法

一、系统工具安装

我们直接安装一个依赖空包即可

apt install linux-crashdump crash

这个包会主动安装

apt install kdump-tools kexec-tools makedumpfile crash

此时我们查看如下工具正常运行即可:

# crash --version crash 7.2.8 Copyright (C) 2002-2020 Red Hat, Inc. Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation Copyright (C) 1999-2006 Hewlett-Packard Co Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited Copyright (C) 2006, 2007 VA Linux Systems Japan K.K. Copyright (C) 2005, 2011 NEC Corporation Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc. Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. This program is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Enter "help copying" to see the conditions. This program has absolutely no warranty. Enter "help warranty" for details. GNU gdb (GDB) 7.6 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "aarch64-unknown-linux-gnu".
# kexec --version kexec-tools 2.0.29
# kdump-config --help Usage: kdump-config {help|test|show|status|load|unload|savecore|propagate|symlinks kernel-version}" help - print this page test - Do a dry-run of kdump kernel load command by showing the kernels and parameters that will be used and echo'ing the kexec command. The kexec command will not be executed. If using fadump, check if required sysfs directories exist. show - Show dump mode, status, any current parameters. Show kexec command for kdump. status - evaluate /sys/kernel/{kexec_crash_loaded,fadump_registered} depending on dump mode. Print appropriate message load - Locate the kdump kernel, debug kernel, and establish links for makedumpfile. Then load the kdump kernel using kexec If using fadump, register. unload - unload the kdump kernel using kexec If using fadump, unregister. savecore - use previously made links to save /proc/vmcore propagate - Send public ssh key to remote host for passwordless connection symlinks - Verify and create vmlinuz and initrd.img links in /var/lib/kdump according to the provided kernel version. If the target initrd.img file is absent, it will create it.

接下来我们会用到crash工具

二、内核配置

为了使得crash工具正常,我们需要打开内核的配置,如下:

CONFIG_KEXEC=y CONFIG_SYSFS=y CONFIG_DEBUG_INFO=y CONFIG_CRASH_DUMP=y CONFIG_PROC_VMCORE=y

为了vmcore,我们可以在bootargs添加crashkernel=256M,用作core的收集

重新编译内核即可。 我们需要boot.img和vmlinux两个文件

三、必要文件

上述准备好了之后,我们还需要vmlinux用来加载crash,如下:

crash ./vmlinux /proc/kcore

稍等一会儿,我们加载好所有符号即可开始crash调试

crash 7.2.8 Copyright (C) 2002-2020 Red Hat, Inc. Copyright (C) 2004, 2005, 2006, 2010 IBM Corporation Copyright (C) 1999-2006 Hewlett-Packard Co Copyright (C) 2005, 2006, 2011, 2012 Fujitsu Limited Copyright (C) 2006, 2007 VA Linux Systems Japan K.K. Copyright (C) 2005, 2011 NEC Corporation Copyright (C) 1999, 2002, 2007 Silicon Graphics, Inc. Copyright (C) 1999, 2000, 2001, 2002 Mission Critical Linux, Inc. This program is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Enter "help copying" to see the conditions. This program has absolutely no warranty. Enter "help warranty" for details. GNU gdb (GDB) 7.6 Copyright (C) 2013 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "aarch64-unknown-linux-gnu"... please wait... (patching 189292 gdb minimal_symbol values) SYSTEM MAP: /boot/System.map DEBUG KERNEL: /root/vmlinux (5.10.198) DUMPFILE: /proc/kcore CPUS: 8 DATE: Mon Nov 25 17:36:10 2024 UPTIME: 00:12:52 LOAD AVERAGE: 0.73, 0.35, 0.21 TASKS: 659 NODENAME: kylin RELEASE: 5.10.198 VERSION: #4 SMP Tue Nov 26 00:17:27 CST 2024 MACHINE: aarch64 (unknown Mhz) MEMORY: 4 GB PID: 15712 COMMAND: "crash" TASK: ffffff8062f84880 [THREAD_INFO: ffffff8062f84880] CPU: 6 STATE: TASK_RUNNING (ACTIVE) crash>

四、示例

为了简单演示crash,我随便介绍几个示例,有兴趣了解crash的,可以私下咨询,或查看官方文档如下:

https://crash-utility.github.io/crash_whitepaper.html

4.1 查看全局变量

crash> p saved_command_line saved_command_line = $1 = 0xffffff81feee7dc0 "storagemedia=emmc androidboot.storagemedia=emmc androidboot.mode=normal dsi-0=2 storagenode=/mmc@fe2e0000 androidboot.verifiedbootstate=orange androidboot.serialno=cc45dde649cc1b19 ro rootwait earlycon=uart8250,mmio32,0xfeb50000 console=ttyFIQ0 irqchip.g"...

4.2 反汇编符号

crash> dis blk_update_request 0xffffffc0087d2fb8 <blk_update_request>: mov x9, x30 0xffffffc0087d2fbc <blk_update_request+4>: nop 0xffffffc0087d2fc0 <blk_update_request+8>: sub sp, sp, #0x60 0xffffffc0087d2fc4 <blk_update_request+12>: stp x29, x30, [sp,#16] 0xffffffc0087d2fc8 <blk_update_request+16>: add x29, sp, #0x10 0xffffffc0087d2fcc <blk_update_request+20>: stp x19, x20, [sp,#32] ....................

4.2 查看task_struct

crash> struct task_struct ffffff8026600000 struct task_struct { thread_info = { flags = 0, addr_limit = 549755813887, { preempt_count = 4294967296, preempt = { count = 0, need_resched = 1 } } }, state = 264, stack = 0xffffffc00f248000, .......................

4.3 打印内存值

假设我们有驱动如下操作:

test = kmalloc(128, GFP_KERNEL);; memcpy(test, "helloworld", 128);

此时我们加载ko,获取test 的虚拟地址0xffffff806f63eb00,crash内直接打印即可

crash> rd -8 0xffffff806f63eb00 10 ffffff806f63eb00: 68 65 6c 6c 6f 77 6f 72 6c 64 helloworld

至此,我们可以发现crash对于调试内核来说还是挺方便的。

编辑
2025-01-22
记录知识
0

RK3588的gpu是mali g610,这个驱动已经默认合入主线mesa了,对于社区,知名开源机构Collabora开源了基于mali的panthor方案,mesa这边使用主线版本,内核更新基于linux6.8的panthor驱动即可。文章详情如下:

https://www.collabora.com/news-and-blog/news-and-events/release-the-panthor.html

一、MESA更新

对于mesa,我们需要更新到这笔commit之后即可:

https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26358

我们切一下mesa的仓库,我们可以直接针对mali显卡编译即可,如下:

meson . build/ -Dvulkan-drivers= -Dgallium-drivers=panfrost -Dllvm=disabled

对应文档如下:

https://docs.mesa3d.org/drivers/panfrost.html

二、内核更新

对于内核,默认mesa对于的panthor版本在6.8上,我们需要更新如下仓库:

https://gitlab.freedesktop.org/panfrost/linux/-/tree/panthor-next+rk3588?ref_type=heads

其主要代码在:driver/gpu/drm/panthor

我们需要移植这里的代码到自己的版本上,例如linux6.1(已验证)/linux5.10(未验证)

三、固件更新

我们知道mali显卡支持csf固件加载,这里的固件也提交在社区上了,可以从如下仓库获取:

https://git.kernel.org/pub/scm/linux/kernel/git/firmware/linux-firmware.git

我们需要一个名字为mali_csffw.bin的文件放在系统环境下,或合并在内核中,通过firmware_request加载

四、移植步骤

4.1 mesa

对于mesa,我们需要切到24.1.0分支上构建,如果我们需要二进制,可以从ubuntu社区上找oibaf的每日构建,如下:

https://launchpad.net/~oibaf/+archive/ubuntu/graphics-drivers

对于指定版本的,根据下载链接修改版本号,可以下载到指定版本上。

当然,如果我们不需要mesa的deb系列包,仍然可以通过meson直接构建如下:

meson . build/ -Dvulkan-drivers= -Dgallium-drivers=panfrost -Dllvm=disabled

4.2 kernel

使能defconfig,如下:

CONFIG_DRM=y CONFIG_DRM_GPUVM=y CONFIG_DRM_EXEC=y CONFIG_DRM_SCHED=y CONFIG_IOMMU_SUPPORT=y CONFIG_IOMMU_IO_PGTABLE_LPAE=y CONFIG_DRM_GEM_SHMEM_HELPER=y CONFIG_PM_DEVFREQ=y CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y CONFIG_DRM_PANTHOR=y CONFIG_ROCKCHIP_REGULATOR_COUPLER=y CONFIG_DRM_GPUVM=y

合入panthor驱动如下:

0041-panthor-v6.txt

设备树需要关闭原来的mali gpu节点,并新增基于panthor的节点如下:

From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Boris Brezillon <boris.brezillon@collabora.com> Date: Mon, 7 Aug 2023 17:30:58 +0200 Subject: arm64: dts: rockchip: rk3588: Add GPU nodes Signed-off-by: Sebastian Reichel <sebastian.reichel@collabora.com> --- arch/arm64/boot/dts/rockchip/rk3588s.dtsi | 119 ++++++++++ 1 file changed, 119 insertions(+) diff --git a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi index 762a095648b1..f43f10340d5d 100644 --- a/arch/arm64/boot/dts/rockchip/rk3588s.dtsi +++ b/arch/arm64/boot/dts/rockchip/rk3588s.dtsi @@ -962,6 +962,120 @@ usb_host2_xhci: usb@fcd00000 { snps,dis-del-phy-power-chg-quirk; snps,dis-tx-ipgap-linecheck-quirk; snps,dis_rxdet_inp3_quirk; + }; + + gpu_opp_table: gpu-opp-table { + compatible = "operating-points-v2"; + + nvmem-cells = <&gpu_leakage>; + nvmem-cell-names = "leakage"; + + rockchip,pvtm-voltage-sel = < + 0 815 0 + 816 835 1 + 836 860 2 + 861 885 3 + 886 910 4 + 911 9999 5 + >; + rockchip,pvtm-pvtpll; + rockchip,pvtm-offset = <0x1c>; + rockchip,pvtm-sample-time = <1100>; + rockchip,pvtm-freq = <800000>; + rockchip,pvtm-volt = <750000>; + rockchip,pvtm-ref-temp = <25>; + rockchip,pvtm-temp-prop = <(-135) (-135)>; + rockchip,pvtm-thermal-zone = "gpu-thermal"; + + clocks = <&cru CLK_GPU>; + clock-names = "clk"; + rockchip,grf = <&gpu_grf>; + volt-mem-read-margin = < + 855000 1 + 765000 2 + 675000 3 + 495000 4 + >; + low-volt-mem-read-margin = <4>; + intermediate-threshold-freq = <400000>; /* KHz */ + rockchip,temp-hysteresis = <5000>; + rockchip,low-temp = <10000>; + rockchip,low-temp-min-volt = <750000>; + rockchip,high-temp = <85000>; + rockchip,high-temp-max-freq = <800000>; + + opp-300000000 { + opp-hz = /bits/ 64 <300000000>; + opp-microvolt = <675000 675000 850000>; + }; + opp-400000000 { + opp-hz = /bits/ 64 <400000000>; + opp-microvolt = <675000 675000 850000>; + }; + opp-500000000 { + opp-hz = /bits/ 64 <500000000>; + opp-microvolt = <675000 675000 850000>; + }; + opp-600000000 { + opp-hz = /bits/ 64 <600000000>; + opp-microvolt = <675000 675000 850000>; + }; + opp-700000000 { + opp-hz = /bits/ 64 <700000000>; + opp-microvolt = <700000 700000 850000>; + opp-microvolt-L2 = <687500 687500 850000>; + opp-microvolt-L3 = <675000 675000 850000>; + opp-microvolt-L4 = <675000 675000 850000>; + opp-microvolt-L5 = <675000 675000 850000>; + }; + opp-800000000 { + opp-hz = /bits/ 64 <800000000>; + opp-microvolt = <750000 750000 850000>; + opp-microvolt-L1 = <737500 737500 850000>; + opp-microvolt-L2 = <725000 725000 850000>; + opp-microvolt-L3 = <712500 712500 850000>; + opp-microvolt-L4 = <700000 700000 850000>; + opp-microvolt-L5 = <700000 700000 850000>; + }; + opp-900000000 { + opp-hz = /bits/ 64 <900000000>; + opp-microvolt = <800000 800000 850000>; + opp-microvolt-L1 = <787500 787500 850000>; + opp-microvolt-L2 = <775000 775000 850000>; + opp-microvolt-L3 = <762500 762500 850000>; + opp-microvolt-L4 = <750000 750000 850000>; + opp-microvolt-L5 = <737500 737500 850000>; + }; + opp-1000000000 { + opp-hz = /bits/ 64 <1000000000>; + opp-microvolt = <850000 850000 850000>; + opp-microvolt-L1 = <837500 837500 850000>; + opp-microvolt-L2 = <825000 825000 850000>; + opp-microvolt-L3 = <812500 812500 850000>; + opp-microvolt-L4 = <800000 800000 850000>; + opp-microvolt-L5 = <787500 787500 850000>; + }; + }; + + gpu: gpu@fb000000 { + compatible = "rockchip,rk3588-mali", "arm,mali-valhall-csf"; + reg = <0x0 0xfb000000 0x0 0x200000>; + interrupts = <GIC_SPI 92 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH 0>, + <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH 0>; + interrupt-names = "job", "mmu", "gpu"; + + clock-names = "core", "coregroup", "stacks"; + clocks = <&cru CLK_GPU>, <&cru CLK_GPU_COREGROUP>, + <&cru CLK_GPU_STACKS>; + assigned-clocks = <&scmi_clk SCMI_CLK_GPU>; + assigned-clock-rates = <200000000>; + power-domains = <&power RK3588_PD_GPU>; + operating-points-v2 = <&gpu_opp_table>; + #cooling-cells = <2>; + dynamic-power-coefficient = <2982>; + status = "disabled"; }; @@ -3124,6 +3238,11 @@ gpio4: gpio@fec50000 { }; }; + gpu_grf: syscon@fd5a0000 { + compatible = "rockchip,rk3588-gpu-grf", "syscon"; + reg = <0x0 0xfd5a0000 0x0 0x100>; + }; + av1d: video-codec@fdc70000 { compatible = "rockchip,rk3588-av1-vpu"; reg = <0x0 0xfdc70000 0x0 0x800>; --

对于firmware加载部分,如果我们有initrd,则firmware可以放在inird中加载,如果没有,我们可以将其放在内核中自包含,则如下修改:

diff --git a/drivers/gpu/drm/panthor/panthor_fw.c b/drivers/gpu/drm/panthor/panthor_fw.c index ef232c0c2049..de85e30241f6 100644 --- a/drivers/gpu/drm/panthor/panthor_fw.c +++ b/drivers/gpu/drm/panthor/panthor_fw.c @@ -705,7 +705,7 @@ static int panthor_fw_load(struct panthor_device *ptdev) (u32)GPU_ARCH_MINOR(ptdev->gpu_info.gpu_id), CSF_FW_NAME); - ret = request_firmware(&fw, fw_path, ptdev->base.dev); + ret = request_firmware(&fw, CSF_FW_NAME, ptdev->base.dev); if (ret) { drm_err(&ptdev->base, "Failed to load firmware image '%s'\n", CSF_FW_NAME); @@ -1367,4 +1367,4 @@ int panthor_fw_init(struct panthor_device *ptdev) return ret;

defconfig设置如下:

CONFIG_FW_LOADER=y CONFIG_EXTRA_FIRMWARE="mali_csffw.bin" CONFIG_EXTRA_FIRMWARE_DIR="firmware"

此时固件应该放在内核目录如下:

firmware/ └── mali_csffw.bin

五、启动日志

至此,panthor的移植已完全完成,如果内核panthor启动成功,则出现如下日志:

[ 10.187485] panthor fb000000.gpu-panthor: [drm] clock rate = 198000000 [ 10.188422] panthor fb000000.gpu-panthor: EM: OPP:400000 is inefficient [ 10.188429] panthor fb000000.gpu-panthor: EM: OPP:300000 is inefficient [ 10.188525] panthor fb000000.gpu-panthor: EM: created perf domain [ 10.188854] panthor fb000000.gpu-panthor: [drm] mali-g610 id 0xa867 major 0x0 minor 0x0 status 0x5 [ 10.188866] panthor fb000000.gpu-panthor: [drm] Features: L2:0x7120306 Tiler:0x809 Mem:0x301 MMU:0x2830 AS:0xff [ 10.188875] panthor fb000000.gpu-panthor: [drm] shader_present=0x50005 l2_present=0x1 tiler_present=0x1 [ 10.190340] panthor fb000000.gpu-panthor: [drm] Firmware protected mode entry not be supported, ignoring [ 10.190563] panthor fb000000.gpu-panthor: [drm] CSF FW v1.1.0, Features 0x0 Instrumentation features 0x71 [ 10.190996] [drm] Initialized panthor 1.0.0 20230801 for fb000000.gpu-panthor on minor 1

此时我们glmark2测试如下,则代表系统启动正常

root@kylin:~# glmark2 ======================================================= glmark2 2021.02 ======================================================= OpenGL Information GL_VENDOR: Mesa GL_RENDERER: Mali-G610 (Panfrost) GL_VERSION: 3.1 Mesa 24.1.0-devel-panthor (git-1c769cb2b0) ======================================================= [build] use-vbo=false: FPS: 1859 FrameTime: 0.538 ms
编辑
2025-01-22
记录知识
0

我们在开发rk3399的时候,我们可以知道,mesa正在实现panfrost来做rk3399的mali T860显卡的开源方案,并且arm公司也给每个芯片方案厂商提供了闭源的libmali方案。现在时间来到了rk3588作为主流芯片的时代,我们可以借鉴之前的内容,实现两套显卡驱动互相切换的功能,做到操作系统中,从而更好的使得客户使用操作系统。

一、介绍

rk3588的两个方案分别为

mesa panfrost libmali legacy

1.1 panfrost

为了让linux平台支持panfrost版本,我们需要更新和升级mesa库,根据参考信息和社区的一些行为,我们需要升级到mesa到23版本及以上

https://gitlab.freedesktop.org/mesa/mesa/-/tree/main/src/panfrost

于是,我们可以从如下源获取mesa-23

https://dev.kylinos.cn/~rk3588/+archive/kylin-desktop/common

我构建的版本号为:1:23.0.5-0kylin1panforkrk1 如下: image.png

注意,mesa依赖llvm-14,我们需要同时更新系统的llvm到14,如下

image.png 对于已经安装的系统,我们需要替换如下包:

image.png

此时,我们通过glmark2测试,可以看到是基于panfrost的opengl方案,如下

image.png 同样的,glmark2-es2也能看到是基于panfrost的opengl es方案,如下

image.png

1.2 libmali legacy

如果我们需要使得系统支持libmali legacy的方案,我们需要更新显卡驱动为libmali.so,并且更换xorg为rk修改和定制的xorg

对于libmali,我们需要更新版本如下:

https://dev.kylinos.cn/~rk3588/+archive/kylin-desktop/common/+packages

image.png

对于xorg,我们需要更新版本如下:

https://dev.kylinos.cn/~rk3588/+archive/kylin-desktop/x11/+index?batch=50&memo=50&start=50

image.png

此时我建议更新的具体包如下:

image.png

image.png

image.png 至此,我们的系统可以默认支持legacy mali方案,此时我们可用glmark2-es2测试,如下:

image.png 但是此时,我们无法通过glmark2测试

image.png

二、实施方案

根据上面的信息,我们已经具备能力将显卡方案选择任意一种,但是没有具备一个能力让应用程序运行时自动选择任意一种显卡方案进行渲染和显示。

故我们的目标是将其两种方案的融合,其主要思路如下

开机默认使用mesa的panfrost方案显卡 用户可以通过环境变量的方式使用libmali legacy方案 在上述思路完成的情况下,我们还需要使得libmali legacy的方案支持opengl。我们还需要

通过gl4es库转换opengl es的实现到opengl上

2.1 开机默认mesa panfrost

根据上述我们可以知道,我们已经更新mesa到panfrost了,但是panfrost需要加载mali_csffw.bin,所以我们需要一个加载mali_csffw.bin的包, 如下

image.png 这个包可以自动根据mali的版本选择固件mali_csffw.bin,所以我们可以看到如下:

image.png 至此,下次加载显卡过程中,会主动读取/usr/lib/firmware/mali_csffw.bin的文件内容,将显卡固件通过驱动加载到显卡中。然后我们的显卡便可以正常工作了。

2.2 通过环境变量设置legacy mali

2.2.1 编译libmali

根据上面我们可以知道,我们如果使用libmali和rk修改的xorg,我们可以让系统默认通过legacy启动显卡,但是如果我们需要实施动态选择显卡的方案,我们xorg不能使用rk定制的,而libmali不需要添加到ld.conf中,所以我们首先需要拿到libmali的代码,如下:

https://github.com/JeffyCN/mirrors/tree/libmali

然后我们需要修改libmali的默认ldconfig的行为,如下补丁

diff --git a/meson.build b/meson.build index 9add735..89c5366 100644 --- a/meson.build +++ b/meson.build @@ -345,7 +345,7 @@ if vendor_package command : ['echo', get_option('prefix') / wrapper_libdir], capture : true, install_dir : '/etc/ld.so.conf.d', - install : true) + install : false) elif get_option('khr-header') # Install optional KHR header install_data(

此时,编译出来的libmali将不包含00-aarch64-mali.conf。

2.2.2 编译gl4es

我们知道,如果我们使用legacy的mali,那么opengl的程序将无法运行,此时我们需要通过libgl4es库使其支持此功能,gl4es库地址如下:

https://github.com/ptitSeb/gl4es.git

我们需要找到其稳定的tag,这里以1.1.6为例,如下

https://github.com/ptitSeb/gl4es/tree/v1.1.6

对于此包,其默认包含debian文件,故我们可以直接编译和生成包,地址如下

image.png 我们可以知道libgl4es包的内容如下

image.png

如果我们通过ld library path配置了gl4es,则默认可以将opengl的内容翻译成opengles渲染,如下

export LD_LIBRARY_PATH+=/usr/lib/gl4es/

至此,我们可以将legacy mali上不支持opengl的应用的问题解决

2.2.3 dri2 to dri3

我们通过解析libmali.so的string,我们可以知道其默认只支持dri2,如下

image.png 而对于现在的操作系统,默认启用dri3,我们需要为这个场景下的将dri2 转换到dri3,从而让支持dri3的应用正常通过libmali legacy执行渲染。

对于此,我们需要仓库如下:

https://github.com/hbiyik/dri2to3

这个仓库我们需要自行生成和编写debian配置,从而形成软件包

此仓库编译出来后,我们需要用ld preload加载,如下

export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libdri2to3.so

2.2.4 显卡加载器

对于上述的功能,我们需要提供一个加载器的deb包,加载器的仓库如下:

https://gitlab2.kylin.com/shanghai-team/3588/rkmali-loader

我们需要实现一个加载脚本rkmali,其代码如下:

#!/bin/bash export LD_PRELOAD=/usr/lib/aarch64-linux-gnu/libdri2to3.so export LD_LIBRARY_PATH=/usr/lib/aarch64-linux-gnu/mali:/usr/lib/gl4es/ exec "$@"

故,我们提供rkmali的deb包,其内容如下

image.png 至此我们可以通过加载器让应用程序使用legacy mali,方法如下:

image.png

image.png

image.png

三、测试验证

根据上面的描述,我们可以动态的选择显卡渲染方式(通过mesa或libmali),这里提供一个测试脚本如下:

#!/bin/bash while((1)) do # test mesa panfrost OpenGL glmark2 sleep 1 # test mesa panfrost OpenGLES glmark2-es2 sleep 1 # test rkmali OpenGLES rkmali glmark2-es2 sleep 1 # test rkmali OpenGL wrapper (gl4es) rkmali glmark2 sleep 1 # test mesa es2gears es2gears sleep 1 # test rkmali es2gears rkmali es2gears sleep 1 done > rkmali-loader-test-$(date "+%F").log

此脚本24小时运行正常即可。

编辑
2025-01-22
记录知识
0

之前我们可以通过waydroid的官方image来实现通过软件渲染的方式运行waydroid,参考Waydroid预研,从而实现在linux上运行安卓程序,这次我们通过移植了panthor,可以通过官方的mesa进行渲染,这样我们根据外网社区的相关文章,同步验证waydroid在panthor的运行效果。可想而知的是,如果最新的waydroid想要运行在panthor上,安卓内部的mesa需要更新到24以上,这样waydroid是纯硬件渲染了。移植安卓mesa这个动作有人完成了,我们只需要拿到对应的固件即可,关于rk3588上使用panthor的文章可以参考RK3588关于panthor驱动的移植

一、在系统上安装waydroid

我们可以参照waydroid的官网,安装waydroid二进制,这样我们就不需要重编译waydroid源码,如下:

sudo apt install curl ca-certificates -y curl https://repo.waydro.id | sudo bash sudo apt install waydroid

此时我们的系统内可以安装好waydroid

二、根据lxc的要求构建内核

我们上层安装好waydroid后,需要根据lxc的配置打开对应的内核配置,我们需要运行命令lxc-checkconfig,如下

LXC version 5.0.0 --- Namespaces --- Namespaces: enabled Utsname namespace: enabled Ipc namespace: enabled Pid namespace: enabled User namespace: enabled newuidmap is not installed newgidmap is not installed Network namespace: enabled --- Control groups --- Cgroups: enabled Cgroup namespace: enabled Cgroup v1 mount points: Cgroup v2 mount points: /sys/fs/cgroup Cgroup v1 systemd controller: missing Cgroup v1 freezer controller: missing Cgroup ns_cgroup: required Cgroup device: enabled Cgroup sched: enabled Cgroup cpu account: enabled Cgroup memory controller: enabled Cgroup cpuset: enabled --- Misc --- Veth pair device: enabled, not loaded Macvlan: enabled, not loaded Vlan: enabled, not loaded Bridges: enabled, loaded Advanced netfilter: enabled, loaded CONFIG_IP_NF_TARGET_MASQUERADE: enabled, not loaded CONFIG_IP6_NF_TARGET_MASQUERADE: enabled, not loaded CONFIG_NETFILTER_XT_TARGET_CHECKSUM: enabled, loaded CONFIG_NETFILTER_XT_MATCH_COMMENT: enabled, not loaded FUSE (for use with lxcfs): enabled, not loaded --- Checkpoint/Restore --- checkpoint restore: enabled CONFIG_FHANDLE: enabled CONFIG_EVENTFD: enabled CONFIG_EPOLL: enabled CONFIG_UNIX_DIAG: enabled CONFIG_INET_DIAG: enabled CONFIG_PACKET_DIAG: enabled CONFIG_NETLINK_DIAG: enabled File capabilities: Note : Before booting a new kernel, you can check its configuration usage : CONFIG=/path/to/config /usr/bin/lxc-checkconfig

这里如果我们发现一些配置没打开,那么需要在内核中将配置打开。我们需要将其所有的特性功能打开。这里需要留意以下配置:

CONFIG_IPV6=y CONFIG_NF_CT_NETLINK=y CONFIG_PSI=y CONFIG_BLK_DEV_LOOP=y CONFIG_ANDROID=y CONFIG_ANDROID_BINDER_IPC=y CONFIG_ANDROID_BINDERFS=y CONFIG_ANDROID_BINDER_DEVICES="binder,hwbinder,vndbinder"

我们可以关闭RK的特性配置如下:

# CONFIG_DRM_IGNORE_IOTCL_PERMIT is not set

至此,相关内核配置可以正常打开,我们编译内核即可

三、waydroid的安卓固件

我们要运行基于panthor的安卓固件,那么我们需要升级安卓的mesa包,我们可以自己编译mesa,也可以利用别人移植好的mesa仓库,替换编译,如下:

https://github.com/WillzenZou/android_external_mesa3d

如果我们只需要二进制,这里我是直接用二进制了,所以可以直接如下获取:

https://github.com/WillzenZou/armbian_fork_build/releases/download/willzen-armbian-24.5.0/2.waydroid-panthorv10-240416-v1.img.tar.gz

此时我们解压镜像如下:

tar xvzf 2.waydroid-panthorv10-240416-v1.img.tar.gz

然后将其拷贝到固件加载目录

cp -rf 2.waydroid-panthorv10-240416-v1.img/* /usr/share/waydroid-extra/images

最后初始化waydroid即可

waydroid init -f -i /usr/share/waydroid-extra/images

四、启动waydroid

我们根据官网的说明直接启动waydroid即可,如下

waydroid show-full-ui

如果启动存在问题,则可以如下查看日志

waydroid logcat

具体cmdline配置可以参考官网:

https://docs.waydro.id/usage/waydroid-command-line-options

至此,我们等一会儿就正常通过panthor启动waydroid,如下:

image.png

五、扩展

根据上面的信息,我们正常的通过panthor在linux设备上运行了安卓设备,这个不是我做这个事情的主要目的,因为如Waydroid预研,waydroid已经可以正常的通过软件渲染运行在麒麟系统上了,这次这个事情是通过硬件渲染的方式来试试waydroid。

这个事情的主要目的是,如果waydroid启动的openharmony,而linux是麒麟系统,那么我们可以使得openharmony通过容器的方式运行,基于麒麟v10上。要完成这个事情,我们还需要如下:

openharmony的gpu支持panthor,(目前仅支持panfrost) 麒麟系统支持的gpu支持panthor,(目前仅支持panfrost/legacy mali) openharmony的hdf和linux内核相互兼容 当然,也有疑问,为什么不直接通过panfrost来运行麒麟系统呢,这里主要原因是,openharmony的panfrost对应的mesa版本在22,而mesa在22上并不完善支持panfrost,我们的机器目前使用的是基于mesa23的panfrost,这个并不兼容,而且,openharmony的mesa的panfrost并不支持rk3588,所以panfrost只能作为openharmony的老旧方案,对应的panfrost版本在Linux上可能并不能工作(waydroid要求显卡显示方案和主机显示方案相同)。

编辑
2025-01-22
记录知识
0

我们编译鸿蒙是通过服务器,那么有没有一种办法,让我们qemu能够直接通过服务器启动openharmony呢,而不是需要将image拷贝到外面,然后通过windows/linux的qemu来启动openharmony,实际上,这是有办法的。本文基于XMing来实现在windows上启动Linux的Xserver,或者Linux下直接启动openharmony

一、启动X11 Forward

为了使得服务器能够接收远程的X11程序启动,我们需要打开sshd 服务的配置选项如下:

vim /etc/ssh/sshd_config X11Forwarding yes

此时,我们重启ssh服务即可

systemctl restart sshd

二、.Xauthority

我们需要知道的是,X11转发的功能是在服务端提供了.Xauthority来识别,如果我们是直接在服务器上运行,则每次登录.Xauthority会在登录的账户上更新,如果我们是root登录,则位置为

/root/.Xauthority

但是我们通常情况下,代码是在chroot中构建,这样的话我们需要利用chroot中的.Xauthority,则如下:

cp .Xauthority /path/to/chroot/root/.Xauthority

假设我们的chroot环境目录是/root/work/kb/squashfs-root/,则如下

cp .Xauthority /root/work/kb/squashfs-root/root/.Xauthority

三、qemu-run.sh

为了让qemu正常运行,我们需要编写qemu脚本,这里参考qemu启动openharmony镜像(二) 在arm64的机器上编译和运行qemu即可

四、Linux主机上通过服务器的qemu启动openharmony

对于Linux主机,我们可以通过ssh 加上X/Y的配置打开X11 Forward功能,这里以131为例

ssh -XY root@172.25.130.131

此时我们进入openharmony的镜像输出路径

cd out/arm64_virt/packages/phone/images

直接运行脚本即可

./qemu-run.sh

五、Windows主机上通过XMing实现

我们知道,Windows不能直接启动X11的程序,我们需要借助XMing开源程序,这里有两种办法

5.1 MobaXterm

我们借助MobaXterm程序,它默认集成了XMing二进制,我们通过其ssh登录的服务器,可以直接启动X11的程序,这里以xterm为例,如下:

image.png

5.2 Putty

我们知道Putty是很好用的开源ssh client,如果我们使用Putty登录ssh,则我们需要启用一个XMing后台,如下可以下载:

http://www.straightrunning.com/XmingNotes/

我们可以通过sourceforge网站来直接下载二进制安装

https://sourceforge.net/projects/xming/

此时我们如果没有putty,则可以预装一个,如果存在putty,则在Xming中不安装putty,如下

image.png 此时,我们可以发现Putty内部多了如下选项

image.png 此时我们通过putty打开一个ssh时,默认打开"Enable X11 forwarding"即可。

此时我们打开窗口如下:

image.png

5.3 启动qemu

此时我们直接进入环境中,启动脚本即可

./qemu-run.sh

六、启动效果

至此,Openharmony启动效果如下:

image.png

七、总结

我们知道,这样的方式是通过X11转发,在Windows/Linux以X11的服务器来运行一个X11程序,而我们这里服务器是qemu启动的窗口,所以这里可能存在兼容性问题,比较明显的是,无法使用鼠标。这和qemu启动的openharmony的兼容性相关。

所以,此方法只可以用作定位系统开机启动中存在的通用性问题,或学习鸿蒙操作系统的一种方式