User Tools

Site Tools


gba:guide:memory_management

Linking and memory management

In Wonderful's ecosystem, instead of relying on the linker and a post-link tool, linker wrappers are utilized instead. This allows handling everything from object linking to program file output in one step on the user side, as well as implementing high-level configuration facilities which generate a link script.

# This call...
$ arm-none-eabi-ld -o program.elf [objects...] [flags...]

# ...becomes:
$ wf-gbatool link rom|multiboot -o program.gba --output-elf program.elf -- [objects...] [flags...]

# By default, wfconfig.toml in the current working directory is used
# (see below). To use a different file:
$ wf-gbatool link rom|multiboot -c other_wfconfig.toml -o program.gba --output-elf program.elf -- [objects...] [flags...]

Cartridge metadata

GBA cartridges contain some user-configurable metadata. To edit it, create a wfconfig.toml file with the following contents:

[cartridge]
logo = "official"
title = "Program"
code = "XXXX"
maker = "WF"

Default memory placement

The GBA contains two separate blocks of memory: 32 kilobytes of fast IWRAM and 256 kilobytes of slower EWRAM. In Wonderful's GBA target, memory which is not explicitly marked as belonging to IWRAM or EWRAM with a section attribute is placed in EWRAM by default. However, this can be changed to IWRAM by using he following wfconfig.toml configuration:

[memory]
data-region = "iwram"

Memory overlays

wf-gbatool link also allows you to easily use memory overlays: overlapping areas of memory containing code and data that can be easily swapped out. For example, the following wfconfig.toml configuration:

[memory.overlay]
iwram = [
  ["one", "two"],
  ["one", "three"],
  ["four"]
]

creates three valid IWRAM layout configurations:

  • linker section .iwram_one and .iwram_two may be loaded at the same time,
  • linker section .iwram_one and .iwram_three may be loaded at the same time (but without guarantees for .iwram_two),
  • linker section .iwram_four may be loaded (but without guarantees for any of the other sections).

This allows minimizing the amount of IWRAM space occupied by code. One can use the following helper (also provided in <gba/overlay.h>) to load such an overlay from ROM to RAM:

#define gba_overlay_load(TYPE, NAME) \
    { \
        extern char __load_addr_ ## TYPE ## _ ## NAME ; \
        extern char __load_start_ ## TYPE ## _ ## NAME ; \
        extern char __load_stop_ ## TYPE ## _ ## NAME ; \
        memcpy( \
            &__load_addr_ ## TYPE ## _ ## NAME , \
            &__load_start_ ## TYPE ## _ ## NAME , \
            &__load_stop_ ## TYPE ## _ ## NAME - \
            &__load_start_ ## TYPE ## _ ## NAME ); \
    }
    
#define gba_overlay_load_iwram(NAME) gba_overlay_load(iwram, NAME)

// EWRAM is also supported!
#define gba_overlay_load_ewram(NAME) gba_overlay_load(ewram, NAME)

From there, the helper can be used as follows:

__attribute__((noinline, section(".iwram_one"))) void func_a(void) {
    // ...code...
}

__attribute__((noinline, section(".iwram_four"))) void func_b(void) {
    // ...code...
}

// ...function...
    gba_overlay_load_iwram(one);
    func_a();

    gba_overlay_load_iwram(four);
    func_b();

gba/guide/memory_management.txt · Last modified: 2024/05/08 03:52 by asie