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.

Coding > Setting Up for Linux GBA Development

#23501 - dist0rted - Wed Jul 14, 2004 9:02 am

I'm running into a few troubles setting up for GBA Development on my SuSE Linux 9.1 Professional system. First off, how can I set it up so I can compile easily without having the GBA gcc getting in the way of my normal gcc (as in what can I do about the PATH). Also, are there any GBA Emulators for Linux? I've searched with no luck.
_________________
All knowledge is good; only the way it is put to use is good or evil.

#23517 - wintermute - Wed Jul 14, 2004 4:46 pm

go to http://www.devkit.tk

there's a linux build of devkitARM in the downloads section

if you really need to build it yourself the build scripts are available in the DIY section.

#23523 - tepples - Wed Jul 14, 2004 5:15 pm

Path issue: If you put your native GCC in front of devkitARM GCC in your PATH, then you can use 'gcc' for native GCC and 'arm-elf-gcc' for devkitARM GCC.

Emulator: VisualBoyAdvance is ported to Linux.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#23541 - SmileyDude - Wed Jul 14, 2004 9:33 pm

although I should probably use arm-elf-gcc instead, I use a script (actually a bash function defined in .bashrc) that sets the path up for the devkit instead. Then, in each window that I work on gba code, I simply type 'devkit'. As a bonus, I have it modify the prompt and the window title to reflect that it's a devkit window.

If you want, I can post up the function.
_________________
dennis

#23542 - dist0rted - Wed Jul 14, 2004 9:58 pm

I downloaded VisualBoy Advance for Linux, and have arm-agb-elf-gcc for use as my compiler in my $PATH. However, whenever I try to compile, I get tons of errors. Do I have to set up the INCLUDE and LIB directories for the compiler? If so, how?
_________________
All knowledge is good; only the way it is put to use is good or evil.

#23543 - wintermute - Wed Jul 14, 2004 10:30 pm

you should get devkitARM from the link I posted earlier. It *should* just work out of the box.

also post a copy of your environment found by typing 'set' in a bash shell

#23545 - dist0rted - Wed Jul 14, 2004 11:08 pm

