linux 运行动态链接程序报错,/bin/sh: ./<file>: not found

错误现象

之前使用 qemu 搭建了 Linux 学习环境后 ,没关注到运行动态链接程序的问题。典型的错误日志如下:

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

修复方法

上述问题出现的原因是动态加载器没找到,sh 程序首先会让内核执行 exec 加载待运行的程序,内核识别到是一个elf 文件,并且发现是一个动态链接的程序,那么会去寻找动态加载器,如果找不到的话就会报上面的错误。通常动态加载器名称是 ld-linux-xxx。以 aarch64 为例,动态加载器在目录 /lib/ld-linux-aarch64.so.1,有时候它可能在 /lib64 下,但是无论如何,动态加载器的位置需要和 elf 文件中记录的名字一样,如果没有的话,拷贝一份即可。动态加载器的名字记录在 elf 文件中,我们可以通过下面的命令看到:

 $ strings test_linux | grep /lib/ld-linux
 /lib/ld-linux-aarch64.so.1

这个名称是可以通过链接选项指定的,-Wl,--dynamic-linker=/lib/ld-linux.aarch64.so.1

除了程序编译时采用静态链接的解决方案外,这里分享一下支持运行动态链接程序的方法。修复方案是找到这个文件,打包到根文件系统,然后运行程序的时候以这样的命令 /lib/ld-linux-aarch64.so.1 test_linux 即可。

这里给一个完整的打包脚本供大家参考。

#!/bin/bash

BUSYBOX_VERSION=1.30.1
CROSS_COMPILER=~/hm-toolchain/gcc-linaro-7.2.1-2017.11-x86_64_aarch64-linux-gnu/

# Remove the old files
sudo rm -rf rootfs
sudo rm -rf tmpfs
sudo rm -rf ramdisk*

# Copy busybox output files to the rootfs
sudo mkdir rootfs
sudo cp -raf ./busybox-${BUSYBOX_VERSION}/_install/*  rootfs/

# Create folders which required by the linux convention
sudo mkdir -p rootfs/proc/
sudo mkdir -p rootfs/sys/
sudo mkdir -p rootfs/tmp/
sudo mkdir -p rootfs/root/
sudo mkdir -p rootfs/var/
sudo mkdir -p rootfs/mnt/
sudo mkdir -p rootfs/lib/
sudo mkdir -p rootfs/dev/

# Download sample etc files with init procedure and copy it to rootfs
#  wget http://files.cnblogs.com/files/pengdonglin137/etc.tar.gz
#  tar -xf ./etc.tar.gz
#  sudo cp ./etc rootfs/ -arf
sudo cp -r ./busybox-${BUSYBOX_VERSION}/examples/bootfloppy/etc/ rootfs/

# Copy shared libraries to the rootfs
SO_PATH=${CROSS_COMPILER}/aarch64-linux-gnu/libc/lib
sudo cp -raf ${SO_PATH}/* rootfs/lib/

# Remove the .a
sudo rm rootfs/lib/*.a

# Strip the so and make it smaller
sudo aarch64-linux-gnu-strip rootfs/lib/*

# Create basic device nodes
sudo mknod rootfs/dev/tty1 c 4 1
sudo mknod rootfs/dev/tty2 c 4 2
sudo mknod rootfs/dev/tty3 c 4 3
sudo mknod rootfs/dev/tty4 c 4 4
sudo mknod rootfs/dev/console c 5 1
sudo mknod rootfs/dev/ttyAMA0 c 204 64
sudo mknod rootfs/dev/null c 1 3

# Create ext4 image file
sudo dd if=/dev/zero of=ramdisk_ext4.img bs=1M count=64
sudo mkfs.ext4 ramdisk_ext4.img

# Mount the ramdisk to tmpfs and copy all the files in the rootfs to the image.
# After that, unmount the tmpfs, thus ramdisk contains all rootfs/ files.
sudo mkdir -p tmpfs
sudo mount -t ext4 ramdisk_ext4.img ./tmpfs/
sudo cp -raf rootfs/* tmpfs/
sudo umount tmpfs
sudo rmdir tmpfs

# sudo gzip --best -c ramdisk > ramdisk.gz
# sudo mkimage -n "ramdisk" -A arm64 -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img

猜你喜欢

转载自blog.csdn.net/FJDJFKDJFKDJFKD/article/details/120853953