如何解决;加载共享库时出错“;尝试使用qemu arm运行arm二进制文件时?
我正在运行LinuxMint14,安装了qemu、qemu用户和gnueabi工具链。我使用如何解决;加载共享库时出错“;尝试使用qemu arm运行arm二进制文件时?,arm,qemu,Arm,Qemu,我正在运行LinuxMint14,安装了qemu、qemu用户和gnueabi工具链。我使用arm linux gnueabi gcc test.c-o test编译了test.c 当我尝试运行qemu-arm/usr/arm-linux-gnueabi/lib/ld-linux.so.3测试时 我收到一个错误,提示:test:error,加载共享库时出错:test:无法打开共享对象文件:没有这样的文件或目录。运行qemu-arm-test,正如我之前尝试过的那样,给出了/lib/ld-linu
arm linux gnueabi gcc test.c-o test编译了test.c
当我尝试运行qemu-arm/usr/arm-linux-gnueabi/lib/ld-linux.so.3测试时
我收到一个错误,提示:test:error,加载共享库时出错:test:无法打开共享对象文件:没有这样的文件或目录
。运行qemu-arm-test
,正如我之前尝试过的那样,给出了/lib/ld-linux.so.3:没有这样的文件或目录
但是,该文件确实存在并且可以访问
$ stat /usr/arm-linux-gnueabi/lib/ld-linux.so.3
File: `/usr/arm-linux-gnueabi/lib/ld-linux.so.3' -> `ld-2.15.so'
Size: 10 Blocks: 0 IO Block: 4096 symbolic link
Device: 801h/2049d Inode: 4083308 Links: 1
Access: (0777/lrwxrwxrwx) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2013-04-22 16:19:48.090613901 -0700
Modify: 2012-09-21 08:31:29.000000000 -0700
Change: 2013-04-22 15:58:41.042542851 -0700
Birth: -
有人知道我如何让qemu运行arm程序而不必模拟整个arm Linux内核吗
测试c是
#include <stdio.h>
int main() {
printf("this had better work\n");
}
如果你想在没有Linux的情况下运行ARM,那么你需要一个不同的编译器(至少)arm linux gnueabi gcc
是一个针对linux的编译器。编译器和libc
紧密相连。您需要一个带有qemu可移植层的newlib
编译器
见:和。一个newlib
端口位于,看起来与Balau博客相同
通常,非Linux gcc称为arm none eabi gcc
。前缀arm none eabi-被一些配置脚本识别。我通过将以下库复制到/lib中解决了这个问题,但我相信应该有更好的解决方案,而不是我发明的这个讨厌的解决方案
sudo cp /usr/arm-linux-gnueabi/lib/ld-linux.so.3 /lib
sudo cp /usr/arm-linux-gnueabi/lib/libgcc_s.so.1 /lib
sudo cp /usr/arm-linux-gnueabi/lib/libc.so.6 /lib
请告诉我是否还有其他更好的解决方案,我很想知道。您可以通过使用-L标志提供arm linux gnueabi共享libs的路径来运行该示例
qemu-arm -L /usr/arm-linux-gnueabi/
另外,请确保未设置LD_LIBRARY_路径
unset LD_LIBRARY_PATH
我在用汇编代码运行C程序时也遇到了这个问题。例如,我的解决方案是使用选项“-static”构建可执行文件
arm-linux-gnueabi-gcc -static -g main.c square.s
然后
不会报告“找不到/lib/ld linux.so.3”错误
唯一的缺点是可执行文件的大小可能很大。但当您只想测试代码时,它会很有帮助
当然,您可以使用Balau的方法(参见artless noise的答案)。但是,如果您不想在这一步中对诸如“UART串行端口”之类的东西感到沮丧,这只是为了运行一个简单的“测试”功能,请尝试一下我的修复程序
$ export QEMU_LD_PREFIX=/usr/arm-linux-gnueabi
这对我有用。
这基本上与:
$ qemu-arm -L /usr/arm-linux-gnueabi/
您可以将它添加到~/.bashrc文件中,这样您就不必每次打开终端时都键入它。一个对我有效的变体是直接传递加载程序库,并使用加载程序参数--library path
指定所需的库路径。例如:
$ TOOLCHAIN_ROOT=/usr/local/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/arm-linux-gnueabihf
$ qemu-arm $TOOLCHAIN_ROOT/libc/lib/ld-linux-armhf.so.3 --library-path $TOOLCHAIN_ROOT/libc/lib/arm-linux-gnueabihf:/$TOOLCHAIN_ROOT/lib ./my_executable
或者等效地导出LD_LIBRARY_PATH
而不是使用--LIBRARY PATH
如果您想进行系统调用,那么对于不需要系统调用的裸机工作,您可以在大多数情况下使用arm linux gnueabi或arm none eabi风格的toolchain。有一个qemu目录,我正在编写一个单独的qemu裸机示例repo,但还没有任何东西要发布。@dwelch Right,您也可以使用-nostlib
编译,但是您必须编写自己的库和libgcc
之类的东西。例如,当您除以零时,libgcc
的Linux版本执行与newlib
不同的操作(我认为这会重置)。我认为这张海报最好使用一个新的lib gcc,但是你是对的,如果你小心的话,你可以使用armlinux-gnueabi-gcc
编译器。这条路线可能会出现很多随机的链接器/加载程序错误,这些错误通常不容易弄清楚。答案的关键是“qemu的可移植层”,这是一个大问题。如果您进行系统调用,任何旧的arm-one-eabi都将无法工作。但是如果你不进行系统调用,那么任何arm-linux gnueabi或arm-none-eabi都将作为编译器工作,并且为了强调你使用-nostlib等。如果你可以为平台构建自己的库或找到新库,那么一定要使用arm-none-eabi。如果在没有操作系统的情况下运行,printf是你最不想做的事情,当然不是你想为这个系统写的第一个程序。打开一个在qemu上没有意义的led,但是将一个字符从串行端口/uart干扰到串行终端通常是很简单的事情。此外,您可能希望从汇编程序开始,而不是从C开始,因为引导代码也很重要,因为您必须确保了解内存映射、程序加载的位置等。这是由于arm库不是作为系统库安装的(即使它们是作为交叉编译器的目标库安装的)。如果发行版支持它,那么您可以将arm安装为多功能目标(比如同时支持x86和x86_64)。在Ubuntu中,这类似于apt-addarchitecture-arm&&apt-get-install-libc6:arm
。我不知道薄荷糖。如果不想考虑的话,只需使用-static
编译即可。是的,当然可以,但在这种情况下,您需要运行Linux。最初的问题是想避开Linux。您没有复制库并运行没有Linux内核的qemu虚拟机吗?这似乎是不可能的。我发现qemu arm的-L/usr/arm-linux-gnueabihf/选项可以工作,正如上面所建议的…@artlessnoise,这里没有什么问题。这个答案使库对qemu可见,因此模拟的二进制文件将链接。它不是在启动一个模拟的Linux系统。它仍在使用系统调用模拟。@artlessnoise,这就是qemu所做的。首先,它必须能够将ARM二进制文件链接到ARM库(除非是静态的),然后这些库进行系统调用,qemu捕获这些系统调用,然后将其转换到主机操作系统。它比模拟整个ARM Linux内核要高效得多。此解决方案只是将库移动到
$ qemu-arm -L /usr/arm-linux-gnueabi/
$ TOOLCHAIN_ROOT=/usr/local/gcc-linaro-arm-linux-gnueabihf-4.7-2013.03-20130313_linux/arm-linux-gnueabihf
$ qemu-arm $TOOLCHAIN_ROOT/libc/lib/ld-linux-armhf.so.3 --library-path $TOOLCHAIN_ROOT/libc/lib/arm-linux-gnueabihf:/$TOOLCHAIN_ROOT/lib ./my_executable