Alright, devkitARM works fine. Now I just have one question about devkitARM: I'm writing a Makefile, and I don't know how to use objcopy to make the .o file after I compile the .c file into a .elf. (I've got it to compile, but how do I get it to use objcopy after already compiling.)
_________________
All knowledge is good; only the way it is put to use is good or evil.

#23550 - SmileyDude - Thu Jul 15, 2004 12:43 am

here is a portion of my Makefile.... these rules should solve the problem you are having:

Code:
ROM = test
OBJS  := $(patsubst %.c,%.o,$(wildcard *.c))

all: $(ROM).gba

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

$(ROM).gba: $(ROM).elf
    objcopy -O binary $(ROM).elf $(ROM).gba

$(ROM).elf: $(OBJS)
    $(CC) -o $(ROM).elf $(LDFLAGS) $(OBJS) $(LIBS)


basically, OBJS will be a list of .o files -- one for each of the .c files in the current directory. since $(ROM).elf depends on each of those .o files, they will all be built before passing them off to the linker. That will give you a .elf file which is passed to objcopy to give you the .gba file that you want.

I've omitted some of the Makefile -- if you want, you can download a Makefile from any of my projects I've posted on my website (http://munsie.dhs.org/gba_code/). They're all pretty much the same, though I've made a few improvements on the ones I haven't released yet.
_________________
dennis

#23584 - wintermute - Thu Jul 15, 2004 7:26 pm

here's a pretty generic makefile I tend to modify to suit what I'm building. I override the system PATH because I tend to have several variants of gcc around and it makes things easier when working with new versions of devkitARM/devkitPPC. It might be easier for you if you either delete that line or use 'export PATH := $(PATH):<path to devkitARM bin dir>'.

I tend to use absolute paths for external libraries too - the makefile builds things in a separate directory and any relative paths should be relative to that, not the source directory.


Code:

#---------------------------------------------------------------------------------
# Generic makefile for GBA projects
#
# Tab stops set to 4
#   |   |   |   |
#   0   1   2   3
#---------------------------------------------------------------------------------
# Clear the implicit built in rules
#---------------------------------------------------------------------------------
.SUFFIXES:
#---------------------------------------------------------------------------------

#---------------------------------------------------------------------------------
# TARGET   - the name of the output, if this ends with _mb generates a multiboot image
# BUILD      - the directory where object files & intermediate files will be placed
# SOURCES   - a list of directories containing source code
# INCLUDES   - a list of directories containing extra header files
#            should include the build directory
#---------------------------------------------------------------------------------
TARGET      :=   myGBArom_mb
BUILD      :=   build
SOURCES      :=   src data
INCLUDES   :=   $(BUILD)

#---------------------------------------------------------------------------------
# options for code generation
#---------------------------------------------------------------------------------
THUMB   :=   -mthumb -mthumb-interwork
ARM      :=   -marm -mthumb-interwork

ARCH   :=   $(THUMB)

CFLAGS   :=   -save-temps -g -Wall -O3\
         -mcpu=arm7tdmi -mtune=arm7tdmi\
          -fomit-frame-pointer\
         -ffast-math

CFLAGS   +=   $(INCLUDE)

ASFLAGS   :=   $(ARCH)

LDFLAGS   =   -g $(ARCH) -Wl,-Map,$(notdir $@).map

#---------------------------------------------------------------------------------
# path to tools - this can be deleted if you set the path in windows
#---------------------------------------------------------------------------------
export PATH      :=   /c/devkitARM_r6a/bin:/bin
#---------------------------------------------------------------------------------
# absolute path required since this makefile uses the build directory
# as the working directory
#---------------------------------------------------------------------------------
LIBGBA   :=   /c/projects/gba/libgba

#---------------------------------------------------------------------------------
# the prefix on the compiler executables
#---------------------------------------------------------------------------------
PREFIX         :=   arm-elf-
#---------------------------------------------------------------------------------
# any extra libraries we wish to link with the project
#---------------------------------------------------------------------------------
LIBS   :=   -lgba

#---------------------------------------------------------------------------------
# list of directories containing libraries, this must be the top level containing
# include and lib
#---------------------------------------------------------------------------------
LIBDIRS   :=   $(LIBGBA)

#---------------------------------------------------------------------------------
# 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))

export CC      :=   $(PREFIX)gcc
export CXX      :=   $(PREFIX)g++
export AR      :=   $(PREFIX)ar
export OBJCOPY   :=   $(PREFIX)objcopy


#---------------------------------------------------------------------------------
# automatically build a list of object files for our project
#---------------------------------------------------------------------------------
CFILES      :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.c)))
CPPFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp)))
SFILES      :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s)))
PCXFILES   :=   $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcx)))

export OFILES   :=   $(PCXFILES:.pcx=.o) $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) $(SFILES:.s=.o)

#---------------------------------------------------------------------------------
# use CXX for linking C++ projects, CC for standard C
#---------------------------------------------------------------------------------
ifeq ($(strip $(CPPFILES)),)

   export LD   :=   $(CC)

else

   export LD   :=   $(CXX)

endif

#---------------------------------------------------------------------------------
# build a list of include paths
#---------------------------------------------------------------------------------
export INCLUDE   :=   $(foreach dir,$(INCLUDES),-I$(CURDIR)/$(dir)) \
         $(foreach dir,$(LIBDIRS),-I$(dir)/include) \
         -I$(CURDIR)/$(BUILD)

#---------------------------------------------------------------------------------
# build a list of library paths
#---------------------------------------------------------------------------------
export LIBPATHS   :=   $(foreach dir,$(LIBDIRS),-L$(dir)/lib)

.PHONY: $(BUILD) clean

#---------------------------------------------------------------------------------
$(BUILD):
   @[ -d $@ ] || mkdir -p $@
   @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile

#---------------------------------------------------------------------------------
clean:
   @echo clean ...
   @rm -fr $(BUILD) *.elf

#---------------------------------------------------------------------------------
else

DEPENDS   :=   $(OFILES:.o=.d)

#---------------------------------------------------------------------------------
# main targets
#---------------------------------------------------------------------------------
$(OUTPUT).gba   :   $(OUTPUT).elf

$(OUTPUT).elf   :   $(OFILES)

#---------------------------------------------------------------------------------
%.gba: %.elf
   @echo built ... $(notdir $@)
   @$(OBJCOPY) -O binary $< $@
   @gbafix $@

