QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 12357|回复: 20

xscale_linux_be交叉编译工具制作[更新]

[复制链接]
发表于 2004-11-1 22:02:27 | 显示全部楼层 |阅读模式
HOWTO build arm-linux toolchain for ARM/XSCALE
----------------------------------------------

These instructions document how to build an arm-linux tool chain
that contains both little-endian and big-endian target libraries.
# 注意,你必须有一个至少是配置好的linux kernel.

1. Packages used:

binutils-2.14.tar.gz
gcc-3.3.2.tar.gz
glibc-2.2.5.tar.gz
glibc-linuxthreads-2.2.5.tar.gz

2. binutils-2.14

tar xvzf binutils-2.14.tar.gz
cd binutils-2.14
mkdir xscale_linux_be
cd xscale_linux_be
../configure --target=armbe-linux --prefix=/opt/xscale_linux_be --with-lib-path=/opt/xscale_linux_be/armbe-linux/lib --program-prefix=xscale_linux_be-

make
make install
chmod 777 /opt/xscale_linux_be


3. gcc-3.3.2 -- bootstrap gcc

tar xvzf gcc-3.3.2.tar.gz
cd gcc-3.3.2
cp $(ATTACHED t-linux file) gcc/config/arm/
# 替换Makefile.in文件中对GCC_FOR_TARGET的定义,增加-mbig-endian选项
perl -pi -e 's/GCC_FOR_TARGET = \$\(STAGE_CC_WRAPPER\) \$\$r\/gcc\/xgcc /GCC_FOR_TARGET = \$\(STAGE_CC_WRAPPER\) \$\$r\/gcc\/xgcc -mbig-endian /g' Makefile.in
cd gcc
# 替换Makefile.in文件中对GCC_FOR_TARGET的定义,增加-mbig-endian选项
perl -pi -e 's/GCC_FOR_TARGET = \$\(STAGE_CC_WRAPPER\) \.\/xgcc /GCC_FOR_TARGET = \$\(STAGE_CC_WRAPPER\) \.\/xgcc -mbig-endian /g' Makefile.in
cd config/arm
# 以下三条perl命令将t-arm-elf文件中的三个宏定义的注释符“#”去掉
perl -pi -e 's/^# MULTILIB_OPTIONS[ ]*\+= mlittle-endian\/mbig-endian/MULTILIB_OPTIONS += mlittle-endian\/mbig-endian/' t-arm-elf
perl -pi -e 's/^# MULTILIB_DIRNAMES[ ]*\+= le be/MULTILIB_DIRNAMES += le be/' t-arm-elf
perl -pi -e 's/^# MULTILIB_MATCHES[ ]*\+= mbig-endian=mbe mlittle-endian=ml/MULTILIB_MATCHES += mbig-endian=mbe mlittle-endian=ml/' t-arm-elf

#当前目录处于gcc-3.3.2/gcc/config/arm
cd ../../..
#回到gcc-3.3.2目录
export PATH=/opt/xscale_linux_be/bin:$PATH

mkdir xscale_linux_be
cd xscale_linux_be
#以下配置GCC,注意--with-headers需要指定你的snapgear uclinux kernel 的头文件位置。
../configure --program-prefix=xscale_linux_be- --prefix=/opt/xscale_linux_be --target=armbe-linux --disable-shared --disable-threads --with-headers=$(WHEREYOURSRCBEING)/snapgear/linux-2.4.x/include --with-gnu-as --with-gnu-ld --enable-multilib --enable-languages=c

perl -pi -e 's/^program_transform_cross_name = s,\^,\$\(target_alias\)-,/program_transform_cross_name = s,\^,xscale_linux_be-,/g' gcc/Makefile

# make的时候可能会出现gcc/Makefile 673行出错[缺少分割符],在gcc/Makefile673行,677行起始处增加TAB就可以了。
# 这个问题到是由什么引起的?照理说自动生成的Makefile不应该有问题
# 另外,make的时候同样会碰到xgcc no input file的错误,问题同样出在673,677行,在行末尾的"\"符号之后多了一个空格,删除这#
# 个空格,就可以了。
make
make install


4. glibc-2.2.5 (big-endian)

