riscv软件系列之linux系统下运行hello程序

1,242 阅读1分钟

hello.c文件内容如下:

#include <stdio.h>
int main()
{
        printf("hello world\n");
        return 0;
}

编译hello.c

$ riscv64-unknown-linux-gnu-gcc  -o hello hello.c

编译后生成hello可执行文件

运行hello

将hello可执行文件拷贝到riscv平台,并执行

/ # ./hello
-/bin/sh: hello: not found

程序找不到?这是什么原因?

查看hello的动态链接信息

riscv64-unknown-linux-gnu-readelf -d hello

从上图可知,我们hello是动态链接的方式,需要依赖libc.so.6这个动态库。但是我们busybox是通过静态链接的方式编译的,因此在lib/目录下没有动态库,也就没有libc.so.6。 出于hello找不到libc.so.6这个动态库的原因,导致hello执行失败。

解决办法(静态链接hello):

由于没有动态库,我们就对hello进行静态链接编译,如下:

$ riscv64-unknown-linux-gnu-gcc -static -o hello hello.c

静态链接后,hello有将近4M的大小,这是因为它已经将所需要的库代码全部添加进来了。

接下来我们将hello拷贝到riscv系统板上执行:

$ ./hello

此时可以正常执行了。

解决办法(将libc.so.6也拷贝到riscv系统):

  • 动态编译busybox

如果选择Build shared libbusybox方式进行编译时,要将交叉编译的动态库或符号链接复制到对应的目录中,否则程序不能运行。同时在配置时应去掉Build shared libbusybox 目录下的两项:

Build shared libbusybox->
Producebinary for each applet,linked against libbusybox
Produceadditional busybox binary linked against libbusybox

同时去掉

Build with Large File Support (for accessing file>2GB)

否则编译会报错(据说会报错,但是在我们平台编译没有报错,但我们不使用这么大文件,就去掉这项)。

一定要勾选上如下配置:

Init Utilities—>
(*) init
(*) Supporting reading an inittab file //支技init进程读取/etc/inittab配置文件。
(*) Supporting running commands with controlling-tty //使busybox在真实的串口设备中运行命令行,不使用可能会报类似与 sh:can’t access tty:job control turned off的错误。

其它基本可按默认配置。

由于hello需要依赖动态库libc.so.6,因此我们在riscv交叉链接工具的安装目录下查找这个动态库文件。 riscv交叉编译工具链的安装目录为:/home/caipengxiang/opt/riscv64_32

在这个目录下搜索libc.so.6:

$ find ./ -name libc.so*

我们riscv不带浮点运算,因此找到 ./sysroot/lib64/lp64/libc.so.6

由于这是个软链接文件,我们查看其指向哪儿:

$ ll sysroot/lib64/lp64/libc.so.6

从图中可以看到,libc.so.6指向libc-2.29.so。因此我们将libc.so.6和libc-2.29.so这两个文件拷贝到我们的riscv系统板的/lib目录下。 接着执行hello程序(此hello为动态链接的):

/ # hello

执行的结果依然是失败,为什么?

-/bin/sh: hello: not found

我们看下riscv系统的环境配置文件/etc/init.c/rcS:

#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin
runlevel=S
prevlevel=N
umask 022
export PATH runlevel prevlevel
mount -a
mdev -s

在PATH环境变量中没有/lib路径,所以会找不到/lib/libc.so.6。

我们将这个libc.so.6拷贝到/bin目录下,结果依然不能执行hello。

接下来如何做呢?还不知道,等知道如何解决后在更新该文档。

查看busybox的动态链接信息

由于busybox也是动态链接的,通过readelf -d busybox可以查看到busybox依赖于libc.so.6和libm.so.6。

为了加载动态链接库,需要ld-linux.so.3,因此我们将libc.so.6、libm.so.6和ld-linux.so.3这三个动态库拷贝到riscv系统平台的/lib目录。

但是:添加了这三个系统库后还是起不来?为什么?

遗留问题:

暂时没能解决动态链接时,hello不能执行的情况。