Can someone explain these files?

Scenario:
I've taken over some prototyping development work on a Coldfire
evaluation board. I'm new to this kind of embedded stuff, although
covered a little at uni (I finished 6 years ago) - but to be honest,
it's not in my head at the moment - given a little pointers it might
bring it all back. I've done plenty of C, C++, C# development for
Windows and set-top-boxes - but usually the tools I've used have made
all the base project for me - not needing to worry about things other
than the application logic and memory/hardware constraints.
I have a very simple app working at the moment written by another guy
who's unavailable to assist.
I'm using GNU gcc (m68k port) within Cygwin for development. The
application compiles fine - but I'm unsure about some of the ancillary
files in the project.
I have a single .c file, a number of .h files, a makefile and three
unknown (assuming assembler or something) files. I'm not using any
external libraries (-nostdlib) as I have none.
The unknown files are named:
api.lds
api.lds.S
apicrt0.S
The contents of api.lds and api.lds.S are almost identical, with only
the 4th line (and minor formatting/comment changes) being different, the
api.lds file is:
ENTRY(_start)
SECTIONS
{
. = BASE_ADDRESS;
_img_start = .;
.text : { *(.text) }
.data : { *
(.data) }
.rodata : { *(.rodata*)
. = ALIGN(4); /* Align the end of rodata. */
}
.glue : { *(.glue*) }
_text = ADDR(.text);
_etext = ADDR(.rodata) + SIZEOF(.rodata);
_img_end = .;
.bss : { *(.bss) }
_bss = ADDR(.bss);
_ebss = ADDR(.bss) + SIZEOF(.bss);
. = ALIGN(4);
_stack = .;
. = . + (16 *
1024);
_estack = .;
.sizealign (NOLOAD) : { } = 0x0
}
The difference with the api.lds.S file is that the 4th line is:
. = BASE_ADDRESS;
The other file, apicrt0.S contains:
.global _start
.extern _estack, _bss, _ebss
.align 4
/*
*
The following defines the registers that are
* maintained by the debugger.
*
/
.equ r_d0,0
.equ r_d1,4
.equ r_d2,8
.equ r_d3,12
.equ r_d4,16
.equ r_d5,20
.equ r_d6,24
.equ r_d7,28
.equ r_a0,32
.equ r_a1,36
.equ r_a2,40
.equ r_a3,44
.equ r_a4,48
.equ r_a5,52
.equ r_a6,56
.equ r_sp,60
.equ r_pc,64
.equ r_sr,68
.equ r_sz,72

_start:
/* save registers to stack */
//movem.l %d0-%d7/%a0-%a6,(r_d0-r_sz,%sp)
move.l %d0 , (r_d0-r_sz,%sp)
move.l %d1 , (r_d1-r_sz,%sp)
move.l %d2 , (r_d2-r_sz,%sp)
move.l %d3 , (r_d3-r_sz,%sp)
move.l %d4 , (r_d4-r_sz,%sp)
move.l %d5 , (r_d5-r_sz,%sp)
move.l %d6 , (r_d6-r_sz,%sp)
move.l %d7 , (r_d7-r_sz,%sp)

move.l %a0 , (r_a0-r_sz,%sp)
move.l %a1 , (r_a1-r_sz,%sp)
move.l %a2 , (r_a2-r_sz,%sp)
move.l %a3 , (r_a3-r_sz,%sp)
move.l %a4 , (r_a4-r_sz,%sp)
move.l %a5 , (r_a5-r_sz,%sp)
move.l %a6 , (r_a6-r_sz,%sp)

move.l %sp, (r_sp-r_sz, %sp) /* sp */
move.l 4(%sp),(r_pc-r_sz, %sp) /* pc */
move.w 2(%sp),(r_sr-r_sz, %sp) /* sr */
move.w 2(%sp),(r_sr+2-r_sz, %sp) /* sr */

/* Decrement Stack pointer by size of regs */
move.l %sp, %d0
subi.l #r_sz, %d0
move.l %d0, %sp

/* zero the bss */
move.l #_bss, %A1
move.l #_ebss, %A2
bss_zero_loop:
cmpa.l %A2, %A1
bge bss_zero_end
move.l #0, (%A1)+
bra bss_zero_loop
bss_zero_end:
/* save old & load new stack pointer */
move.l #saved_sp, %A1
move.l %sp, (%A1)
move.l #_estack, %A1
move.l %A1, %sp
/* call main */
jsr main
move.l #saved_sp, %A1
move.l (%A1), %sp
/* Increment Stack pointer by size of regs */
move.l %sp, %d0
addi.l #r_sz, %d0
move.l %d0, %sp