tar xvzf glibc-2.2.5.tar.gz
cd glibc-2.2.5
tar xvzf ../glibc-linuxthreads-2.2.5.tar.gz

# 增加arm target
perl -pi -e 's/i386/arm*)\n\tlibc_cv_gcc_unwind_find_fde=yes\n\tarch_minimum_kernel=2.0.10\n\t;;\n i386/' sysdeps/unix/sysv/linux/configure
# 注释掉此行
perl -pi -e 's/weak_alias \(__old_sys_nerr/\/\/ $&/' sysdeps/unix/sysv/linux/arm/errlist.c
# 注释掉此行
perl -pi -e 's/weak_alias \(__old_sys_nerr/\/\/ $&/' sysdeps/unix/sysv/linux/errlist.c

cd sysdeps/arm
patch -p0 < ../../Patch.armbe-strlen-fix

# 当前我们在glibc-2.2.5/sysdeps/arm目录下
cd ../..
# 切换到glibc-2.2.5目录

vi linuxthreads/sysdeps/pthread/pthread.h
- change line 163, "__thread" -> "__thr"
- change line 591, "__thread" -> "__thr"
vi linuxthreads/internals.h
- change line 555, "__thread" -> "__thr"
vi linuxthreads/sysdeps/unix/sysv/linux/bits/sigthread.h
- change line 36, "__thread" -> "__thr"
# 以下两行改变函数声明
vi stdio-common/sprintf.c
- line 30, change to "sprintf(char *s, const char *format, ...)"
vi stdio-common/sscanf.c
- line 30, change to "sscanf(const char *s, const char *format, ...)"
# 就是把134行的a1删掉,clobber list是指内联汇编的修饰列表
vi sysdeps/unix/sysv/linux/arm/sysdep.h
- line 134, remove "a1" from clobber list
# 主要是内联汇编没有换行符,有很多
vi sysdeps/arm/dl-machine.h
- add '\n\' to end of all macro asm lines (there is a _lot_ of them)

vi config.make.in
- change "slibdir=@libc_cv_slibdir@" to "slibdir=@libdir@"

vi sysdeps/unix/sysv/linux/arm/ioperm.c
- add include file <linux/input.h> to avoid compile error of BUS_ISA not defined.

mkdir xscale_linux_be
cd xscale_linux_be
export CC="xscale_linux_be-gcc -mbig-endian -finline-limit=10000"
export AR="xscale_linux_be-ar"
export RANLIB="xscale_linux_be-ranlib"
export LD="xscale-linux_be-ld -mbig-endian"
../configure armbe-linux --target=armbe-linux --prefix=/opt/xscale_linux_be/armbe-linux --build=i686-pc-linux-gnu --with-headers=$(WHEREYOURSRCBEING)/snapgear/linux-2.4.x/include --with-headers=/opt/xscale_linux_be/armbe-linux/sys-include --enable-add-ons=linuxthreads --enable-shared
make
make install

6. gcc-3.3.2 (c++, etc) full version

tar xvzf gcc-3.3.2.tar.gz
cd gcc-3.3.2

cp $(ATTACHED t-linux file) gcc/config/arm/
vi gcc/config/arm/t-linux
- remove all "-Dinhibit_libc" occruances

# 替换Makefile.in文件中对GCC_FOR_TARGET的定义,增加-mbig-endian选项
perl -pi -e 's/GCC_FOR_TARGET = \$\(STAGE_CC_WRAPPER\) \$\$r\/gcc\/xgcc /GCC_FOR_TARGET = \$\(STAGE_CC_WRAPPER\) \$\$r\/gcc\/xgcc -mbig-endian /g' Makefile.in
cd gcc
# 替换Makefile.in文件中对GCC_FOR_TARGET的定义,增加-mbig-endian选项
perl -pi -e 's/GCC_FOR_TARGET = \$\(STAGE_CC_WRAPPER\) \.\/xgcc /GCC_FOR_TARGET = \$\(STAGE_CC_WRAPPER\) \.\/xgcc -mbig-endian /g' Makefile.in
cd config/arm
# 以下三条perl命令将t-arm-elf文件中的三个宏定义的注释符“#”去掉
perl -pi -e 's/^# MULTILIB_OPTIONS[ ]*\+= mlittle-endian\/mbig-endian/MULTILIB_OPTIONS += mlittle-endian\/mbig-endian/' t-arm-elf
perl -pi -e 's/^# MULTILIB_DIRNAMES[ ]*\+= le be/MULTILIB_DIRNAMES += le be/' t-arm-elf
perl -pi -e 's/^# MULTILIB_MATCHES[ ]*\+= mbig-endian=mbe mlittle-endian=ml/MULTILIB_MATCHES += mbig-endian=mbe mlittle-endian=ml/' t-arm-elf

