我们希望解决的挑战是:
-
在嵌入式设备上运行标准 Linux 工具
-
编译自己的工具以在嵌入式设备上运行
-
在电脑上运行嵌入式设备的二进制文件
这通常可以通过交叉编译和/或静态编译目标二进制文件来实现。这是一种非常有效的方法,但也可能非常耗时,即使你在这方面经验丰富。因此,这里描述的方法不这样做。
随身携带依赖库
实际情况是,虽然动态链接的二进制文件需要一些环境,但实际上弄清楚该环境是什么并将其复制到想要运行二进制文件的系统并不难。
strace
考虑在 arm64 Android 手机上从 arm64 Raspberry Pi运行的示例。
仅仅复制是行不通的,因为 Android 与常见的 Linux 发行版差别太大:
pi@rpi:~ $ adb push `which strace` /data/local/tmp
/usr/bin/strace:推送了 1 个文件,跳过了 0 个。16.0 MB/s(0.098 秒内 1640712 字节)
pi@rpi:~ $ adb exec-out /data/local/tmp/strace -ttewrite /bin/echo X
/system/bin/sh:/data/local/tmp/strace:没有此文件或目录
pi@rpi:~ $ adb exec-out ldd /data/local/tmp/strace
linux-vdso.so.1 => [vdso] (0x73edb38000)
无法链接可执行文件“linker64”:未找到库“libc.so.6”:主可执行文件需要
我们可以列出依赖项。strace
依赖于动态链接器、库,并且通常依赖于一些特殊位,例如 VDSO。
pi@rpi:~ $ ldd `哪个 strace`
linux-vdso.so.1 (0x0000007faf464000)
libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000007faf0b0000)
/lib/ld-linux-aarch64.so.1 (0x0000007faf427000)
我们可以复制依赖项并使用适当的动态链接器来加载它们(第一个突出显示的位枚举了依赖项):
pi@rpi:~ $ bin=`which strace`; adb push $bin $(ldd $bin | sed -nre 's/^[^/]*(\/.*) \(0x.*\)$/\1/p') /data/local/tmp/
/usr/bin/strace:推送了 1 个文件,跳过了 0 个。19.4 MB/s(0.081 秒内 1640712 字节)
/lib/aarch64-linux-gnu/libc.so.6:推送了 1 个文件,跳过了 0 个。23.7 MB/s(0.067 秒内 1651472 字节)
/lib/ld-linux-aarch64.so.1: 推送了 1 个文件ÿ