Help.....Embedded Linux uClibc, unable to run shared executables.
We have been using an embedded glibc toolchain for sometime. I recently bootstrapped an toolchain using uClibc (gcc-4.2.4, binutils-2.18, uClibc-0.29). The target is a broadcom chip which has a mips core it is strapped little-endian (mipsel).
All the libs are in /lib include the important ld-xxx [root@2WireBlockBuster /lib]# ls ld-uClibc-0.9.29.so libexpat.so librt.so ld-uClibc.so.0 libexpat.so.0 librt.so.0 libc.so.0 libexpat.so.0.5.0 libsqlite3.so libcrypt-0.9.29.so libgcc_s.so libssl.so libcrypt.so libgcc_s.so.1 libssl.so.0.9.8 libcrypt.so.0 libiw.so libstdc++.so libcrypto.so libiw.so.28 libstdc++.so.6 libcrypto.so.0.9.8 libm-0.9.29.so libstdc++.so.6.0.9 libcurl.so libm.so.0 libthread_db-0.9.29.so libcurl.so.4 libmpg123.so libthread_db.so libcurl.so.4.0.1 libpthread-0.9.29.so libthread_db.so.1 libdaemon.so libpthread.so libuClibc-0.9.29.so libdaemon.so.0 libpthread.so.0 libutil-0.9.29.so libdaemon.so.0.4.0 libresolv-0.9.29.so libutil.so libdl-0.9.29.so libresolv.so libutil.so.0 libdl.so libresolv.so.0 modules libdl.so.0 librt-0.9.29.so I can link and run static executables, but when I try to run a dynamically linked executable I get: [root@2WireBlockBuster /bin]# ./mount -sh: ./mount: not found This happens to any dynamically linked executable By running a statically linked ldd shows that the .so(es) are where they are supposed to be: [root@2WireBlockBuster /bin]# ./ldd mount checking sub-depends for '/lib/libc.so.0' ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x2aaa8000) libc.so.0 => /lib/libc.so.0 (0x00000000) /lib/ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x00000000) Has anyone had this problem. Did I miss a step? I've pasted the makefile used to build the toolchain below? Thanks, Jackson USE_UCLIBC=1 TOP=./.. include $(TOP)/build/cfg/top.mk BUILD_DIR = $(BASE_BUILD_DIR) #TOOLCHAIN_KERNEL=linux-2.6.18-brcm-5.0 TOOLCHAIN_KERNEL=linux-2.6.18-brcm-6.2 KERNEL_ARCH=mips PARALLLELMFLAGS?=-j4 toolchain: kernel-headers uClibc-headers binutils gcc-bootstrap uClibc-bootstrap gcc-full uClibc gettext pkg-config \ remove-la_files install-intltool install-gtkdoc squashfs mkappimage mkappimagebb stripkernel kernel-headers: config-kernel-headers copy-kernel-headers uClibc-headers: config-uClibc-headers install-uClibc-headers binutils: config-binutils build-binutils install-binutils gcc-bootstrap: config-gcc-bootstrap build-gcc-bootstrap install-gcc-bootstrap uClibc-bootstrap: config-uClibc-bootstrap build-uClibc-bootstrap install-uClibc-bootstrap gcc-full: config-gcc-full build-gcc-full install-gcc-full uClibc: config-uClibc build-uClibc install-uClibc pkg-config: config-pkg-config build-pkg-config install-pkg-config gdb: config-gdb build-gdb install-gdb gettext: config-gettext build-gettext install-gettext gdbnative: config-gdbnative build-gdbnative install-gdbnative gdbserver: config-gdbserver build-gdbserver install-gdbserver squashfs: build-squashfs install-squashfs mkappimage: build-mkappimage install-mkappimage mkappimagebb: build-mkappimagebb install-mkappimagebb stripkernel: build-stripkernel install-stripkernel ################################################################################## # 1. Set up kernel headers, now using the headers_check with ARCH. # config-kernel-headers: $(MAKE) -C $(TOP)/kernel config-kernel copy-kernel-headers: rm -rf $(PREFIX) mkdir -p $(SYSROOT) mkdir -p $(HEADER_DIR) rm -rf $(HEADER_DIR)/linux rm -rf $(HEADER_DIR)/asm rm -rf $(HEADER_DIR)/asm-generic cd $(KERNEL_DIR) && \ cp -r include/linux $(HEADER_DIR) && \ cp -r include/asm-$(KARCH) $(HEADER_DIR)/asm && \ cp -r include/asm-generic $(HEADER_DIR)/asm-generic # RJJ this method is broken in this kernel. Maybe 2.6.18-brcm-5.1? I doubt it #config-kernel-headers: # cd $(TOP)/kernel/$(TOOLCHAIN_KERNEL) && \ # make mrproper && \ # make ARCH=$(KERNEL_ARCH) headers_check # #copy-kernel-headers: # rm -rf $(PREFIX) # mkdir -p $(SYSROOT) # cd $(TOP)/kernel/$(TOOLCHAIN_KERNEL) && \ # make ARCH=$(KERNEL_ARCH) INSTALL_HDR_PATH=$(SYSROOT) headers_install # cp $(TOP)/kernel/$(TOOLCHAIN_KERNEL)/arch/mips/include/asm/asm.h $(SYSROOT)/include/asm/ # cp $(TOP)/kernel/$(TOOLCHAIN_KERNEL)/arch/mips/include/asm/regdef.h $(SYSROOT)/include/asm/ # # ################################################################################## ################################################################################## # 2. Build Inital headers for bootstrap compiler) # config-uClibc-headers: @echo "Configuring uClibc-headers" rm -rf $(BUILD_DIR)/uClibc-headers mkdir -p $(BUILD_DIR) cp -a $(UCLIBC_DIR) $(BUILD_DIR) mv $(BUILD_DIR)/$(UCLIBC_VER) $(BUILD_DIR)/uClibc-headers chmod +w -R $(BUILD_DIR)/uClibc-headers install-uClibc-headers: @echo "Installing uClibc-headers" PATH="$(PATH):$(PREFIX)/bin"; export PATH; \ cd $(BUILD_DIR)/uClibc-headers && \ make PREFIX=$(SYSROOT) install_headers # # ################################################################################## ################################################################################## # 2. build binutils (as, ar, ld, ranlib, nm, etc) # config-binutils: @echo "Configuring binutils" rm -rf $(BUILD_DIR)/binutils mkdir -p $(BUILD_DIR)/binutils AR=$(CROSS_COMPILE)ar AS=$(CROSS_COMPILE)as \ cd $(BUILD_DIR)/binutils && \ $(BINUTILS_DIR)/configure \ --prefix=$(PREFIX) \ --build=$(HOST) \ --host=$(HOST) \ --target=$(TARGET) \ --with-sysroot=$(PREFIX) \ --with-lib-path=$(SYSROOT)/lib \ --enable-shared \ --enable-multilib \ --disable-werror # cp -a $(BINUTILS_DIR)/* $(BUILD_DIR)/binutils build-binutils: @echo "Building binutils" cd $(BUILD_DIR)/binutils && \ make -j4 install-binutils: @echo "Installing binutils" cd $(BUILD_DIR)/binutils && \ make install # # ################################################################################## ################################################################################## # 3. build bootstrap gcc (used to compile glibc bootstrap) # config-gcc-bootstrap: echo "Configuring gcc bootstrap compiler" rm -rf $(BUILD_DIR)/gcc-bootstrap mkdir -p $(BUILD_DIR)/gcc-bootstrap PATH="$(PATH)"; export PATH; \ cd $(BUILD_DIR)/gcc-bootstrap && \ $(GCC_DIR)/configure \ --prefix=$(PREFIX) \ --build=$(HOST) \ --host=$(HOST) \ --target=$(TARGET) \ --with-sysroot=$(SYSROOT) \ --disable-__cxa_atexit \ --with-gnu-ld \ --with-gnu-as \ --disable-shared \ --disable-libssp \ --disable-libmudflap \ --disable-libgomp \ --enable-threads \ --disable-multilib \ --disable-nls \ --enable-c99 \ --enable-long-long \ --with-abi=32 \ --with-tune-mips1 \ --enable-languages=c build-gcc-bootstrap: echo "Building gcc bootstrap compiler" PATH="$(PATH)"; export PATH; \ cd $(BUILD_DIR)/gcc-bootstrap && \ make all-gcc -j4 install-gcc-bootstrap: echo "Installing gcc bootstrap compiler" mkdir -p $(BUILD_DIR)/gcc-bootstrap/$(TARGET)/libiberty echo "install:" > $(BUILD_DIR)/gcc-bootstrap/$(TARGET)/libiberty/Makefile PATH="$(PATH)"; export PATH; \ cd $(BUILD_DIR)/gcc-bootstrap && \ make install # # ################################################################################## ################################################################################## # 4. Build uClibc bootstrap (may not need to do a full) # config-uClibc-bootstrap: @echo "Configuring uClibc-bootstrap" rm -rf $(BUILD_DIR)/uClibc-bootstrap cp -a $(UCLIBC_DIR) $(BUILD_DIR) mv $(BUILD_DIR)/$(UCLIBC_VER) $(BUILD_DIR)/uClibc-bootstrap chmod +w -R $(BUILD_DIR)/uClibc-bootstrap build-uClibc-bootstrap: @echo "Building uClibc-bootstrap" PATH="$(PATH):$(PREFIX)/bin"; export PATH; export SYSROOT; \ cd $(BUILD_DIR)/uClibc-bootstrap && \ make -j1 install-uClibc-bootstrap: @echo "Installing uClibc-bootstrap" PATH="$(PATH):$(PREFIX)/bin"; export PATH; \ cd $(BUILD_DIR)/uClibc-bootstrap && \ make PREFIX=$(SYSROOT) install # # ################################################################################## ################################################################################## # 5. Build full gcc now that glibc has been built. This is a non-static version # of gcci (unlike the bootstrap), g++, gcj, libgcj and classpath. # config-gcc-full: @echo "Configuring gcc full" rm -rf $(BUILD_DIR)/gcc mkdir -p $(BUILD_DIR)/gcc PATH="$(PATH):$(PREFIX)/bin"; export PATH; \ cd $(BUILD_DIR)/gcc && \ LDFLAGS="-Wl,-rpath,$(SYSROOT)/lib" \ $(GCC_DIR)/configure \ --prefix=$(PREFIX) \ --build=$(HOST) \ --host=$(HOST) \ --target=$(TARGET) \ --with-sysroot=$(SYSROOT) \ --disable-__cxa_atexit \ --with-gnu-ld \ --with-gnu-as \ --enable-shared \ --enable-threads-posix \ --disable-multilib \ --with-abi=32 \ --with-tune=mips1 \ --enable-languages=c,c++,java \ --enable-c99 \ --enable-long-long \ --disable-libmudflap \ --disable-libssp \ --disable-libgomp \ --disable-nls \ --without-x \ --disable-jvmpi \ --disable-java-awt \ --disable-java-swing \ --disable-interpreter build-gcc-full: @echo "Building gcc full" PATH="$(PATH):$(PREFIX)/bin"; export PATH; \ cd $(BUILD_DIR)/gcc && \ make AS_FOR_TARGET=$(CROSS_COMPILE)as \ LD_FOR_TARGET=$(CROSS_COMPILE)ld -j4 install-gcc-full: @echo "Installing gcc full" PATH="$(PATH):$(PREFIX)/bin"; export PATH; \ cd $(BUILD_DIR)/gcc && \ make install -j1 # # ################################################################################## ################################################################################## # 6. Build Full uClibc, actually same except with full gcc compiler # config-uClibc: @echo "Configuring uClibc" rm -rf $(BUILD_DIR)/uClibc cp -a $(UCLIBC_DIR) $(BUILD_DIR) mv $(BUILD_DIR)/$(UCLIBC_VER) $(BUILD_DIR)/uClibc chmod +w -R $(BUILD_DIR)/uClibc build-uClibc: @echo "Building uClibc" PATH="$(PATH):$(PREFIX)/bin"; export PATH; export SYSROOT; \ cd $(BUILD_DIR)/uClibc && \ make -j1 cd $(BUILD_DIR)/uClibc/utils && \ make -j1 install-uClibc: @echo "Installing uClibc" PATH="$(PATH):$(PREFIX)/bin"; export PATH; \ cd $(BUILD_DIR)/uClibc && \ make PREFIX=$(PREFIX) install mkdir -p $(SYSROOT)/sbin cp $(BUILD_DIR)/uClibc/utils/ldconfig $(SYSROOT)/sbin cp $(BUILD_DIR)/uClibc/utils/iconv $(SYSROOT)/bin cp $(BUILD_DIR)/uClibc/utils/ldd $(SYSROOT)/bin cp $(BUILD_DIR)/uClibc/utils/readelf $(SYSROOT)/bin # # ################################################################################## config-gettext: @echo "Configuring gettext" rm -rf $(BUILD_DIR)/gettext mkdir -p $(BUILD_DIR)/gettext chmod +w $(GETTEXT_DIR)/configure PATH="$(PATH):$(PREFIX)/bin"; export PATH; \ cd $(BUILD_DIR)/gettext \ AR=$(CROSS_COMPILE)ar AS=$(CROSS_COMPILE)as && \ $(GETTEXT_DIR)/configure \ --prefix=$(SYSROOT) \ --target=$(TARGET) \ --host=$(TARGET) \ --disable-libasprintf \ --enable-shared \ --disable-openmp \ --disable-rpath \ --enable-relocatable \ --without-libintl-prefix \ --with-included-gettext \ --without-libpth-prefix build-gettext: @echo "Building gettext" cd $(BUILD_DIR)/gettext && \ make -j4 install-gettext: @echo "Installing gettext" cd $(BUILD_DIR)/gettext && \ make install chmod -w $(GETTEXT_DIR)/configure config-pkg-config: @echo "Configuring pkg-config" rm -rf $(BUILD_DIR)/pkg-config mkdir -p $(BUILD_DIR)/pkg-config PATH="$(PATH):$(PREFIX)/bin"; export PATH; \ cd $(BUILD_DIR)/pkg-config \ AR=ar AS=as && \ $(PKG-CONFIG_DIR)/configure \ --prefix=$(PREFIX) \ --target=$(HOST) \ --host=$(HOST) build-pkg-config: @echo "Building pkg-config" cd $(BUILD_DIR)/pkg-config && \ make -j4 install-pkg-config: @echo "Installing pkg-config" cd $(BUILD_DIR)/pkg-config && \ make install install-intltool: cp $(INTLTOOL_DIR)/* $(PREFIX)/bin install-gtkdoc: cp $(GTKDOC_DIR)/* $(PREFIX)/bin install-automake: cp $(AUTOMAKE_DIR)/* $(PREFIX)/bin install-autoconf: cp $(AUTOCONF_DIR)/* $(PREFIX)/bin install-aclocal: remove-la_files: @echo "Removing .la files from libs" rm $(SYSROOT)/lib/*.la ################################################################################## # 7. Build the debugger # ifeq ($(ARCH),pcdev) EXTRA_GDB_OPTS=--program-prefix=$(CROSS_COMPILE) endif config-gdb: @echo "Configuring gdb" rm -rf $(BUILD_DIR)/gdb mkdir -p $(BUILD_DIR)/gdb PATH="$(PATH)"; export PATH; \ cd $(BUILD_DIR)/gdb && \ $(GDB_DIR)/configure \ --prefix=$(PREFIX) \ --target=$(TARGET) \ --program-prefix=$(CROSS_COMPILE) build-gdb: @echo "Building gdb" PATH="$(PATH)"; export PATH; \ cd $(BUILD_DIR)/gdb && \ make install-gdb: @echo "Installing gdb" PATH="$(PATH)"; export PATH; \ cd $(BUILD_DIR)/gdb && \ make install # # ################################################################################## ################################################################################## # 8. This is for building a MIPS NATIVE version of the debugger can only be build # AFTER libs dir is built (for ncurses) could even put this in "utils" # makefile... This runs too slow on Mediaportal/Mediapoint to be pratical # config-gdbnative: @echo "Configuring gdb native" rm -rf $(BUILD_DIR)/gdbnative mkdir -p $(BUILD_DIR)/gdbnative PATH="$(PATH)"; export PATH; \ export bash_cv_have_mbstate_t=yes; \ export LDFLAGS="-L$(ULIB_DIR)/lib"; \ export CFLAGS="-I$(ULIB_DIR)/include"; \ cd $(BUILD_DIR)/gdbnative && \ $(GDB_DIR)/configure \ --prefix=$(ULIB_DIR) \ --host=$(TARGET) \ --target=$(TARGET) \ --build=$(HOST) build-gdbnative: @echo "Building gdb native" PATH="$(PATH)"; export PATH; \ export bash_cv_have_mbstate_t=yes; \ export CPPFLAGS="-I$(ULIB_DIR)/include"; \ cd $(BUILD_DIR)/gdbnative && \ make LDFLAGS="-L$(ULIB_DIR)/lib" \ CFLAGS="-I$(ULIB_DIR)/include" install-gdbnative: # @echo "Installing gdb native" # PATH="$(PATH)"; export PATH; \ # cd $(BUILD_DIR)/gdbnative && \ # make install # # ################################################################################## ################################################################################## # 9. gdbserver is a debug stub that runs on target machine. This does not work # so well, but is slowly getting better as mips support in glibc gets better. # I don't know about uClibc. # config-gdbserver: @echo "Configuring gdbserver" rm -rf $(BUILD_DIR)/gdbserver mkdir -p $(BUILD_DIR)/gdbserver PATH="$(PATH):$(PREFIX)/bin"; export PATH; \ cd $(BUILD_DIR)/gdbserver && \ CC=$(CROSS_COMPILE)gcc \ LD_FOR_TARGET=$(CROSS_COMPILE)ld \ $(GDB_DIR)/gdb/gdbserver/configure \ --prefix=$(SYSROOT)/bin \ --host=$(TARGET) \ --target=$(TARGET) \ --with-sysroot=$(SYSROOT) build-gdbserver: @echo "Building gdbserver" PATH="$(PATH)"; export PATH; \ cd $(BUILD_DIR)/gdbserver && \ make # make LDFLAGS=-static install-gdbserver: @echo "Installing gdbserver" PATH="$(PATH)"; export PATH; \ cd $(BUILD_DIR)/gdbserver && \ make install # # ################################################################################## build-squashfs: @echo "Building squashfs" $(MAKE) -C $(SQUASHFS_DIR) install-squashfs: @echo "Installing squashfs" $(MAKE) -C $(SQUASHFS_DIR) install build-mkappimage: @echo "Building mkappimage" $(MAKE) -C mkappimage build-mkappimagebb: @echo "Building mkappimagebb" cd mkappimage && \ $(MAKE) -f Makefilebb install-mkappimage: @echo "Installing mkappimage" $(MAKE) -C mkappimage install install-mkappimagebb: @echo "Installing mkappimage" cd mkappimage && \ $(MAKE) -f Makefilebb install build-stripkernel: @echo "Building stripkernel" $(MAKE) -C stripkernel install-stripkernel: @echo "Installing stripkernel" $(MAKE) -C stripkernel install remove-toolchain: @echo "Removing toolchain install tree" $(E)-rm -rf $(PREFIX) clean-build: @echo "Cleaning build dir" rm -rf $(TOP)/output rm -rf $(PREFIX) |
If you run your executable under strace you'll be able to see what file(s) this executable tried to access.
|
statically linking strace, looks as if the executable cannot be found even though the file can be found.
[root@2WireBlockBuster /bin]# ./strace mount execve("/bin/mount", ["mount"], [/* 14 vars */]) = -1 ENOENT (No such file or directory) write(2, "strace: exec: No such file or dir"..., 40strace: exec: No such file or directory ) = 40 exit_group(1) = ? |
Quote:
Code:
./strace ./mount |
Good point, I forgot, I still got a similar result. Something weird about the filesystem. I can run scripts, just not dynamically linked executable. I had to link busybox statically just to get the box up.
[root@2WireBlockBuster /bin]# ./strace ./mount execve("./mount", ["./mount"], [/* 14 vars */]) = -1 ENOENT (No such file or directory) write(2, "strace: exec: No such file or dir"..., 40strace: exec: No such file or directory ) = 40 exit_group(1) = ? [root@2WireBlockBuster /bin]# Another executable. We have the real lsmod since we are using busybox 1.00 and its module utils don't support 2.6. I did try a newer busybox, but had the same problem anyway. [root@2WireBlockBuster /bin]# ./strace ./lsmod execve("./lsmod", ["./lsmod"], [/* 14 vars */]) = -1 ENOENT (No such file or directory) write(2, "strace: exec: No such file or dir"..., 40strace: exec: No such file or directory ) = 40 Doing an strace on a statically linked executable shows that strace works: [root@2WireBlockBuster /bin]# ./strace ./ldd execve("./ldd", ["./ldd"], [/* 14 vars */]) = 0 brk(0) = 0x450000 brk(0x450458) = 0x450458 set_thread_area(0x457440) = 0 ioctl(0, TIOCNXCL, {B115200 opost isig icanon echo ...}) = 0 ioctl(1, TIOCNXCL, {B115200 opost isig icanon echo ...}) = 0 write(2, "ldd: missing file arguments\n"..., 28ldd: missing file arguments ) = 28 write(2, "Try `ldd --help' for more informa"..., 39Try `ldd --help' for more information. ) = 39 exit_group(1) = ? [root@2WireBlockBuster /bin]# The problem starts early due to the fact that mount can't be found (I am using the linux-utils mount instead of busybox) when Linux cannot mount its "special" filesystems. Sending DHCP requests ., OK IP-Config: Got DHCP answer from 10.5.255.254, my address is 10.5.252.165 IP-Config: Complete: device=eth0, addr=10.5.252.165, mask=255.255.0.0, gw=10.5.0.1, host=10.5.252.165, domain=2wire.com, nis-domain=(none), bootserver=10.5.255.254, rootserver=10.5.251.61, rootpath= Looking up port of RPC 100003/3 on 10.5.251.61 Looking up port of RPC 100005/3 on 10.5.251.61 VFS: Mounted root (nfs filesystem). Freeing unused kernel memory: 160k freed init started: BusyBox v1.00 (2000.01.01-00:00+0000) multi-call binary Starting pid 38, console /dev/ttyS0: '/etc/init.d/rcS' Mounting proc filesystem. /etc/init.d/rcS: 16: mount: not found Mounting /var.../etc/init.d/rcS: 25: mount: not found failed! /etc/init.d/rcS: 47: cannot create /proc/sys/net/ipv4/icmp_echo_ignore_broadcasts: Directory nonexistent Mounting all special filesystems. /etc/init.d/rcS: 51: mount: not found /etc/init.d/rcS: 52: mount: not found /etc/init.d/rcS: 53: mount: not found /etc/init.d/rcS: 54: mount: not found /etc/init.d/rcS: 57: depmod: not found Loading modules: bcmdriver - /etc/init.d/rcS: 72: insmod: not found Setting hostname. Mounting /etc/config as JFFS2.../etc/init.d/rcS: 103: /bin/mount: not found => Creating config filesystem /etc/init.d/rcS: 103: /bin/flash_eraseall: not found /etc/init.d/rcS: 103: /bin/mount: not found Config filesystem created successfully. Factory reset detected Starting pid 73, console /dev/ttyS0: '/etc/init.d/rc' Configuring and Starting Network...done. Starting Network Interface Plugging Daemon:/etc/rc2.d/S10ifplugd: 65: /sbin/ifplugd: not found eth0. Starting system log daemon: syslogdstart-stop-daemon: unable to start /sbin/syslogd: No such file or directory klogdstart-stop-daemon: unable to start /sbin/klogd: No such file or directory . Starting NFS client daemons: portmapstart-stop-daemon: nothing in /proc - not mounted? rpc.statdstart-stop-daemon: nothing in /proc - not mounted? . Starting Telnet Server: telnetd. |
Very strange. Looks like something seriously messed.
I think may be for some reason your system only able to find file in the current directory. i.e you able run Code:
./strace Code:
$PWD/strace |
I figured it out. The interpreter path was incorrect. I patched gcc with a mips patch, but the patch also changed the interpreter patch from /lib to /tools/lib . I changed it back to /lib and rebuild. Now everything is fine.
It was not able to find the ld-uClib.so. I discovered this by statically linking readelf and looking at mount. |
All times are GMT -5. The time now is 07:16 PM. |