export PATH=/opt/xscale_linux_be/bin:$PATH

mkdir xscale_linux_be
cd xscale_linux_be
../configure --program-prefix=xscale_linux_be- --prefix=/opt/xscale_linux_be --target=armbe-linux --enable-multilib --with-headers=/opt/xscale_linux_be/armbe-linux/include --enable-languages=c,c++
perl -pi -e 's/int namelen/unsigned int namelen/' ../libjava/java/net/natInetAddress.cc
[ For big-endian ]
perl -pi -e 's/^CC_FOR_TARGET = \$\$r\/gcc\/xgcc/CC_FOR_TARGET = \$\$r\/gcc\/xgcc -mbig-endian /' Makefile
perl -pi -e 's/\$\$r\/gcc\/ -nostdinc\+\+ /\$\$r\/gcc\/ -nostdinc++ -mbig-endian /' Makefile
cd gcc
perl -pi -e 's/libstdc\+\+ /libstdc\+\+ -mbig-endian /' Makefile

make LDFLAGS="-mbig-endian"
make install

7. gdb-5.1.1

bzip2 -cd gdb-5.1.1.tar.bz2 | tar xvf -
cd gdb-5.1.1
mkdir xscale_linux_be
cd xscale_linux_be
../configure --prefix=/opt/xscale_linux_be --program-prefix=xscale_linux_be- --target=armbe-linux
make
make install

8. cd /
tar cvzf /opt/xscale_linux_be-toolchain-20040511.tar.gz /opt/xscale_linux_be

------------------------------------------------------------------------------

APPENDIX A -- modified t-linux for gcc-3.3.2

------------------------------------------------------------------------------
# Just for these, we omit the frame pointer since it makes such a big
# difference. It is then pointless adding debugging.
TARGET_LIBGCC2_CFLAGS = -fomit-frame-pointer -fPIC -Dinhibit_libc -D__gthr_posix
LIBGCC2_DEBUG_CFLAGS = -g0

# Don't build enquire
ENQUIRE=

LIB1ASMSRC = arm/lib1funcs.asm
LIB1ASMFUNCS = _udivsi3 _divsi3 _umodsi3 _modsi3 _dvmd_lnx

# MULTILIB_OPTIONS = mhard-float/msoft-float
# MULTILIB_DIRNAMES = hard-float soft-float
MULTILIB_OPTIONS = mlittle-endian/mbig-endian
MULTILIB_DIRNAMES = le be

# If you want to build both APCS variants as multilib options this is how
# to do it.
# MULTILIB_OPTIONS += mapcs-32/mapcs-26
# MULTILIB_DIRNAMES += apcs-32 apcs-26

EXTRA_MULTILIB_PARTS = crtbegin.o crtbeginS.o crtend.o crtendS.o crti.o crtn.o

LIBGCC = stmp-multilib
INSTALL_LIBGCC = install-multilib
T_CFLAGS = -Dinhibit_libc -D__gthr_posix_h

# Assemble startup files.
$(T)crti.o: $(srcdir)/config/arm/crti.asm $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-c -o $(T)crti.o -x assembler-with-cpp $(srcdir)/config/arm/crti.asm

$(T)crtn.o: $(srcdir)/config/arm/crtn.asm $(GCC_PASSES)
$(GCC_FOR_TARGET) $(GCC_CFLAGS) $(MULTILIB_CFLAGS) $(INCLUDES) \
-c -o $(T)crtn.o -x assembler-with-cpp $(srcdir)/config/arm/crtn.asm
------------------------------------------------------------------------------

------------------------------------------------------------------------------