#---------------------------------------------------------------------------------
%_mb.elf:
   @echo linking multiboot
   $(LD) -specs=gba_mb.specs $(LDFLAGS) $(OFILES) $(LIBPATHS) $(LIBS) -o $@

#---------------------------------------------------------------------------------
%.elf:
   @echo linking cartridge
   @$(LD)  $(LDFLAGS) -specs=gba.specs $(OFILES) $(LIBPATHS) $(LIBS) -o $@

#---------------------------------------------------------------------------------
# Compile Targets for C/C++
#---------------------------------------------------------------------------------

#---------------------------------------------------------------------------------
%_arm.o : %_arm.cpp
   @echo $(notdir $<)
   @$(CXX) -MMD $(ARM) $(CFLAGS) -o $@ -c $<

#---------------------------------------------------------------------------------
%.o : %.cpp
   @echo $(notdir $<)
   @$(CXX) -MMD $(THUMB) $(CFLAGS) -o $@ -c $<

#---------------------------------------------------------------------------------
%_arm.o : %_arm.c
   @echo $(notdir $<)
   @$(CC) -MMD $(ARM) $(CFLAGS) -o $@ -c $<

#---------------------------------------------------------------------------------
%.o : %.c
   @echo $(notdir $<)
   @$(CC) -MMD $(THUMB) $(CFLAGS) -o $@ -c $<

#---------------------------------------------------------------------------------
%.o : %.s
   @echo $(notdir $<)
   @$(CC) -MMD $(ASFLAGS) -o $@ -c $<

#---------------------------------------------------------------------------------
# canned command sequence for binary data
#---------------------------------------------------------------------------------
define bin2o
   cp $(<) $(*).tmp
   $(OBJCOPY) -I binary -O elf32-littlearm -B arm \
   --rename-section .data=.rodata,readonly,data,contents,alloc \
   --redefine-sym _binary_$*_tmp_start=$*\
   --redefine-sym _binary_$*_tmp_end=$*_end\
   --redefine-sym _binary_$*_tmp_size=$*_size\
   $(*).tmp $(@)
   echo "extern const u8" $(*)"[];" > $(*).h
   echo "extern const u32" $(*)_size[]";" >> $(*).h
   rm $(*).tmp
endef

#---------------------------------------------------------------------------------
%.o   :   %.pcx
#---------------------------------------------------------------------------------
   @echo $(notdir $<)
   @$(bin2o)

-include $(DEPENDS)

#---------------------------------------------------------------------------------
endif
#---------------------------------------------------------------------------------

#23668 - dist0rted - Sun Jul 18, 2004 4:27 am

I'm having major problems with VisualBoy Advance for Linux. I run it at the cmd line (./VisualBoyAdvance game.bin) and no matter what I code I used to compile game.bin, nothing will appear but a blank, white screen. Is it something I'm doing wrong? (The code is directly from thepernproject.com copied and pasted; so I doubt it's a coding error.)
_________________
All knowledge is good; only the way it is put to use is good or evil.

#23669 - wintermute - Sun Jul 18, 2004 4:57 am

That really depends on how you're building the ROM image. It would be helpful if you showed us the build commands used to create the image you're trying to run with VBA.

#23675 - tepples - Sun Jul 18, 2004 6:29 pm

dist0rted: Do known-good, freely-redistributable ROMs such as Tetanus On Drugs work?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#23682 - dist0rted - Sun Jul 18, 2004 8:00 pm

arm-elf-gcc -o main.elf main.c
arm-elf-objcopy -O binary main.elf main.bin
_________________
All knowledge is good; only the way it is put to use is good or evil.

#23753 - mazterdeath - Wed Jul 21, 2004 3:09 am

Hi, I just started on the gba programming world, so I downloaded the devkitadv release 4 for linux, the compiled one found at sourceforge. But I'm not sure how to use it or I have trouble with it. I placed the files in a dir and when I try to compile I call the arm-agb-gcc from that dir, cuz I haven't placed it in the path, but even with an empty main function it crashes. It tells me this:

In function `jump_intr':
../devkitadv/bin/../lib/gcc-lib/arm-agb-elf/3.1/../../../../arm-agb-elf/lib/crt0
.o(.iwram+0xc4): undefined reference to `IntrTable'


and also it tells me this:


../devkitadv/bin/../lib/gcc-lib/arm-agb-elf/3.1/../../../../arm-agb-elf/bin/ld: section .iwram [0800039c -> 08000463] overlaps section .init [08000388 -> 080003a3]

So I haven't been able to compile anything at all. Should I build devkitadv myself or how do I use it or what am I missing.

Thanks

#23777 - Cearn - Wed Jul 21, 2004 12:28 pm

Quote:
In function `jump_intr':
../devkitadv/bin/../lib/gcc-lib/arm-agb-elf/3.1/../../../../arm-agb-elf/lib/crt0
.o(.iwram+0xc4): undefined reference to `IntrTable'

This concerns the use of hardware interrupts. There are 14 interrupt types and their interrupt service routines (isr) are often put in a table of function pointers called `IntrTable'. The thing is that the crt0.S file that references the table doesn't contain it, so you have to define it yourself. Try adding this to your code.
Code:

typedef void (*fnptr)(void);
fnptr IntrTable[14];

That should clear the error. For more on this, see devrs GBA Faq.

Quote:

../devkitadv/bin/../lib/gcc-lib/arm-agb-elf/3.1/../../../../arm-agb-elf/bin/ld: section .iwram [0800039c -> 08000463] overlaps section .init [08000388 -> 080003a3]

I'm not exactly sure what's going on here, but this seems to be a link script error. The iwram section should be at 0x03000000, not 0x08000000.

It'll probably be better to use devkitARM, though, as it shouldn't have these kinds of problems. And uses a newer GCC. And produces smaller binaries. And has been updated more recently than, what, 2 years ago?

Just be sure you
1) set your path correctly
2) use the `arm-elf-' prefix for its commands
3) use the `-mthumb-interwork' flag when compiling
4) use either `-specs=gba.specs' or `specs=gba_mb.specs' when linking.

