我有一个扎根的Sony阅读器PRS900,运行OEM linux内核2.6.23,我可以从SD存储卡驱动器上运行任意bash / sh脚本。 我想编译和执行C程序......但是我遇到了动态链接器问题。
我首先尝试在SD卡上加载gcc for arm(slackware 14' s),但即使使用LD_LIBRARY_PATH,sony也无法找到"大多数较新的elf .so库,虽然使用旧库的新程序实际上运行正常。 (我可以运行slackware-14" readelf"很好。但不是ar,或gcc ......)如果我尝试升级/lib/ld-linux.so.3,我会得到a"内核太旧"错误信息。
然后我尝试了一个旧的slackware 10版本的gcc,虽然这解决了精灵库"发现"问题 - 然后我得到一条非法指令"运行程序时出错。
所以 - 我需要在我的x86上为正确的ARM处理器制作一个gcc交叉编译器,然后用它来为sony重新编译gcc。 但是我不知道我必须使用哪种遗留版本的binutils,因为它汇编并链接到ELF格式,无论是在sony上工作还是中断。
索尼正在运行兼容arm6的MX31 EBX5016处理器。 索尼上的一些相关的OEM文件名是:
/lib/ld-2.5.so
/lib/ld-linux.so.3 -> ld-2.5.s
/lib/libc-2.5.so
/lib/libgcc_s.so.1
我知道,从内核来看,使用了gcc-4.2.0。 我更喜欢使用最新版本的gcc,它可以与我需要安装的任何传统binutils软件包一起使用。
如何确定我需要哪个版本的binutils,以及我对gcc有哪些选择? 谢谢!
答案 0 :(得分:2)
您可以在源代码分发服务网站上找到Sony使用的工具链:
http://www.sony.net/Products/Linux/Audio/PRS-900.html
似乎sourceryg++-4.2-28armeabi.src.rpm
是编译器。
我不建议在设备上运行编译器;它会很慢。
关于“非法指令”问题,您的编译器可能会生成过于新的指令,并且通过-march=armv6
可能只是解决它。
答案 1 :(得分:0)
索尼正在使用motavista linux发布的内核;根据montavista的说法,该内核的编译器是用binutils 2.17编写的。我无法找到任何方法来确定哪个binutils最初是从gnu项目本身的哪个版本的GCC开发的。甚至存储库上传日期也不一致...但我确实发现了哪个binutils montavista是用它开发的。
我能够制作的库存GCC源代码的工作交叉编译器的最低版本来自gcc-4.2.0,binutils 2.19.1和glibc-2.5使用glibc-ports -2.5用于arm处理器/ linux扩展。
本答案的其余部分详细介绍了如何从头开始构建交叉编译器,作为其他人想要为包含gnu c库的arm构建linux交叉编译器的参考;例如:gcc with eabi和glibc for linux:arm-linux-gnueabi- tool。
这是一个非常重要的问题,我希望我的笔记对其他人有用。
索尼阅读器PRS900使用EABI编译器来制作内核,它也被配置为小端。
当时Binutils正在从arm eabi-V4切换到eabi-V5,索尼的PRS-900 / lib / ld- *似乎期待设置eabi-5标志,否则会让人感到困惑。当与binutils链接时,人们可能会意外混合导致大部分问题的eabi 4和5目标文件,因为它将默认返回eabi-version 4链接:因此,确保eabi 4永远不会意外生成的方法,是编辑气体的默认头文件(Gnu ASsmebler),因此即使在构建交叉编译器库时它总是默认为eabi-5,除非明确告知不这样做。
例如:binutil中的这两个文件:
gas / config / te-armeabi.h< - 将EABI_VER4更改为 - > #define EABI_DEFAULT EF_ARM_EABI_VER5
gas / config / te-armlinuxeabi.h< - do same - > #define EABI_DEFAULT EF_ARM_EABI_VER5
使用代码源工具实际上比构建gcc工具链更容易, 从头开始(我将测试它们以查看它们是否也适用于内核模块) - 但是当我打算升级到更新的工具时 - 我需要知道如何从头开始这样做。
下面:我已经包含了一个脚本,它对于它包含的注释比对它的可用性更重要;例如:它不是为了运行而不是自动的 - 而是它被剪切并粘贴到一个shell中并用作一个备忘单,勾勒出工作的标志和必须操纵的文件来规避错误。它有意思是读的注释,虽然不完美 - 人类阅读错误消息应该能够从shell的错误消息中找出其余部分。
我无法让libmudflap,libgomp或libssp在gcc中工作 - 无论我怎么做,所以它们在GCC构建中被禁用,因为这三者都会导致不可解决的编译问题;但除此之外,这个脚本显示了构建“C”交叉编译器arm-linux-gnueabi-工具链所需的内容,它将编译和链接没有段错误或错误的Sony PRS-900二进制可执行文件。
一个注意事项: 它使用正确的CRC代码 NOT 构建内核模块,并且似乎sony在其网站上发布的内核(参见上一篇文章)与我索尼上的内核略有不同;虽然日期是相同的,我使用了来自我的实际索尼的/proc/config.gz。我打算打开一个单独的线程来解决这个问题...但至少有一个可以使用这个交叉编译器构建用户空间可执行文件而没有任何问题。
#!/bin/false
# Do not run this script directly, until you have read and edited source
# files appropriately. It's not automated. vim is a text editor...
# This script creates a toolchain in a local directory (not root).
# I made it to build a gcc toolchain on a USB memory stick,
# mounted under /media/memory1 on slackware14.
#
# Needed source files:
#
# binutils-2.19.1.tar.bz2
# gcc-core-4.2.0.tar.bz2
# linux-2.6.23_091126.tgz
# glibc-2.5.tar.bz2
# glibc-ports-2.5.tar.bz2
#
# and from the sony PRS-900, itself, you need file: /proc/config.gz
# To guarantee the kernel is compiled the same.
# First make a local script to set paths for the toolchain once it it built
# --------------
echo -e "\
#!--/bin/bash-- # but must run as . setArmEnvironment.rc \n\
# There are two kinds of binaries for cross compilation, the tool binaries\n\
# and libraries, and the target headers, libraries, etc.\n\
export CROSSROOT="\$PWD/.local"\n\
export TARGETROOT="\$PWD/.target"\n\
export PATH="\$PATH:\$CROSSROOT/bin"\n\
export LD_CONFIG_PATH="\$CROSSROOT/lib:\$LD_CONFIG_PATH"\n\
" > setArmEnvironment.rc
# ----------
# Next:
# Create the local binary and header directories for the cross compiler toolchain
# .local is the buld machines' local tools for arm development
# This is for the binaries for the machine doing the cross compiling.
mkdir .local
cd .local
ln -s . usr
ln -s . local
mkdir include
mkdir lib
mkdir bin
ln -s include sys-linux
cd ..
# Target is for the host tools, headers, etc. it is a pure ARM directory.
# Everthing here is potentially installable on the sony itself.
# And is what would appear on the SONY PRS-900 if it had a toolchain.
mkdir .target
cd .target
ln -s . usr
ln -s . local
mkdir include
mkdir lib
mkdir bin
ln -s include sys-linux
cd ..
# Now, we need to set the paths so that as we make build tools, we can
# use them from the shell we are in.
. setArmEnvironment.rc
# FIRST! ----------------------------------------------------------------------
# Problem: GCC supposedly needs some g-libc header files for proper target code
# generation...
# but they don't really exist until compiled -- so chicken-egg-rooster prob !
# Which to make first...
#
# Solve it by installing headers from uncompiled packages, using a broken gcc/binutils
# then, re-build and re-install proper header files -- re-build proper gcc... etc.
# build a broken binutils package.
tar -xf /tmp/binutils-2.19.1.tar.bz2
mkdir build.binutils.eabi
cd build.binutils.eabi
../binutils-2.19.1/configure --target=arm-eabi --prefix=$CROSSROOT
# Make with flags to prevent warning creep on newer GCC's compiling older code.
make CFLAGS="-Os -w"
make install
cd ..
# build a broken gcc core.
tar -xf /tmp/gcc-core-4.2.0.tar.bz2
mkdir build.gcc.eabi
cd build.gcc.eabi
../gcc-4.2.0/configure --target=arm-eabi --prefix=$CROSSROOT --enable-multilib --disable-libssp
make CFLAGS="-Os -w"
make install
cd ..
# Install kernel headers using first pass (broken) cross-compiler -------------
tar -xf /tmp/linux-2.6.23_091126.tgz
gzip -d config.gz
cp config linux-2.6.23_091126/.config
cd linux-2.6.23_091126
# The makefile is a little broken for use on slackware 14...
# edit so that:
# CROSS_COMPILE ?= arm-eabi-
# and make the two implicit rules explicit:
# eg: lines 425 and 1476 contain rules that need to be broken into two rules each:
# Here's a patch file to do it automatically -- paste as one quoted unit to shell:
# ******************** START ECHO DIFF COPY/PASTE
echo '192c192
< CROSS_COMPILE ?= /opt/timesys/toolchains/armv6j-linux/bin/armv6j-linux-
---
> CROSS_COMPILE ?= arm-eabi-
422c422
< config %config: scripts_basic outputmakefile FORCE
---
> %config: scripts_basic outputmakefile FORCE
424a425,428
> config: scripts_basic outputmakefile FORCE
> $(Q)mkdir -p include/linux include/config
> $(Q)$(MAKE) $(build)=scripts/kconfig $@
>
1472c1476,1479
< / %/: prepare scripts FORCE
---
> %/: prepare scripts FORCE
> $(Q)$(MAKE) KBUILD_MODULES=$(if $(CONFIG_MODULES),1) \
> $(build)=$(build-dir)
> /: prepare scripts FORCE
1475c1482
< %.ko: prepare scripts FORCE
---
> %%.ko: prepare scripts FORCE' > Makefile.diff
# ******************** END ECHO DIFF COPY/PASTE
# now apply the patch to the Makefile
patch Makefile Makefile.diff
# You might also need to edit
# vim linux scripts/unidef.c and search all instances of getline, replacing it with _getline to avoid stdio.h overloading conflict.
# This is not always necessary... but if you have the problem... that's the solution.
make ARCH=arm INSTALL_HDR_PATH=$TARGETROOT headers_install
cd ..
# DONE installing kernel header files somewhat sanitized...
------------------------ GLibc, headers install
## Create aliases for binutils so I don't need to fight with glibc...
cd .local/bin
for i in `ls arm-eabi-*`; do ln -s $i arm-linux${i##arm-eabi} ; done
cd ../..
# Now we need to build glibc-2.5 with the arm port (glibc-ports-2.5.tar.gz)
tar -xzf glibc-2.5.tar.gz
cd glibc-2.5
tar -xzf ../glibc-ports-2.5.tar.gz
mv glibc-ports-2.5 ports
# Steal configuration for arm from other processors... probably not needed.
cp sysdeps/wordsize-32/bits/wordsize.h bits # 32bits
cp sysdeps/i386/bits/endian.h bits # little endian
cd ..
# For the first pass, just make enough of libc to install the header files.
mkdir build.glibc.eabi
#bash # Enter a new shell, because path needs to be forced.
# CAUTION: You must not do this as superuser, or with write priveleges to
# the system directores, as there are bugs in the GLIBC install that
# will try to put them there even though they don't belong there in a cross
# compiler..!
(
cd build.glibc.eabi
export LD_LIBRARY_PATH=""
export PATH=$CROSSROOT/bin:$PATH
echo "libc_cv_forced_unwind=yes" > config.cache
echo "libc_cv_c_cleanup=yes" >> config.cache
echo "libc_cv_arm_tls=yes" >> config.cache # For posix threads, but maybe not.
../glibc-2.5/configure --with-binutils=$CROSSROOT/arm-eabi/bin --build=i686-linux --host=arm-linux --prefix=/usr --enable-kernel=2.6.23 --with-headers=$TARGETROOT/include --enable-add-ons --disable-profile --config-cache --disable-sanity-checks --with-tls --with-__thread
# Caution, this install will attempt to install to both --prefix=/usr AND install_root.
# Because any directories where actual compilation is unfinished will
# not make install_root= correctly, but default back to prefix.
# Therefore,
# Do not allow writes to local system directories, by not installing as root!
# ... AND ...
# You must run make install_headers twice so everything does end up in $TARGETROOT
make -k install-headers install_root=$TARGETROOT
make -k install-headers install_root=$TARGETROOT
# Manually install two files, ... or GCC won't build. Three if you want it all.
# Glibc has a *REAAAALY* crappy installer script ...
cp bits/stdio_lim.h $TARGETROOT/include/bits
touch $TARGETROOT/include/gnu/stubs.h
cp nptl/sysdeps/pthread/pthread.h $TARGETROOT/include
# Long-double is messed up ... I ran into this. :)
( cd $TARGETROOT/include/bits
sed '/ifndef.*NO_LONG_DOUBLE/,/#endif/d' < mathdef.h > mathdef.h.new
mv mathdef.h.new mathdef.h
)
# LIB-C woes.
# We don't have the core files made yet, but generally, linking for arm needs:
# ... elf-init.o crt1.o crti.o crtbegin.o [-L] [user.o's] [gcc lb] [C lb] crtend.o crtn.o
# Unfortunately, GCC uses these during configuration tests and to make libgcc.o
# so we need them NOW, even if they are a little wrong, to make gcc.
# What they are:
# crt1.o -- from glibc's Start.S --calls libc's __libc_csu_init, __libc_csu_fini
# crti.o -- gcc's default version is no good; but libc's is. defines prolog _init
# crtn.o -- ... ; defines function epilog _fini
# crtbegin.o and crtend.o are supplied by gcc, for constructors/destructors.
# elf-init.o -- I don't remember what it is, but it has fn's that gcc needs.
#
# so, we need to build the crt files -- and only them... as the rest can't be
# done yet. So we 'make' the crt's subdirectory.
make CFLAGS="-Os -w" ARCH=arm cross-compiling=yes csub/subdir_lib
# Manually install them in a place where the linker will find them...
cp csu/crt*.o $TARGETROOT/lib
# elf-init.o is only needed during the build of GCC. It should be removed
# after the new gcc is made, or if it causes errors when gcc is made for
# redundant symbols.
cp csu/elf-init.o $TARGETROOT/lib
) # finished with bash subtask. restore environment to normal.
# The .local tools we built previously are now basically useless
# I'll just move them, although you might want to remove them...
mv .local .local.eabi
# ****************************************************************************
# ----------------------------------------------------------------------------
# Build actual tools
# We must build gcc.linux.gnueabi in order for glibc programs to compile right...
# ----------------------------------------------------------------------------
# Create a clean .local directory
mkdir .local
cd .local
ln -s . usr
ln -s . local
mkdir include
mkdir lib
mkdir bin
ln -s include sys-linux
cd ..
# Rebuild the toolchain with the basic headers we just installed.
# First do bintools
# Be sure to Change the DEFAULT_EABI to version 5 before compiling gas.
mkdir build.binutils2.19.1.linux.gnueabi
cd build.binutils2.19.1.linux.gnueabi
../binutils-2.19.1/configure --target=arm-linux-gnueabi --prefix=$CROSSROOT --with-sysroot=$TARGETROOT
# Make with flags to prevent warning creep on newer GCC's compiling older code.
make CFLAGS="-O2 -w"
make install
cd ..
# !!!! Now for GCC.
mkdir build.gcc.linux.gnueabi
cd build.gcc.linux.gnueabi
../gcc-4.2.0/configure --target=arm-linux-gnueabi --prefix=$CROSSROOT --enable-multilib --disable-libssp --enable-shared --disable-libgomp --disable-werror --disable-libmudflap --with-sysroot=$TARGETROOT
make -j2
make install
cd ..
# Create the specs file for editing GCC's configuration if we want to...
arm-linux-gnueabi-gcc -dumpspecs > .local/arm-linux-gnueabi/lib/specs
# Edit the specs file, and make *startfile command read:
#
# %{!shared: %{pg|p|profile:gcrt1.o%s;pie:Scrt1.o%s;:crt1.o%s}} elf-init.o%s crti.o%s %{static:crtbeginT.o%s;shared|pie:crtbeginS.o%s;:crtbegin.o%s}
vim .local/arm-linux-gnueabi/lib/specs
# This edit will cause GCC to link the elf-init.o crti.o crt1.o crtn.o files (happily) from $TARGETROOT/lib where a user can easily install them.
# There are a few abused/problem header files... so fix them!
vim glibc-2.5/posix/regex_internal.h # line 393, changed static int to
#static reg_errcode_t build_wcs_upper_buffer (re_string_t *pstr) internal_function;
vim .target/include/asm/unistd.h # find line 410, comment it out...
# And do a softlink to fake out an abused header...
ln -s hwcap.h .target/include/asm/procinfo.h
# Now we can finally build a true libc...
mkdir build.glibc.gnueabi
( # Enter a new shell, because path needs to be forced.
rm -rf build.glibc.gnueabi/*
cd build.glibc.gnueabi
# GLibc errors out if it thinks LD_LIBRARY_PATH is set wrong, even if it's not.
# So disable it temporarily.
export LD_LIBRARY_PATH=""
echo "libc_cv_forced_unwind=yes" > config.cache # No crt1.o exists, yet...force
echo "libc_cv_ctors_header=yes" >> config.cache # constructor headers, yes?
echo "libc_cv_c_cleanup=yes" >> config.cache
echo "cross_compiling=yes" >> config.cache
echo "install_root=$TARGETROOT" > configparms # Where to really install target
export CFLAGS="-fgnu89-inline -D__OPTIMIZE__ -O2 "
../glibc-2.5/configure --build=i686 --host=arm-linux-gnueabi --prefix=/ --enable-kernel=2.6.23 --with-headers=$TARGETROOT/include --enable-add-ons --disable-profile --with-tls --with-__thread --cache-file=config.cache
make
make install-headers install_root=$TARGETROOT
make localedata/install-locales install_root=$TARGETROOT
) # End of subshell