APPENDIX B -- Patch.armbe-strlen-fix for glibc-2.2.5

------------------------------------------------------------------------------
--- strlen.S.orig 2003-06-30 14:55:04.000000000 +0200
+++ strlen.S 2003-06-30 14:58:16.000000000 +0200
@@ -53,11 +53,20 @@
ldrne r2, [r1], $4 @ and we continue to the next word
bne Laligned @
Llastword: @ drop through to here once we find a
+#ifdef __ARMEB__
+ tst r2, $0xff000000 @ word that has a zero byte in it
+ addne r0, r0, $1 @
+ tstne r2, $0x00ff0000 @ and add up to 3 bytes on to it
+ addne r0, r0, $1 @
+ tstne r2, $0x0000ff00 @ (if first three all non-zero, 4th
+ addne r0, r0, $1 @ must be zero)
+#else
tst r2, $0x000000ff @ word that has a zero byte in it
addne r0, r0, $1 @
tstne r2, $0x0000ff00 @ and add up to 3 bytes on to it
addne r0, r0, $1 @
tstne r2, $0x00ff0000 @ (if first three all non-zero, 4th
addne r0, r0, $1 @ must be zero)
+#endif
RETINSTR(mov,pc,lr)
END(strlen)
------------------------------------------------------------------------------
 楼主| 发表于 2004-11-1 22:08:30 | 显示全部楼层
更新了一下,昨天我在家里编译过,后面gcc full version & gdb我没有编译,前面的都没有问题,没有试因为家里机器太慢了,呵呵:)下次有空再试。
回复

使用道具 举报

发表于 2004-11-1 22:32:48 | 显示全部楼层
谢谢John,终于更新了,仅代表广大newbie们对你致以崇高的敬意。
回复

使用道具 举报

发表于 2004-11-1 23:14:45 | 显示全部楼层
我按照你的要求重新修改了Makefile文件,然后编译gcc通过,真没有想到困扰我这么多天的难题解决起来竟是如此的简单。至于怎么出现这种错误,我看到需要更新的t-linux文件里面的内容正好是出错的673和677,因此我想应该是我在编写这个t-linux文件的时候,没有注意文本排列的格式导致的,当时我是直接就copy过来了,什么都没有管,结果就出了这些问题。真是菜啊!像673和677这几行语句应该是有书写规范的吧,我一向对这些语法规则不太了解,不知道John能否讲解一下。非常感谢。
另外还有一个问题,你在文章开头提到“# 注意,你必须有一个至少是配置好的linux kernel.”,这是什么意思呢?我的OS 是MDK 10.1,其自带的kernel是2.6.8.1-mdk10.1,按理说kernel应该放在usr/src/linux下面,不过我的那个目录下面只有一个RPM的目录,别的什么都没有。我是否需要重新下载一个kernel来编译呢?如果是,那麽我在编译的时候是直接make menuconfig还是使用make ARCH=arm menuconfig呢?另外,下面所提到的“snapgear uclinux kernel 的头文件位置”是不是就是上面需要编译的那个kernel的位置呢?最后一个笨笨的问题,为什么是“uclinux kernel“呢?我们编译for Xscale的toolchain会跟uclinux有关系吗?
谢谢john,不好意思,又是一堆问题。
回复

使用道具 举报

 楼主| 发表于 2004-11-2 09:12:05 | 显示全部楼层
需要一个for xscale的内核,在制作交叉编译工具的第二步,编译bootstrap gcc的时候会将kernel的头文件copy到/opt/xscale_linux_be/armbe_linux/sysinclude目录,而编译glibc的时候会检查linux/version.h头文件,以确定kernel的版本,所以说需要有一个至少是配置好的kernel(version.h在配置的时候生成)。

snapgear包有三个kernel,2.0.x 2.4.x 2.6.x 其实都是uclinux kernel,配置的时候需指定make ARCH=arm menuconfig

673行,677行的问题首先是要加TAB,另外在“\”符号是续行的意思,就是把下面一行作为本行的延续。“\”符号后面不能有其他符号,就是这个问题。
回复

使用道具 举报

