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.