Environment
First I will give a quick summary of my environment
Device: Samsung Galaxy M20 (m20lte)
SoC: Exynos 7904 (with Mali-G71 GPU)
OS: Android 10 (Stock ROM with root using Magisk)
Kernel: 4.4.177
SELinux is disabled (set to permissive mode)
Vulkan API version: 1.1.108
Chroot environment: Debian 11 (arm64) running on Linux Deploy, with full root access. Directories like /dev
, /proc
, /data
, /system
, /sdcard
are mounted into the chroot.
Vulkan availability
I know this device support Vulkan API (Vulkan loader avaliable at /system/lib64/libvulkan.so
).
Normal Android apps can load and use Vulkan APIs without any problems. For example:
- Vulkan Caps Viewer can display Vulkan information on this device
- GeekBench 5,
Compute
section has an option to compute with GPU using Vulkan API, and it works well
Problem
I cannot load libvulkan.so
from /system/lib64/libvulkan.so
by running program in the chroot.
For example, I created a simple c source (named dlopen.c
):
#include <stdio.h>
#include <dlfcn.h>
int main() {
void *handle = dlopen("libvulkan.so", RTLD_LAZY);
if (!handle) {
printf("Cannot load libvulkan.so\n");
} else {
printf("Loaded libvulkan.so\n");
}
return 0;
}
Compile it using gcc: gcc dlopen.c -ldl -o dlopentest
Setup the environment variable LD_LIBRARY_PATH=/system/lib64/
or symlink /system/lib64/libvulkan.so
to (folder in chroot) /lib/aarch64-linux-gnu/libvulkan.so
and /lib/aarch64-linux-gnu/libvulkan.so.1
Finally run it using ./dlopentest
, the program always print Cannot load libvulkan.so
Using strace
, but nothing weird found (log link)
I'm not sure about /lib/aarch64-linux-gnu/libc.so
, since instead of being a symlink to libc.so.6
or a real .so
file, it's some kind of ld script. But replacing it with a symlink to libc.so.6
makes no change.
vulkaninfo
also reports an error:
ERROR at /build/vulkan-tools-3Ouhix/vulkan-tools-1.2.162.0+dfsg1/vulkaninfo/vulkaninfo.h:628: Failed to initialize: Vulkan loader is not installed, not found, or failed to load.
strace
result is pretty much the same as my dlopentest
, so I won't include it here.
EDIT 1:
(actually I don't know what section to put this, so I put it here)
Running file
on /system/lib64/libvulkan.so
:
/system/lib64/libvulkan.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[md5/uuid]=e749d3c10d92fcef9b84402783d311f8, stripped
It's dynamically linked
, so I run ldd
on it and notice the following line:
/system/lib64/libvulkan.so: /lib/aarch64-linux-gnu/libc.so: version `LIBC' not found (required by /system/lib64/libvulkan.so)
/system/lib64/libvulkan.so: /lib/aarch64-linux-gnu/libdl.so: version `LIBC' not found (required by /system/lib64/libvulkan.so)
And other lines from .so
libraries in /system/lib64
claimed the same thing.
So I check the /system/lib64/libc.so
, and found that it's a symbolic link to /apex/com.android.runtime/lib64/bionic/libc.so
.
So I mounted /apex/com.android.runtime
to chroot.
After doing so, ldd found no more problem (log link)
But, when I run the program:
root@localhost:~# ./dlopentest
Trace/breakpoint trap
Running strace
(log link)
Using gdb
, I found that it was a trap signal from /system/lib64/ld-android.so
Program received signal SIGTRAP, Trace/breakpoint trap.
0x0000007fb7fef000 in rtld_db_dlactivity () from /system/lib64/ld-android.so
When I check that file:
root@localhost:~# file /system/lib64/ld-android.so
/system/lib64/ld-android.so: ELF 64-bit LSB shared object, ARM aarch64, version 1 (SYSV), dynamically linked, BuildID[md5/uuid]=62f4de8cdef6f71d65c403ac59427c51, stripped
root@localhost:~# ldd /system/lib64/ld-android.so
statically linked
Question
- Why it does not work (why I cannot load
libvulkan.so
properly)? - How to fix it?
Real purpose
I know this section might not related to the question, but I still want to include it, to avoid possible XY problem.
I want to run War Thunder (a game, and it supports x86_64 Linux). I run it on box64 and it runs until report cannot initialize Vulkan. FYI, Vulkan is the only supported render backend for the game on Linux, so I can't use OpenGL or something.
The game require the real libc (not Android one), so I can't run it on proot, and distro-proof on Termux is too complicated compared to Linux Deploy.
Finally, thank you for reading this I just want to run War Thunder :)
/lib/aarch64-linux-gnu/libc.so.6
is loaded, then another libc/system/lib64/libc.so
is loaded. I don't think libc can be loaded with multiple instances