发表于 2004-11-2 12:04:13 | 显示全部楼层
谢谢,请问一定需要snapgear的kernel吗?我从网上下载的linux-2.6.8的kernel可以吗?snapgear的kennel没有找到,我在http://ftp.snapgear.org/pub/snapgear/src/看到一个压缩包,170M,不知道里面有什么东东,是不是在这里面呢?
谢谢了!非常感谢!
回复

使用道具 举报

 楼主| 发表于 2004-11-3 08:43:24 | 显示全部楼层
http://www.snapgear.org/snapgear/downloads.html下载snapgear的源代码包。

应该是可以用其他内核吧,因为交叉编译工具使用到的只是内核的头文件,当然,2.4和2.6相差比较多。

解压缩后的目录结构跟uClinux-dist差不多:
uClinux/distribution SOURCE
---------------------------

The sources in this build have come from many places. Everything in
this package is covered by some type of open source or public domain
license. GNU copyleft is the most prevelant, but check within each
package for its specific licsense if you have concerns.


The directories:

linux-2.0.x -- uClinux sources from cvs.uclinux.org
linux-2.4.x -- uClinux sources from cvs.uclinux.org
linux-2.6.x -- uClinux sources from cvs.uclinux.org

freeswan    -- FreeSWAN 1.97 from www.freeswan.org

lib         -- Application libraries. Includes uC-libc, libm and others.

uClibc      -- An alternate libc from www.uClibc.org

glibc       -- Standard GNU libc

user        -- User mode applications, source from many, many places.
               Too many places to enumerate, most are standard GNU/Linux
               packages, all are freely available on the net somewhere.
               Some applications have been specially developed for uClinux.

The following directories hold results of the build process:

config      -- A version of the linux config scripts that are used to
               drive the vendor/platform configuration.

vendors     -- holds plaform specific build information or support files.
               This is also the location where default build configurations
               are kept for each of the supported platforms.

romfs       -- Is the structrue of the root file system. Mostly it holds
               the user application binaries, but also has device nodes,
               configuration files, shared libraries, etc.

images      -- Contains the final build binaries of the kernel, root file
               system, and often a complete combined image.
回复

使用道具 举报

发表于 2004-11-4 22:41:28 | 显示全部楼层
谢谢john,太感谢了。gcc已经编译通过,在编译glibc-2.2.5的时候,在执行
patch -p0 < ../../Patch.armbe-strlen-fix
的时候,结果是
patching file strlen.S
patch: **** malformed patch at line 4: ldrne r2, [r1], $4 @ and we continue to the next word
我查了一下“malformed“,这个单词的意思是”残缺不全的“。请问这是个错误吗?
谢谢!
回复

使用道具 举报

发表于 2004-11-5 14:03:13 | 显示全部楼层
不好意思,还是有问题啊!在编译glibc-2.2.5的时候出了问题。我找不出原因,但是前面有些步骤不能确定是否正确,写出来,请john帮忙看看,谢谢!
我是这样配置内核的:
make mrproper
make ARCH=arm menuconfig
make include/linux/version.h
下面拷贝内核头文件
cp -dRf include/linux  /opt/xscale_linux_be/armbe-linux/sys-include
cp -dRf include/asm-arm  /opt/xscale_linux_be/armbe-linux/sys-include/asm

在修改文件sysdeps/arm/dl-machine.h的时候,在内联汇编中加入换行符,我只找到了一处需要添加,如下:
__asm __volatile ("swi 0x9f0002               @ sys_cacheflush" \n\    \
                    : /* no outputs */ \n\                                                  \
                    : /* no inputs  */  \n\                                                \                                 
                    : "a1");                                                                   \
加上了三个换行符,不知道加的对不对。请指点一下。
我的linux kernel放在/usr/src/linux-2.6.8中,所以--with-headers=/usr/src/linux-2.6.8/include,configure如下:
../configure armbe-linux --target=armbe-linux --prefix=/opt/xscale_linux_be/armbe-linux --build=i686-pc-linux-gnu --with-headers=/usr/src/linux-2.6.8/include --with-headers=/opt/xscale_linux_be/armbe-linux/sys-include --enable-add-ons=linuxthreads --enable-shared

