diff --git a/Makefile b/Makefile index bf2859aca4..ddd9e1edf7 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ ############################################################################ # Makefile # -# Copyright (C) 2007-2009 Gregory Nutt. All rights reserved. +# Copyright (C) 2007-2010 Gregory Nutt. All rights reserved. # Author: Gregory Nutt # # Redistribution and use in source and binary forms, with or without @@ -100,6 +100,13 @@ else MAKEDIRS += $(FSDIRS) endif +# +# Extra objects used in the final link + +ifeq ($(CONFIG_BUILD_2PASS),y) +EXTRA_OBJS = $(TOPDIR)/$(CONFIG_PASS1_DIR)/$(CONFIG_PASS1_LIB) +endif + # LINKLIBS is the list of NuttX libraries that is passed to the # processor-specific Makefile to build the final target. # Libraries in FSDIRS are excluded if file descriptor support @@ -249,8 +256,29 @@ graphics/libgraphics$(LIBEXT): context examples/$(CONFIG_EXAMPLE)/lib$(CONFIG_EXAMPLE)$(LIBEXT): context @$(MAKE) -C examples/$(CONFIG_EXAMPLE) TOPDIR="$(TOPDIR)" lib$(CONFIG_EXAMPLE)$(LIBEXT) -$(BIN): context depend $(LINKLIBS) - @$(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" LINKLIBS="$(LINKLIBS)" $(BIN) +pass1: +ifeq ($(CONFIG_BUILD_2PASS),y) + @if [ -z "$(CONFIG_PASS1_LIB)" ]; then \ + echo "ERROR: CONFIG_PASS1_LIB not defined"; \ + exit 1; \ + fi + @if [ -z "$(CONFIG_PASS1_DIR)" ]; then \ + echo "ERROR: CONFIG_PASS1_DIR not defined"; \ + exit 1; \ + fi + @if [ ! -d "$(CONFIG_PASS1_DIR)" ]; then \ + echo "ERROR: CONFIG_PASS1_DIR does not exist"; \ + exit 1; \ + fi + @if [ ! -f "$(CONFIG_PASS1_DIR)/Makefile" ]; then \ + echo "ERROR: No Makefile in CONFIG_PASS1_DIR"; \ + exit 1; \ + fi + @$(MAKE) -C $(CONFIG_PASS1_DIR) TOPDIR="$(TOPDIR)" LINKLIBS="$(LINKLIBS)" $(CONFIG_PASS1_LIB) +endif + +$(BIN): context depend $(LINKLIBS) pass1 + @$(MAKE) -C $(ARCH_SRC) TOPDIR="$(TOPDIR)" EXTRA_OBJS="$(EXTRA_OBJS)" LINKLIBS="$(LINKLIBS)" $(BIN) @if [ -w /tftpboot ] ; then \ cp -f $(TOPDIR)/$@ /tftpboot/$@.${CONFIG_ARCH}; \ fi @@ -283,6 +311,9 @@ subdir_clean: done @$(MAKE) -C tools -f Makefile.mkconfig TOPDIR="$(TOPDIR)" clean @$(MAKE) -C mm -f Makefile.test TOPDIR="$(TOPDIR)" clean +ifeq ($(CONFIG_BUILD_2PASS),y) + @$(MAKE) -C $(CONFIG_PASS1_DIR) TOPDIR="$(TOPDIR)" clean +endif clean: subdir_clean @rm -f $(BIN) nuttx.* mm_test *.map *~ @@ -296,5 +327,6 @@ subdir_distclean: distclean: clean subdir_distclean clean_context @rm -f Make.defs setenv.sh .config - - +ifeq ($(CONFIG_BUILD_2PASS),y) + @$(MAKE) -C $(CONFIG_PASS1_DIR) TOPDIR="$(TOPDIR)" distclean +endif diff --git a/arch/arm/src/Makefile b/arch/arm/src/Makefile index 8bc63a18d1..c7b4d86e64 100644 --- a/arch/arm/src/Makefile +++ b/arch/arm/src/Makefile @@ -103,7 +103,7 @@ board/libboard$(LIBEXT): nuttx: $(HEAD_AOBJ) board/libboard$(LIBEXT) @echo "LD: nuttx" - @$(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) -o $(NUTTX)$(EXEEXT) $(HEAD_AOBJ) \ + @$(LD) --entry=__start $(LDFLAGS) $(LIBPATHS) -o $(NUTTX)$(EXEEXT) $(HEAD_AOBJ) $(EXTRA_OBJS) \ --start-group $(LDLIBS) -lboard --end-group $(EXTRA_LIBS) $(LIBGCC) ifeq ($(CONFIG_BOOT_RUNFROMFLASH),y) @export flashloc=`$(OBJDUMP) --all-headers $(NUTTX)$(EXEEXT) | grep _eronly | cut -d' ' -f1`; \ diff --git a/arch/sim/src/Makefile b/arch/sim/src/Makefile index 067b7cf36f..54cde18c2b 100644 --- a/arch/sim/src/Makefile +++ b/arch/sim/src/Makefile @@ -90,7 +90,7 @@ endif LINKOBJS = up_head$(OBJEXT) LINKLIBS = -LDPATHES = $(addprefix -L$(TOPDIR)/,$(dir $(LINKLIBS))) +LDPATHS = $(addprefix -L$(TOPDIR)/,$(dir $(LINKLIBS))) LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(LINKLIBS)))) all: up_head$(OBJEXT) libarch$(LIBEXT) @@ -126,7 +126,7 @@ Cygwin-names.dat: nuttx-names.dat nuttx.rel : libarch$(LIBEXT) $(HOSTOS)-names.dat $(LINKOBJS) @echo "LD: nuttx.rel" - @$(LD) -r $(LDFLAGS) $(LDPATHES) -o $@ $(LINKOBJS) --start-group $(LDLIBS) --end-group $(EXTRA_LIBS) + @$(LD) -r $(LDFLAGS) $(LDPATHS) -o $@ $(LINKOBJS) --start-group $(LDLIBS) --end-group $(EXTRA_LIBS) @$(OBJCOPY) --redefine-syms=$(HOSTOS)-names.dat $@ # Generate the final NuttX binary by linking the host-specific objects with the NuttX @@ -134,7 +134,7 @@ nuttx.rel : libarch$(LIBEXT) $(HOSTOS)-names.dat $(LINKOBJS) nuttx$(EXEEXT): cleanrel nuttx.rel $(HOSTOBJS) @echo "LD: nuttx$(EXEEXT)" - @$(CC) $(LDFLAGS) $(LDPATHES) -o $(TOPDIR)/$@ nuttx.rel $(HOSTOBJS) $(STDLIBS) + @$(CC) $(LDFLAGS) $(LDPATHS) -o $(TOPDIR)/$@ nuttx.rel $(HOSTOBJS) $(STDLIBS) @$(NM) $(TOPDIR)/$@ | \ grep -v '\(compiled\)\|\(\.o$$\)\|\( [aUw] \)\|\(\.\.ng$$\)\|\(LASH[RL]DI\)' | \ sort > $(TOPDIR)/System.map diff --git a/configs/ea3131/locked/Makefile b/configs/ea3131/locked/Makefile index 52815a0ddc..db552a771e 100755 --- a/configs/ea3131/locked/Makefile +++ b/configs/ea3131/locked/Makefile @@ -35,20 +35,37 @@ -include $(TOPDIR)/Make.defs -all: liblocked.r +ifeq ($(WINTOOL),y) + # Windows-native toolchains + PASS1_LIBPATHS = ${shell for path in $(LINKLIBS); do dir=`dirname $(TOPDIR)/$$path`;echo "-L\"`cygpath -w $$dir`\"";done} + PASS1_LDSCRIPT = -T "${shell cygpath -w $(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/locked/ld-locked.inc}" +else + # Linux/Cygwin-native toolchain + PASS1_LIBPATHS = $(addprefix -L$(TOPDIR)/,$(dir $(LINKLIBS))) + PASS1_LDSCRIPT = -T$(TOPDIR)/configs/$(CONFIG_ARCH_BOARD)/locked/ld-locked.inc +endif -ld-locked.script: - ./mklocked.sh "$(TOPDIR)" +PASS1_LDFLAGS = -r $(PASS1_LDSCRIPT) +PASS1_LDLIBS = $(patsubst lib%,-l%,$(basename $(notdir $(LINKLIBS)))) +PASS1_LIBGCC = "${shell $(CC) -print-libgcc-file-name}" -liblocked.r: ld-locked.script $(OBJS) - @LD -o $@ --start-group $(LDLIBS) --end-group -u os_start $(LIBGCC) +all: locked.r + +ld-locked.inc: mklocked.sh $(TOPDIR)/.config + @echo "MK: ld-locked.inc" + @./mklocked.sh "$(TOPDIR)" + +locked.r: ld-locked.inc $(OBJS) + @echo "LD: locked.r" + @$(LD) -o $@ $(PASS1_LDFLAGS) $(PASS1_LIBPATHS) --start-group $(PASS1_LDLIBS) --end-group -u os_start $(PASS1_LIBGCC) .depend: depend: .depend clean: - @rm -f liblocked.r *~ .*.swp + @rm -f locked.r *~ .*.swp distclean: clean - @rm -f ld-locked.script + @rm -f ld-locked.inc + diff --git a/configs/ea3131/locked/ld-locked.script b/configs/ea3131/locked/ld-locked.script new file mode 100644 index 0000000000..f89d8549f9 --- /dev/null +++ b/configs/ea3131/locked/ld-locked.script @@ -0,0 +1,44 @@ +/**************************************************************************** + * configs/ea3131/pgnsh/ld-locked.script + * + * Copyright (C) 2010 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +INCLUDE ld-locked.inc +OUTPUT_ARCH(arm) +SECTIONS +{ + .locked : { + *(.vectors) + *(.text .text.*) + } +} \ No newline at end of file diff --git a/configs/ea3131/locked/mklocked.sh b/configs/ea3131/locked/mklocked.sh index 188ca47965..8bfd03da37 100755 --- a/configs/ea3131/locked/mklocked.sh +++ b/configs/ea3131/locked/mklocked.sh @@ -76,62 +76,61 @@ function checkconfig () { # Interrupt Handlers ############################################################################ # -# All interrupt handlers must be forced to lie in the locked -# .text region +# All interrupt handlers must be forced to lie in the locked .text region # -# These are the vector entry points (only one is really needed -# since they are all in the same file). These should drag in all -# of the vector dispatching logic. +# These are the vector entry points (only one is really needed since they +# are all in the same file). These should drag in all of the vector +# dispatching logic. # -rm -f ld-locked.script -echo "EXTERN(up_vectorswi)" >>ld-locked.script -echo "EXTERN(up_vectordata)" >>ld-locked.script -echo "EXTERN(up_vectorprefetch)" >>ld-locked.script -echo "EXTERN(up_vectorundefinsn)" >>ld-locked.script -echo "EXTERN(up_vectorfiq)" >>ld-locked.script -echo "EXTERN(up_vectorirq)" >>ld-locked.script +rm -f ld-locked.inc +echo "EXTERN(up_vectorswi)" >>ld-locked.inc +echo "EXTERN(up_vectordata)" >>ld-locked.inc +echo "EXTERN(up_vectorprefetch)" >>ld-locked.inc +echo "EXTERN(up_vectorundefinsn)" >>ld-locked.inc +echo "EXTERN(up_vectorfiq)" >>ld-locked.inc +echo "EXTERN(up_vectorirq)" >>ld-locked.inc # -# These are the initialization entry points of all device drivers -# that handle interrupts. We really want to include as little as -# possible -- ideally just the interrupt handler itself, but that -# is not usually possible. +# These are the initialization entry points of all device drivers that +# handle interrupts. We really want to include as little as possible -- +# ideally just the interrupt handler itself, but that is not usually +# possible. # -# Of course, this list must be extended as interrupt handlers are -# added. +# Of course, this list must be extended as interrupt handlers are added. -echo "EXTERN(up_timerinit)" >>ld-locked.script +echo "EXTERN(up_timerinit)" >>ld-locked.inc answer=$(checkconfig CONFIG_LPC313X_UART) if [ $answer = y ]; then - echo "EXTERN(up_earlyserialinit)" >>ld-locked.script + echo "EXTERN(up_earlyserialinit)" >>ld-locked.inc fi # up_i2cinitialize -- Not conditioned on anything answer=$(checkconfig CONFIG_USBDEV) if [ $answer = y ]; then - echo "EXTERN(up_usbinitialize)" >>ld-locked.script + echo "EXTERN(up_usbinitialize)" >>ld-locked.inc fi ############################################################################ # Idle Loop ############################################################################ # -# The IDLE loop must be forced to lie in the locked .text region -# NOTE that most of the IDLE loop is is os_start.c, but we don't -# we want to handle that differently so that it does not draw in -# a lot of things that we do not need. +# The IDLE loop must be forced to lie in the locked .text region. NOTE that +# most of the IDLE loop is is os_start.c, but we don't we want to handle +# that differently so that it does not draw in a lot of things that we do +# not need in the locked region. However, we do need to bring in all of +# the things called by os_start up to the point where the page fill worker +# thread is started. -echo "EXTERN(up_idle)" >>ld-locked.script +echo "EXTERN(up_idle)" >>ld-locked.inc ############################################################################ # PG Fill Worker Thread ############################################################################ # -# All of the page fill worker thread must be in the locked .text -# region. +# All of the page fill worker thread must be in the locked .text region. -echo "EXTERN(pg_worker)" >>ld-locked.script +echo "EXTERN(pg_worker)" >>ld-locked.inc diff --git a/configs/ea3131/pgnsh/defconfig b/configs/ea3131/pgnsh/defconfig index 696b5f310a..756e92e884 100755 --- a/configs/ea3131/pgnsh/defconfig +++ b/configs/ea3131/pgnsh/defconfig @@ -198,6 +198,13 @@ CONFIG_MOTOROLA_SREC=n CONFIG_RAW_BINARY=y CONFIG_HAVE_LIBM=n +# +# Setup for a two-pass build +# +CONFIG_BUILD_2PASS=y +CONFIG_PASS1_DIR=configs/ea3131/locked +CONFIG_PASS1_LIB=locked.r + # # General OS setup # diff --git a/configs/ea3131/pgnsh/ld.script b/configs/ea3131/pgnsh/ld.script index bf84a0681a..0dc7682570 100755 --- a/configs/ea3131/pgnsh/ld.script +++ b/configs/ea3131/pgnsh/ld.script @@ -37,20 +37,37 @@ * LPC313x boot ROM expects the boot image be compiled with entry point at * 0x1102:9000. A 128b header will appear at this address (applied by * lpc313xImgCreator) and the executable code must begin at 0x1102:9080. + * + * The .text vitual address space begins at the same location as the physical + * address space: 0x1102 8000. The virtual space is broken up into three + * regions: + * + * locked - Pages locked in memory. Start: 0x1102 8000 Size: 36Kb + * paged - Pages in nonvolatile store. Start: 0x1103 1000 Size: 384Kb + * data - .data/.bss/heap. Start: 0x1109 1000 Size: 44Kb */ MEMORY { - isram (rwx) : ORIGIN = 0x11029080, LENGTH = 192K - 4224 + locked (rx) : ORIGIN = 0x11029080, LENGTH = 36K - 4224 + paged (rx) : ORIGIN = 0x11031000, LENGTH = 384K + data (rw) : ORIGIN = 0x11091000, LENGTH = 44K } OUTPUT_ARCH(arm) ENTRY(_stext) SECTIONS { - .text : { - _stext = ABSOLUTE(.); + .locked : { + _slocked = ABSOLUTE(.); *(.vectors) + *(.locked) + _elocked = ABSOLUTE(.); + } >locked + _eronly = ABSOLUTE(.); /* See below */ + + .paged : { + _spaged = ABSOLUTE(.); *(.text .text.*) *(.fixup) *(.gnu.warning) @@ -61,8 +78,8 @@ SECTIONS *(.got) *(.gcc_except_table) *(.gnu.linkonce.r.*) - _etext = ABSOLUTE(.); - } > isram + _epaged = ABSOLUTE(.); + } > paged _eronly = ABSOLUTE(.); @@ -72,17 +89,17 @@ SECTIONS *(.gnu.linkonce.d.*) CONSTRUCTORS _edata = ABSOLUTE(.); - } > isram + } > data AT > locked .ARM.extab : { *(.ARM.extab*) - } >isram + } >data .ARM.exidx : { __exidx_start = ABSOLUTE(.); *(.ARM.exidx*) __exidx_end = ABSOLUTE(.); - } > isram + } > data .bss : { _sbss = ABSOLUTE(.); @@ -90,7 +107,7 @@ SECTIONS *(.gnu.linkonce.b.*) *(COMMON) _ebss = ABSOLUTE(.); - } > isram + } > data /* Stabs debugging sections. */ .stab 0 : { *(.stab) } .stabstr 0 : { *(.stabstr) }