This is an old revision of the document!
Memory management
The GBA contains multiple separate blocks of memory
- 32 kilobytes of fast IWRAM,
- 256 kilobytes of slower EWRAM,
- 96 kilobytes of video RAM.
To place a variable or function explciitly in IWRAM or EWRAM, you can use ELF section attributes like so:
__attribute__((section(".iwram.fast_variable")))
int fast_variable;
__attribute__((section(".ewram.my_function")))
void my_function(void) {
printf("Running from EWRAM!\n");
}
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 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_oneand.iwram_twomay be loaded at the same time, - linker section
.iwram_oneand.iwram_threemay be loaded at the same time (but without guarantees for.iwram_two), - linker section
.iwram_fourmay 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();