最后出现的问题是:
/opt/xscale_linux_be/armbe-linux/sys-include/asm/param.h:13:45: asm/arch/param.h                                           : No such file or directory
In file included from /opt/xscale_linux_be/armbe-linux/sys-include/linux/sysctl.                                           h:23,
                 from ../sysdeps/unix/sysv/linux/sys/sysctl.h:28,
                 from ../include/sys/sysctl.h:2,
                 from ../sysdeps/unix/sysv/linux/dl-osinfo.h:21,
                 from ../sysdeps/unix/sysv/linux/init-first.c:33:
/opt/xscale_linux_be/armbe-linux/sys-include/linux/list.h:699:2: warning: #warni                                           ng "don't include kernel headers in userspace"
make[2]: *** [/home/jerry/download/sw/arm-linux/glibc-2.2.5/xscale_linux_be/csu/                                           init-first.o] 错误 1
make[2]: Leaving directory `/home/jerry/download/sw/arm-linux/glibc-2.2.5/csu'
make[1]: *** [csu/subdir_lib] 错误 2
make[1]: Leaving directory `/home/jerry/download/sw/arm-linux/glibc-2.2.5'
make: *** [all] 错误 2
麻烦帮忙看一下了,万分万分的感谢!
回复

使用道具 举报

发表于 2004-11-5 15:00:43 | 显示全部楼层
在google上面搜索了一下,没有找到解决的办法,但是有一个帖子可能有所启发,但是我看不懂。原文如此:
According to the results of a search in the LFS archives this sort of
problem is caused by incorect symbolic links. I have checked the and
made sure the /tools is a symbolics link to $LFS/tools and that
$LFS/tools/src is not a symbolic link. The problem still occours if I
run make from $LFS/tools/src/glibc-build.
在配置内核的时候是否需要甚至symlinks呢,我使用make symlinks命令,但是不能执行。
回复

使用道具 举报

 楼主| 发表于 2004-11-6 20:02:10 | 显示全部楼层
strlen patch的warning应该没有问题的。
头文件是不需要自己copy到目标目录的。
dl-machine.h中不止这一处需要修改,在这个头文件中很多内联汇编都被定义成宏了,所以你要加上\n\在行尾。
不应该用2.6.8内核,你应该选用snapgear自带的内核,BTW,你们的产品是用哪一套代码在开发呢?uClinux-dist,还是snapgear?
回复

使用道具 举报

发表于 2004-11-8 12:13:42 | 显示全部楼层
谢谢john。如果我不把头文件copy到目标目录,在编译到glibc的时候,就会出现类似于“kernle version is too old”的错误提示。也许这是没有使用snapgear的原因吧,我在试一试。
我们的产品是基于PXA255的开发板,我们不想使用uclinux,因为他不带MMU,所以我们只能使用普通的linux,snapgear是我找到的第一个开发包,所以一开始就想使用它了。
回复

使用道具 举报

 楼主| 发表于 2004-11-8 13:10:24 | 显示全部楼层
Jerry, 注意到第一次编译gcc的时候,配置选项中有--with-headers=.....,这时指定的内核头文件目录将会被自动copy到目标文件夹中,所以说在一开始就需要配置好内核。
另外,说到支持mmu的内核,snapgear作为独立的开发包从uclinux分离出来的目的之一也就是为了增加对一些带mmu的cpu得支持,我以前的项目使用ixp422,也选用snapgear没有问题。
回复

使用道具 举报

发表于 2004-11-8 14:25:29 | 显示全部楼层
谢谢john,我一直有一个疑问, snapgear提供的已经编译好的开发包arm-linux-tools-20031127.tar.gz和我们自己编译完的开发包之间有什么主要的区别呢?它提供的编译好的也支持Xscale啊。
回复

使用道具 举报

发表于 2004-11-8 23:27:09 | 显示全部楼层
我刚刚下载了snapgear的kernel,2.6.x的,make ARCH=arm menuconfig的时候,发现里面并没有支持PXA255的选项,最高只支持到PXA250,请问john,是不是还需要打补丁。或者我在编译交叉编译器的时候,使用snapgear的kernel,而在后来编译以后应用的kernel的时候,用linux-2.6.8的kernel。行吗?谢谢
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-5-22 11:01 , Processed in 0.135718 second(s), 15 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表