And, of course, read the forum FAQ, if you haven't already.

#24036 - mazterdeath - Mon Jul 26, 2004 9:22 pm

I downloaded devkitARM, and when I try to compile with the flag it tells me it is an invalid option:

Code:
[mabel@Decroma Mazter]$ arm-elf-gcc -mthumb-internetwork test1.c
cc1: error: invalid option `thumb-internetwork'



And when I compile without it it works, but nothing happens on the emulator, just a blank screen.

Also, where do I use the:
`-specs=gba.specs' or `specs=gba_mb.specs'
flags?

Maybe I'm using the wrong commands, which are they to compile.

Thanks

#24039 - torne - Mon Jul 26, 2004 10:41 pm

The argument is -mthumb-interwork. You need to add the specs to all invocations of gcc, iirc.

#24212 - mazterdeath - Thu Jul 29, 2004 9:05 pm

Thanks, now it compiles ok, and works.

There should be a place where to discuss the details of compiling under linux.

Thanks anyway.

#24220 - tepples - Thu Jul 29, 2004 11:14 pm

mazterdeath wrote:
There should be a place where to discuss the details of compiling under linux.

The C/C++ forum would probably work best for questions about a particular compiler toolchain.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#24415 - allenu - Tue Aug 03, 2004 7:38 am

mazterdeath wrote:

../devkitadv/bin/../lib/gcc-lib/arm-agb-elf/3.1/../../../../arm-agb-elf/bin/ld: section .iwram [0800039c -> 08000463] overlaps section .init [08000388 -> 080003a3]



When I downloaded devkitadvance, I was unable to compile my simple source code because I'd get the above error as well. It's a problem in the link stage. Anyway, I ended up building gcc completely to build for the GBA. I basically followed the instructions on this page to do it: http://linux.gbadev.org/gcc-gba/. However, I encountered other issues. You can read about all of the problems I encountered on this page: ttp://www3.telus.net/allenu/Wiki/ProjectHazukiLog.html (see the entries dated 2004-08-02).

To make a long story short, I encountered yet another problem similar to the above, but I was finally able to fix it by adding "-nostartfiles" to the arm-thumb-elf-g++ command and also adding a custom crt0.o to the compile process. Like I said, follow the link above to my webpage for more info. You might want to try that. There is a link on the linux.gbadev.org page above to the CRT0.S that you will need to build on your system.

#24418 - wintermute - Tue Aug 03, 2004 11:03 am

or you could stick with devkitARM which fully supports C++ out of the box. I'm currently testing some variations on the build scripts which support BSD systems, should be an update on that shortly.

http://www.devkit.tk