分类: 嵌入式
2012-07-09 13:27:13
交叉编译环境 arm-none-linux-gnueabi-gcc-4.5.1(CodeSourcery/Sourcery_G++_Lite)
编译后,运行uboot发现运行到
get_PLLCKL()函数是程序跑飞,进一步跟踪发现问题语句
return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s)); //CONFIG_SYS_CLK_FREQ mini2440.h中定义
用低版本gcc编译是可以运行的,我猜测是浮点运算库的问题,google一下
uboot可以使用自己的浮点运算库,查看lib_arm,并没有生成_divsi3.o
打开Makefile
GLSOBJS += _divsi3.o
LGOBJS := $(addprefix $(obj),$(GLSOBJS)) \
$(addprefix $(obj),$(GLCOBJS))
$(LIBGCC): $(obj).depend $(LGOBJS)
$(AR) $(ARFLAGS) $@ $(LGOBJS)
# Build private libgcc only when asked for
ifdef USE_PRIVATE_LIBGCC
TARGETS += $(LIBGCC)
endif
从makefile看出要定义 USE_PRIVATE_LIBGCC才可以编译uboot自己的浮点运算库
打开uboot顶层config.mk
export HOSTCC HOSTCFLAGS CROSS_COMPILE \
AS LD CC CPP AR NM STRIP OBJCOPY OBJDUMP MAKE
export TEXT_BASE PLATFORM_CPPFLAGS PLATFORM_RELFLAGS CPPFLAGS CFLAGS AFLAGS
export USE_PRIVATE_LIBGCC =yes
验证lib_arm下生成自己的浮点库
enzo@debian:~/u-boot-2009.08/lib_arm$ ls *.o
_ashldi3.o board.o cache-cp15.o div0.o eabi_compat.o _lshrdi3.o reset.o _umodsi3.o
_ashrdi3.o bootm.o cache.o _divsi3.o interrupts.o _modsi3.o _udivsi3.o
运行uboot,运行正常
新问题,uboot 采用Os编译又出问题,看来还是不用uboot自身的库吧
找个根本的解决办法
enzo@debian:~/u-boot-2009.08$ arm-linux-gcc -v
Reading specs from /home/enzo/gcc-3.4.5-glibc-2.3.6/bin/../lib/gcc/arm-linux/3.4.5/specs
Configured with: /work/tools/create_crosstools/crosstool-0.43/build/arm-linux/gcc-3.4.5-glibc-2.3.6/gcc-3.4.5/configure --target=arm-linux --host=i686-host_pc-linux-gnu --prefix=/work/tools/gcc-3.4.5-glibc-2.3.6 --with-float=soft --with-headers=/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux/include --with-local-prefix=/work/tools/gcc-3.4.5-glibc-2.3.6/arm-linux --disable-nls --enable-threads=posix --enable-symvers=gnu --enable-__cxa_atexit --enable-languages=c,c++ --enable-shared --enable-c99 --enable-long-long
Thread model: posix
gcc version 3.4.5
我先前用的交叉编译器支持的是硬浮点,不支持软浮点,现在换个支持软浮点的编译器
交叉编译器在编译的时候,对于浮点运行会预设硬浮点运算FPA(Float Point Architecture),而没有FPA的CPU,比如SAMSUNG S3C2410/S3C2440,会使用FPE(Float Point Emulation 即软浮点),这样在速度上就会遇到极大的限制,使用EABI(Embedded Application Binary
Interface)则可以对此改善处理,ARM EABI有许多革新之处,其中最突出的改进就是Float Point Performance,它使用Vector Float Point(矢量浮点),因此可以极大提高涉及到浮点运算的程序
Why ARM's EABI Matters
by Andres Calderon and Nelson Castillo
It's common nowadays to hear of the new ARM EABI (embedded application binary interface) Linux port. There are many motivations to start using it, but there is one we especially like -- it's much faster for floating point operations. Since many ARM cores lack a hardware FPU (floating point unit), any software acceleration is more than welcome.
It might be hard to switch to EABI, though. For instance, for the Debian distribution, EABI is actually considered a new port.
Without EABI
The ARM EABI improves the floating point performance. This is not surprising, if you read how your processor is wasting a lot of cycles now. From the Debian wiki:
The current Debian port creates hardfloat FPA instructions. FPA comes from "Floating Point Accelerator." Since the FPA floating point unit was implemented only in very few ARM cores, these days FPA instructions are emulated in kernel via Illegal instruction faults. This is of course very inefficient: about 10 times slower that -msoftfloat for a FIR test program. The FPA unit also has the peculiarity of having mixed-endian doubles, which is usually the biggest grief for ARM porters, along with structure packing issues.So, what does this mean? It means that the compilers usually generate instructions for a piece of hardware, namely a Floating Point Unit, that is not actually there! When you make a floating point operation, such at 3.58*x, the CPU runs into an illegal instruction, and it raises an exception. The kernel catches this specific exception and performs the intended float point operation, and then resumes executing the program. And this is slow because it implies a context switch.
CodeSourcery根据操作系统的不同,根据应用的不用所需要的标准库有所不同,ARM GCC有四个不同的版本:
1) arm-none-eabi 这个是没有操作系统的,自然不可能支持那些跟操作系统关系密切的函数,比如fork(2),他使用的是newlib这个专用于嵌入式系统的C库
2) arm-none-linux-eabi 用于Linux的,使用Glibc
3) arm-none-uclinuxeabi 用于uCLinux的,使用Glibc
4) arm-none-symbianelf 用于symbian的,我没用过不知道C库是什么
需要的话,去