gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS Misc > Linker scripts for compiling patches(Resolved)

#167773 - yellowstar - Thu Mar 26, 2009 10:15 pm

I'm attempting to use custom linker scripts and a custom crt0 to compile a patch.(Normally I'd just use arm-eabi-as with just an assembler patch, but for this hack I need to write to FAT, so I'd like to use libfat and DLDI.) Ld is failing to find _start. I'm using one Makefile for specs similar to chishm's .nds loader, and the main Makefile similar to chishm's .nds loader main Makefile. Ld is defaulting to setting the entry point to 0x02000068. Is there a way to have the linker add labels for the sizes of the .text, .rodata, .itcm/.dtcm sections?
<edit>
Never mind about the _start issue, I forgot to add a ".global _start" line. Now my asm is being assembled into a separate .text section than it should be, and is being ignored by objcopy...
<edit>
Text section resolved, now there's that section sizes issue. I'd like to use some standard way for this, if and when I get this hack finished and working properly... For now guess I could write some tool to get the section sizes and update the patch binary.
<edit>
Section issue resolved with linker script.
</edit>
</edit>
</edit>

Makefile:
Code:

#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------

ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM")
endif

include $(DEVKITARM)/ds_rules

#---------------------------------------------------------------------------------
# TARGET is the name of the output
# BUILD is the directory where object files & intermediate files will be placed
# SOURCES is a list of directories containing source code
# INCLUDES is a list of directories containing extra header files
# MAXMOD_SOUNDBANK contains a directory of music and sound effect files
#---------------------------------------------------------------------------------
TARGET      :=   $(shell basename $(CURDIR))
BUILD      :=   build
SOURCES      :=   source
DATA      :=   data 
INCLUDES   :=   include

#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
ARCH   :=   -mthumb -mthumb-interwork

CFLAGS   :=    -g -Wall -O2\
       -march=armv5te -mtune=arm946e-s -fomit-frame-pointer\
      -ffast-math \
      $(ARCH)

CFLAGS   +=   $(INCLUDE) -DARM9
CXXFLAGS   := $(CFLAGS) -fno-rtti -fno-exceptions

ASFLAGS   :=   -g $(ARCH)
LDFLAGS   =   -specs=$(CURDIR)/../specs/my_arm9.specs -T $(CURDIR)/../specs/my_arm9.ld -g $(ARCH) -Wl,-Map,$(notdir $*.map)

export OBJCOPY   :=   $(PREFIX)objcopy

#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project (order is important)
#---------------------------------------------------------------------------------
LIBS   :=    -lnds9
 
 
#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS   :=   $(LIBNDS)
 
#---------------------------------------------------------------------------------
# no real need to edit anything past this point unless you need to add additional
# rules for different file extensions
#---------------------------------------------------------------------------------
ifneq ($(BUILD),$(notdir $(CURDIR)))
#---------------------------------------------------------------------------------

export OUTPUT   :=   $(CURDIR)/$(TARGET)

export VPATH   :=   $(foreach dir,$(SOURCES),$(CURDIR)/$(dir)) \
               $(foreach dir,$(DATA),$(CURDIR)/$(dir))

export DEPSDIR   :=   $(CURDIR)/$(BUILD)

CFILES      :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES      :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
BINFILES   :=   $(foreach dir,$(DATA),$(notdir $(wildcard $(dir)/*.*)))
 
#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)
#---------------------------------------------------------------------------------
   export LD   :=   $(CC)
#---------------------------------------------------------------------------------
else
#---------------------------------------------------------------------------------
   export LD   :=   $(CXX)
#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

export OFILES   :=   $(addsuffix .o,$(BINFILES)) \
         $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)
 
export INCLUDE   :=   $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
         $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
         $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
         -I$(CURDIR)/$(BUILD)
 
export LIBPATHS   :=   $(foreach dir,$(LIBDIRS),-L$(dir)/lib)

icons = $(wildcard *.bmp)

ifneq (,$(findstring $(TARGET).bmp,$(icons)))
   export GAME_ICON := $(CURDIR)/$(TARGET).bmp
else
   ifneq (,$(findstring icon.bmp,$(icons)))
      export GAME_ICON := $(CURDIR)/icon.bmp
   endif
endif
 
.PHONY: $(BUILD) clean
 
#---------------------------------------------------------------------------------
$(BUILD):
   @[ -d $@ ] || mkdir -p $@
   @make -C specs
   @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
 
#---------------------------------------------------------------------------------
clean:
   @echo clean ...
   @rm -fr $(BUILD) $(TARGET).elf $(TARGET).bin
   @make -C specs clean

#---------------------------------------------------------------------------------
else
 
#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).bin : $(OUTPUT).elf
   @$(OBJCOPY) -O binary $< $@

$(OUTPUT).elf : $(OFILES)
 
#---------------------------------------------------------------------------------
%.bin.o   :   %.bin
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   $(bin2o)
 
-include $(DEPSDIR)/*.d
 
#---------------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------------


specs/Makefile:
Code:

ifeq ($(strip $(DEVKITARM)),)
$(error "Please set DEVKITARM in your environment. export DEVKITARM=<path to>devkitARM)
endif

-include $(DEVKITARM)/ds_rules

all:
   @echo -n Compiling load_crt0...
   @$(CC)  -x assembler-with-cpp -marm -mthumb-interwork -c my_arm9_crt0.s -o my_arm9_crt0.o
   @echo done.
   
   @echo -n Rewriting specs file...
   @echo '*startfile:' > my_arm9.specs
   @echo -n $(shell pwd -W) >> my_arm9.specs
   @echo '/../specs/my_arm9_crt0%O%s crti%O%s crtbegin%O%s' >> my_arm9.specs
   @echo done.
   
clean:
   @echo Clean...
   rm -f my_arm9.specs my_arm9_crt0.o
   @echo done.


specs/my_arm9_crt0.s:
Code:

@ This is actually from an another patch, this wasn't changed much yet, though that will be needed later.

.thumb
.section .init
.align 2

sections:
total_reloc_sections:
.word 2

itcm_dst_addr:
.word 0x01004000 @ old dest 0x023ffe00

itcm_size:
.word 0x1e0

dtcm_dst_addr:
.word 0x027e1000

dtcm_size:
.word 0x11c
.align 2

_start:
push {r0, r1, r2, r3, r4, r5, r6, r7, lr}
ldr r0, section_text_size
add r0, r0, pc
sub r0, r0, #28

add r4, pc, #0
sub r4, #32
add r1, pc, #0
add r1, #8
str r4, [r1, #48]
ldr r4, section_text_size
str r4, [r1, #52]
mov r4, #0

add r7, pc, #0
sub r7, #48
ldr r6, [r7]
add r7, #4
ldr r5, [r7]

reloc_loop:
ldr r1, [r7]
ldr r2, [r7, #4]
add r7, #8
add r2, r1

copy_loop:
ldr r3, [r0]
str r4, [r0]
str r3, [r1]
add r0, #4
add r1, #4
cmp r1, r2
bne copy_loop

sub r6, r6, #1
bne reloc_loop

mov r0, #1
add r0, r5
add r0, #8
bx r0  @ Has yet to be removed, won't be needed for this patch.

.align 2
section_text_size: @ In the other patch _start was in the .text section, and was labeled differently.
.word 0x5c


EDIT:
my_arm9.ld is a renamed ds_arm9.ld, and the generated my_arm9.specs looks similar to this:
Code:

*startfile:
c:/XxxxxConsoleStuff/RE/handheld/DS/FW/patch/specs/../specs/my_arm9_crt0%O%s crti%O%s crtbegin%O%s