/* reload previous registers */
//movem.l (r_d0-r_sz,%sp),%d0-%d7/%a0-%a6
move.l (r_d0-r_sz,%sp),%d0
move.l (r_d1-r_sz,%sp),%d1
move.l (r_d2-r_sz,%sp),%d2
move.l (r_d3-r_sz,%sp),%d3
move.l (r_d4-r_sz,%sp),%d4
move.l (r_d5-r_sz,%sp),%d5
move.l (r_d6-r_sz,%sp),%d6
move.l (r_d7-r_sz,%sp),%d7
move.l (r_a0-r_sz,%sp),%a0
move.l (r_a1-r_sz,%sp),%a1
move.l (r_a2-r_sz,%sp),%a2
move.l (r_a3-r_sz,%sp),%a3
move.l (r_a4-r_sz,%sp),%a4
move.l (r_a5-r_sz,%sp),%a5
move.l (r_a6-r_sz,%sp),%a6
nop
rts
nop
nop

saved_sp: .long 0x00000000
.end
I'm guessing that they're assembler code to do the initialisation etc
(_start). However, can someone explain the difference between the two
files, and how they're built etc? Could one of the api.lds/api.lds.S
files be historical/obsolete?
The Makefile contains:
export SHELL=/bin/bash
BOOTROOT=$(shell pwd)
# ****************************
# Set up required definitions
# ****************************
CONFIG_APP_OFFSET=0x00100000
BUILD_SDRAM_BASE=0x00000000
BUILD_FLASH_BASE=0xFF800000
BUILD_LOCATION=RAM
AR=m68k-elf-ar
AS=m68k-elf-as
CC=m68k-elf-gcc
CPP=m68k-elf-cpp
CXX=m68k-elf-g++
LD=m68k-elf-ld
OBJCOPY=m68k-elf-objcopy
OBJDUMP=m68k-elf-objdump
STRIP=m68k-elf-strip
DEFINES = -DBASE_ADDRESS=$(BUILD_SDRAM_BASE)+$(CONFIG_APP_OFFSET) \
-DMEMAP_BASE_SDRAM=$(BUILD_SDRAM_BASE) \
-DBOOTFLASH_PHYS_BASE=$(BUILD_FLASH_BASE) \
-DLOGIC_CARDENGINE_MCF5475_10 -DCONFIG_IN_FLASH=0 -DM5475EVB
ASFLAGS = -m5407 -D_ASM_ $(INCLUDES) $(DEFINES)
CFLAGS = -m5407 -malign-int -mnoshort -mstrict-align -fno-builtin \
-O0 -Wall -g -ggdb $(INCLUDES) $(DEFINES) -fno-builtin \
-nostdlib -N
LFLAGS = $(DEFINES) $(INCLUDES) -preproc
LDSFLAGS = -T api.lds
# **********************************
# Set up application to be complied
# **********************************
EXECUTABLE=appname
SOURCES=appname.c
OBJECTS=appname.o apicrt0.o
# **************************************
# the default target for our make files
# **************************************
all: clean $(SOURCES) $(EXECUTABLE)
$(EXECUTABLE): $(OBJECTS)
$(CC) $(CFLAGS) $(LDFLAGS) $(LDSFLAGS) $(OBJECTS) -o $@.elf
cp $@.elf $@.debug
$(STRIP) $@.elf
$(OBJCOPY) -O binary $(EXECUTABLE).elf $(EXECUTABLE).raw

.c.o:
$(CC) -c $(CFLAGS) $< -o $@

.lds:
$(CPP) -P -D_ASM_ $(DEFINES) $(INCLUDES) $< > $@

clean::
-rm *.o *.raw *.elf *.debug
From this I suspect that it's using appname.c, apicrt0.S, and api.lds
(ignoring api.lds.S entirely.
So, if I needed to move the source files into another compiler/IDE (eg.
Eclipse with Zylin CDT for embedded work) then I don't need any other
files than appname.c, apicrt0.S and api.lds - right?
What's the difference between the api.lds and apicrt0.S files?
Sorry if all this is a bit basic - I've got some more questions which
I'll put into another post another time!
Thanks for your help,
David
Reply to
David Hearn
Loading thread data ...
These are linker control files - they define how the application is mapped into memory.
and this is the startup code, as you correctly deduced.
Correect in that case.
The Makefile's telling you which one is used and which is obsolete ;)
You appear to be right.
pete
--
pete@fenelon.com "That is enigmatic. That is textbook enigmatic..." - Dr Who
                 "There's no room for engimas in built-up areas." - N Blackwell
Reply to
Pete Fenelon
Thanks for the confirmation!
D
Reply to
David Hearn
I don't know if the Zylin CDT will support the ability to auto-create the linker script file for you, but if it doesn't, then you'll still need it. I'm not familiar with this toolset, but many IDEs that gcc users use are only good at editting .c and .h files, and they do nothing to help you set up makefiles and linker scripts.
Some of the better IDEs let you specify various memory ranges in a configuration menu, and they automatically build both the makefile and linker script for you. That's how my EmbeddedGNU IDE works, but it doesn't support Coldfire yet.
Eric
Reply to
Eric

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.