
For some time there have been repeated reports about build problems with some ARM (cross) tool chains. Especially issues about (in)compatibility with the tool chain provided runtime support library libgcc.a caused to add and support a private implementation of such runtime support code in U-Boot. A closer look at the code indicated that some of these issues are actually home-made. This patch attempts to clean up some of the most obvious problems and make building of U-Boot with different tool chains easier:
- Even though all ARM systems basicy used the same compiler options to select a specific ABI from the tool chain, the code for this was distributed over all cpu/*/config.mk files. We move this one level up into lib_arm/config.mk instead.
- So far, we only checked if "-mapcs-32" was supported by the tool chain; if yes, this was used, if not, "-mabi=apcs-gnu" was selected, no matter if the tool chain actually understood this option. There was no support for EABI conformant tool chains. This patch implements the following logic:
1) If the tool chain supports "-mabi=aapcs-linux -mno-thumb-interwork" we use these options (EABI conformant tool chain). 2) Otherwise, we check first if "-mapcs-32" is supported, and then check for "-mabi=apcs-gnu" If one test succeeds, we use the first found option. 3) In case 2), we also test if "-mno-thumb-interwork", and use this if the test succeeds. [For "-mabi=aapcs-linux" we set "-mno-thumb-interwork" mandatorily.]
This way we use a similar logic for the compile options as the Linux kenrel does.
- Some EABI conformant tool chains cause external references to utility functions like raise(); such functions are provided in the new file lib_arm/eabi_compat.c
Note that lib_arm/config.mk gets parsed several times, so we must make sure to add eabi_compat.o only once to the linker list.
Signed-off-by: Wolfgang Denk wd@denx.de Cc: Jean-Christophe PLAGNIOL-VILLARD plagnioj@jcrosoft.com Cc: Dirk Behme dirk.behme@googlemail.com Cc: Magnus Lilja lilja.magnus@gmail.com Cc: Tom Rix Tom.Rix@windriver.com Cc: Prafulla Wadaskar prafulla@marvell.com ---
I have run a full "MAKEALL arm" for ELDK releases 3.1 (gcc 3.3.3), 3.1.1 (gcc 3.3.3), 4.1 (gcc 4.0.0) and 4.2 (gcc 4.2.2, both as "arm" [softfloat] and "armVFP" [VFP hardfloat]), and all of these both with USE_PRIVATE_LIBGCC=yes (i. e. using U-Boot internal libgcc replacement code) and without (i. e. using the tool chain provided standard libgcc instead).
The ELDK fails to build the big-endian IXP boards, but this is a restriction of the ELDK, not a new issue introcued by this patch. Except of this, all build were succesful.
Note 1: Please note that older tool chains (based on binutils versions older than 2.16) will have problems with the SORT_BY_ALIGNMENT() and SORT_BY_NAME() functions introduced to the linker scripts with commit f62fb99941c6. I'll soon submit a patch to fix this issue. Final tests are running right now.
Note 2: Even though this is a bigger change, I consider it a bug fix and therefor tend to have it included into the upcoming release. Of course this requires sufficient test coverage and feedback. Please help!!
Note 3: Most ARM systems also define this: PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) I guess this can be unified and moved to lib_arm/config.mk, too, but I would like to handle this in a separate, later patch. This makes testing (and bisecting) easier, and it is a non-critical problem.
config.mk | 2 +- cpu/arm1136/config.mk | 2 -- cpu/arm1176/config.mk | 2 -- cpu/arm1176/s3c64xx/config.mk | 1 - cpu/arm720t/config.mk | 2 -- cpu/arm920t/config.mk | 2 -- cpu/arm925t/config.mk | 2 -- cpu/arm926ejs/config.mk | 2 -- cpu/arm926ejs/davinci/config.mk | 2 -- cpu/arm946es/config.mk | 2 -- cpu/arm_cortexa8/config.mk | 1 - cpu/arm_cortexa8/omap3/board.c | 7 ------- cpu/arm_intcm/config.mk | 2 -- cpu/ixp/config.mk | 1 - cpu/lh7a40x/config.mk | 2 -- cpu/pxa/config.mk | 2 -- cpu/s3c44b0/config.mk | 2 -- cpu/sa1100/config.mk | 2 -- lib_arm/Makefile | 15 ++++++++++++--- lib_arm/config.mk | 28 ++++++++++++++++++++++++++++ lib_arm/eabi_compat.c | 18 ++++++++++++++++++ 21 files changed, 59 insertions(+), 40 deletions(-) create mode 100644 lib_arm/eabi_compat.c
diff --git a/config.mk b/config.mk index fd56621..0c6d1d1 100644 --- a/config.mk +++ b/config.mk @@ -86,7 +86,7 @@ ifdef ARCH sinclude $(TOPDIR)/lib_$(ARCH)/config.mk # include architecture dependend rules endif ifdef CPU -sinclude $(TOPDIR)/cpu/$(CPU)/config.mk # include CPU specific rules +sinclude $(TOPDIR)/cpu/$(CPU)/config.mk # include CPU specific rules endif ifdef SOC sinclude $(TOPDIR)/cpu/$(CPU)/$(SOC)/config.mk # include SoC specific rules diff --git a/cpu/arm1136/config.mk b/cpu/arm1136/config.mk index 295e8a5..61d5a38 100644 --- a/cpu/arm1136/config.mk +++ b/cpu/arm1136/config.mk @@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv5 # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm1176/config.mk b/cpu/arm1176/config.mk index d2f057b..a31c7b0 100644 --- a/cpu/arm1176/config.mk +++ b/cpu/arm1176/config.mk @@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv5t # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm1176/s3c64xx/config.mk b/cpu/arm1176/s3c64xx/config.mk index 4f3b66c..a31c7b0 100644 --- a/cpu/arm1176/s3c64xx/config.mk +++ b/cpu/arm1176/s3c64xx/config.mk @@ -30,5 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv5t # Supply options according to compiler version # # ========================================================================= -#PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm720t/config.mk b/cpu/arm720t/config.mk index 3cae1dc..74d5283 100644 --- a/cpu/arm720t/config.mk +++ b/cpu/arm720t/config.mk @@ -31,6 +31,4 @@ PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm920t/config.mk b/cpu/arm920t/config.mk index 5d8a10f..a43b156 100644 --- a/cpu/arm920t/config.mk +++ b/cpu/arm920t/config.mk @@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv4 # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm925t/config.mk b/cpu/arm925t/config.mk index 5d8a10f..a43b156 100644 --- a/cpu/arm925t/config.mk +++ b/cpu/arm925t/config.mk @@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv4 # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm926ejs/config.mk b/cpu/arm926ejs/config.mk index 885d5c1..90eb3c0 100644 --- a/cpu/arm926ejs/config.mk +++ b/cpu/arm926ejs/config.mk @@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv5te # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm926ejs/davinci/config.mk b/cpu/arm926ejs/davinci/config.mk index a57d03a..7757be3 100644 --- a/cpu/arm926ejs/davinci/config.mk +++ b/cpu/arm926ejs/davinci/config.mk @@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv5te # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm946es/config.mk b/cpu/arm946es/config.mk index 9d62ba8..a81321b 100644 --- a/cpu/arm946es/config.mk +++ b/cpu/arm946es/config.mk @@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv4 # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/arm_cortexa8/config.mk b/cpu/arm_cortexa8/config.mk index 3bfe3db..da5ee16 100644 --- a/cpu/arm_cortexa8/config.mk +++ b/cpu/arm_cortexa8/config.mk @@ -30,6 +30,5 @@ PLATFORM_CPPFLAGS += -march=armv5 # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,\ $(call cc-option,-malignment-traps,)) diff --git a/cpu/arm_cortexa8/omap3/board.c b/cpu/arm_cortexa8/omap3/board.c index 2337287..b8bd052 100644 --- a/cpu/arm_cortexa8/omap3/board.c +++ b/cpu/arm_cortexa8/omap3/board.c @@ -300,13 +300,6 @@ int dram_init(void) /****************************************************************************** * Dummy function to handle errors for EABI incompatibility *****************************************************************************/ -void raise(void) -{ -} - -/****************************************************************************** - * Dummy function to handle errors for EABI incompatibility - *****************************************************************************/ void abort(void) { } diff --git a/cpu/arm_intcm/config.mk b/cpu/arm_intcm/config.mk index 9d62ba8..a81321b 100644 --- a/cpu/arm_intcm/config.mk +++ b/cpu/arm_intcm/config.mk @@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv4 # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/ixp/config.mk b/cpu/ixp/config.mk index a71a20b..2c33b40 100644 --- a/cpu/ixp/config.mk +++ b/cpu/ixp/config.mk @@ -33,5 +33,4 @@ PLATFORM_CPPFLAGS += -mbig-endian -march=armv5te -mtune=strongarm1100 # Supply options according to compiler version # # ========================================================================= -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/lh7a40x/config.mk b/cpu/lh7a40x/config.mk index c0e7a1d..27bc481 100644 --- a/cpu/lh7a40x/config.mk +++ b/cpu/lh7a40x/config.mk @@ -30,6 +30,4 @@ PLATFORM_CPPFLAGS += -march=armv4 # Supply options according to compiler version # # ======================================================================== -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/pxa/config.mk b/cpu/pxa/config.mk index af910e2..f360478 100644 --- a/cpu/pxa/config.mk +++ b/cpu/pxa/config.mk @@ -31,6 +31,4 @@ PLATFORM_CPPFLAGS += -march=armv5te -mtune=xscale # Supply options according to compiler version # # ======================================================================== -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/s3c44b0/config.mk b/cpu/s3c44b0/config.mk index 01e7040..3623f25 100644 --- a/cpu/s3c44b0/config.mk +++ b/cpu/s3c44b0/config.mk @@ -31,6 +31,4 @@ PLATFORM_CPPFLAGS += -march=armv4 -mtune=arm7tdmi -msoft-float # Supply options according to compiler version # # ======================================================================== -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/cpu/sa1100/config.mk b/cpu/sa1100/config.mk index 9ef4a19..553cd0c 100644 --- a/cpu/sa1100/config.mk +++ b/cpu/sa1100/config.mk @@ -31,6 +31,4 @@ PLATFORM_CPPFLAGS += -march=armv4 -mtune=strongarm1100 # Supply options according to compiler version # # ======================================================================== -PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu) -PLATFORM_CPPFLAGS +=$(call cc-option,-mno-thumb-interwork,) PLATFORM_RELFLAGS +=$(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/lib_arm/Makefile b/lib_arm/Makefile index c37e2e0..0293348 100644 --- a/lib_arm/Makefile +++ b/lib_arm/Makefile @@ -51,12 +51,21 @@ OBJS := $(addprefix $(obj),$(SOBJS-y) $(COBJS-y)) LGOBJS := $(addprefix $(obj),$(GLSOBJS)) \ $(addprefix $(obj),$(GLCOBJS))
+# Always build libarm.a +TARGETS := $(LIB) + +# Build private libgcc only when asked for ifdef USE_PRIVATE_LIBGCC -all: $(LIB) $(LIBGCC) -else -all: $(LIB) +TARGETS += $(LIBGCC) +endif + +# For EABI conformant tool chains, provide eabi_compat() +ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS))) +TARGETS += $(obj)eabi_compat.o endif
+all: $(TARGETS) + $(LIB): $(obj).depend $(OBJS) $(AR) $(ARFLAGS) $@ $(OBJS)
diff --git a/lib_arm/config.mk b/lib_arm/config.mk index a13603e..705dfc3 100644 --- a/lib_arm/config.mk +++ b/lib_arm/config.mk @@ -25,4 +25,32 @@ CROSS_COMPILE ?= arm-linux-
PLATFORM_CPPFLAGS += -DCONFIG_ARM -D__ARM__
+# Explicitly specifiy 32-bit ARM ISA since toolchain default can be -mthumb: +PLATFORM_CPPFLAGS += $(call cc-option,-marm,) + +# Try if EABI is supported, else fall back to old API, +# i. e. for example: +# - with ELDK 4.2 (EABI supported), use: +# -mabi=aapcs-linux -mno-thumb-interwork +# - with ELDK 4.1 (gcc 4.x, no EABI), use: +# -mabi=apcs-gnu -mno-thumb-interwork +# - with ELDK 3.1 (gcc 3.x), use: +# -mapcs-32 -mno-thumb-interwork +PLATFORM_CPPFLAGS += $(call cc-option,\ + -mabi=aapcs-linux -mno-thumb-interwork,\ + $(call cc-option,\ + -mapcs-32,\ + $(call cc-option,\ + -mabi=apcs-gnu,\ + )\ + ) $(call cc-option,-mno-thumb-interwork,)\ + ) + +# For EABI, make sure to provide raise() +ifneq (,$(findstring -mabi=aapcs-linux,$(PLATFORM_CPPFLAGS))) +# This file is parsed several times; make sure to add only once. +ifeq (,$(findstring lib_arm/eabi_compat.o,$(PLATFORM_LIBS))) +PLATFORM_LIBS += $(OBJTREE)/lib_arm/eabi_compat.o +endif +endif LDSCRIPT := $(SRCTREE)/cpu/$(CPU)/u-boot.lds diff --git a/lib_arm/eabi_compat.c b/lib_arm/eabi_compat.c new file mode 100644 index 0000000..86eacf1 --- /dev/null +++ b/lib_arm/eabi_compat.c @@ -0,0 +1,18 @@ +/* + * Utility functions needed for (some) EABI conformant tool chains. + * + * (C) Copyright 2009 Wolfgang Denk wd@denx.de + * + * This program is Free Software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + */ + +#include <common.h> + +int raise (int signum) +{ + printf("raise: Signal # %d caught\n", signum); + return 0; +}