From 977213d712fb8982bd6212517e5bd8cd380d10bb Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Fri, 30 Aug 2024 05:46:22 -0500 Subject: [PATCH] add trivial example program --- .gitignore | 6 ++- Makefile | 11 ++++ addresses_arm9.lds | 5 ++ arm9.lds | 70 ++++++++++++++++++++++++++ arm9.mk | 5 ++ common.mk | 91 +++++++++++++++++++++++++++++++++ debug.lds | 94 +++++++++++++++++++++++++++++++++++ header.s | 53 ++++++++++++++++++++ logo.s | 20 ++++++++ main.c | 9 ++++ patch.py | 59 ++++++++++++++++++++++ registers/format.py | 2 +- registers/graphics_engine_a.h | 2 +- registers/graphics_engine_b.h | 2 +- start.s | 65 ++++++++++++++++++++++++ symbols.lds | 33 ++++++++++++ 16 files changed, 523 insertions(+), 4 deletions(-) create mode 100644 Makefile create mode 100644 addresses_arm9.lds create mode 100644 arm9.lds create mode 100644 arm9.mk create mode 100644 common.mk create mode 100644 debug.lds create mode 100644 header.s create mode 100644 logo.s create mode 100644 main.c create mode 100644 patch.py create mode 100644 start.s create mode 100644 symbols.lds diff --git a/.gitignore b/.gitignore index e50e45d..ca1ffe7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,7 @@ __pycache__ *.gch -*.o \ No newline at end of file +*.o +*.d +*.elf +*.bin +*.nds \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a8fc0b2 --- /dev/null +++ b/Makefile @@ -0,0 +1,11 @@ +all: main.nds + +MAIN_OBJ = \ + header.o \ + start.o \ + main.o + +main.elf: $(MAIN_OBJ) + +include arm9.mk +include common.mk diff --git a/addresses_arm9.lds b/addresses_arm9.lds new file mode 100644 index 0000000..b95a94c --- /dev/null +++ b/addresses_arm9.lds @@ -0,0 +1,5 @@ +graphics_engine_a = 0x04000000; +graphics_engine_b = 0x04001000; +pram = 0x05000000; +vram = 0x06000000; +oam = 0x07000000; diff --git a/arm9.lds b/arm9.lds new file mode 100644 index 0000000..b61d403 --- /dev/null +++ b/arm9.lds @@ -0,0 +1,70 @@ +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +MEMORY +{ + rom : ORIGIN = 0x00000000, LENGTH = 4M + ram : ORIGIN = 0x02000000, LENGTH = 4M +} +SECTIONS +{ + . = ORIGIN(rom); + + .text.header ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.text.header)) + } > rom + + . = ORIGIN(ram); + + .text.arm9 ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.text.9start)) + *(.text) + *(.text.*) + *(.glue_7t) + *(.glue_7) + *(.vfp11_veneer) + *(.v4_bx) + } > ram AT> rom + + .text ALIGN(4) : SUBALIGN(4) + { + *(.text.*) + *(.text) + } > ram AT> rom + + .data ALIGN(4) : + { + *(.data) + *(.data.*) + } > ram AT> rom + + .rodata ALIGN(4) : + { + *(.rodata) + *(.rodata.*) + } > ram AT> rom + + .ctors ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.ctors)) + KEEP(*(.ctors.*)) + } > ram AT> rom + + .bss ALIGN(4) (NOLOAD) : SUBALIGN(4) + { + *(.bss) + *(.bss.*) + *(COMMON) + } > ram AT> rom + + .text.arm7 ALIGN(4) : SUBALIGN(4) + { + KEEP(*(.text.7start)) + } > ram AT> rom + + INCLUDE "debug.lds" +} + +INCLUDE "symbols.lds" +INCLUDE "addresses_arm9.lds" diff --git a/arm9.mk b/arm9.mk new file mode 100644 index 0000000..1160206 --- /dev/null +++ b/arm9.mk @@ -0,0 +1,5 @@ +TARGET = arm-none-eabi- +AARCH = -march=armv5te+nofp -mlittle-endian +CARCH = -march=armv5te+nofp -mtune=arm946e-s -mlittle-endian -mno-thumb-interwork +OBJARCH = -O elf32-littlearm -B armv5te +LDSCRIPT = arm9.lds diff --git a/common.mk b/common.mk new file mode 100644 index 0000000..fd67be6 --- /dev/null +++ b/common.mk @@ -0,0 +1,91 @@ +OPT ?= -Og +DEBUG = -g -gdwarf-4 + +AFLAGS += --fatal-warnings + +CFLAGS += -falign-functions=4 -ffunction-sections -fdata-sections -fshort-enums -ffreestanding -nostdlib -fno-builtin +#-finline-stringops +CFLAGS += -Wall -Werror -Wfatal-errors +CFLAGS += -Wno-array-bounds +#CFLAGS += -Wno-error=narrowing -Wno-error=unused-variable -Wno-error=array-bounds= +CFLAGS += -Wno-error=maybe-uninitialized +CFLAGS += -Wno-error=unused-but-set-variable +CFLAGS += -Wno-error=unused-variable + +CXXFLAGS += -fno-exceptions -fno-non-call-exceptions -fno-rtti -fno-threadsafe-statics + +# --print-gc-sections +LDFLAGS += --gc-sections --no-warn-rwx-segment --print-memory-usage --entry=_start --orphan-handling=error + +DEPFLAGS = -MMD -MP + +CC = $(TARGET)gcc +CXX = $(TARGET)g++ +AS = $(TARGET)as +LD = $(TARGET)ld +OBJCOPY = $(TARGET)objcopy +OBJDUMP = $(TARGET)objdump + +LIBGCC = $(shell $(CC) -print-file-name=libgcc.a) + +define BUILD_BINARY_O + $(OBJCOPY) \ + -I binary $(OBJARCH) \ + --rename-section .data=.data.$(basename $@) \ + $< $@ +endef + +as_obj_binary = _binary_$(subst .,_,$(subst /,_,$(1))) + +define BUILD_BINARY_H + @echo gen $@ + @echo '#pragma once' > $@ + @echo '#include ' >> $@ + @echo 'extern uint32_t $(call as_obj_binary,$<)_start __asm("$(call as_obj_binary,$<)_start");' >> $@ + @echo 'extern uint32_t $(call as_obj_binary,$<)_end __asm("$(call as_obj_binary,$<)_end");' >> $@ + @echo 'extern uint32_t $(call as_obj_binary,$<)_size __asm("$(call as_obj_binary,$<)_size");' >> $@ +endef + +%.bin.o: %.bin + $(BUILD_BINARY_O) + +%.pcm.o: %.pcm + $(BUILD_BINARY_O) + +%.data.o: %.data + $(BUILD_BINARY_O) + +%.data.pal.o: %.data.pal + $(BUILD_BINARY_O) + +%.o: %.s + $(AS) $(AARCH) $(AFLAGS) $(DEBUG) $< -o $@ + +%.o: %.c + $(CC) $(CARCH) $(CFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -MF ${<}.d -c $< -o $@ + +%.o: %.cpp + $(CXX) $(CARCH) $(CFLAGS) $(CXXFLAGS) $(OPT) $(DEBUG) $(DEPFLAGS) -MF ${<}.d -c $< -o $@ + +%.elf: + $(LD) $(LDFLAGS) -T $(LDSCRIPT) $^ -o $@ + +%.bin: %.elf + $(OBJCOPY) -O binary $< $@ + du -b $@ + +%.nds: %.bin + python patch.py $< $@ + +-include $(shell find -type f -name '*.d') + +.SUFFIXES: +.INTERMEDIATE: +.SECONDARY: +.PHONY: all clean + +%: RCS/%,v +%: RCS/% +%: %,v +%: s.% +%: SCCS/s.% diff --git a/debug.lds b/debug.lds new file mode 100644 index 0000000..d7d682a --- /dev/null +++ b/debug.lds @@ -0,0 +1,94 @@ + .rel.dyn : + { + *(.rel.init) + *(.rel.text .rel.text.* .rel.gnu.linkonce.t.*) + *(.rel.fini) + *(.rel.rodata .rel.rodata.* .rel.gnu.linkonce.r.*) + *(.rel.data.rel.ro .rel.data.rel.ro.* .rel.gnu.linkonce.d.rel.ro.*) + *(.rel.data .rel.data.* .rel.gnu.linkonce.d.*) + *(.rel.tdata .rel.tdata.* .rel.gnu.linkonce.td.*) + *(.rel.tbss .rel.tbss.* .rel.gnu.linkonce.tb.*) + *(.rel.ctors) + *(.rel.dtors) + *(.rel.got) + *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) + PROVIDE_HIDDEN (__rel_iplt_start = .); + *(.rel.iplt) + PROVIDE_HIDDEN (__rel_iplt_end = .); + } + .rela.dyn : + { + *(.rela.init) + *(.rela.text .rela.text.* .rela.gnu.linkonce.t.*) + *(.rela.fini) + *(.rela.rodata .rela.rodata.* .rela.gnu.linkonce.r.*) + *(.rela.data .rela.data.* .rela.gnu.linkonce.d.*) + *(.rela.tdata .rela.tdata.* .rela.gnu.linkonce.td.*) + *(.rela.tbss .rela.tbss.* .rela.gnu.linkonce.tb.*) + *(.rela.ctors) + *(.rela.dtors) + *(.rela.got) + *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) + PROVIDE_HIDDEN (__rela_iplt_start = .); + *(.rela.iplt) + PROVIDE_HIDDEN (__rela_iplt_end = .); + } + .rel.plt : + { + *(.rel.plt) + } + .rela.plt : + { + *(.rela.plt) + } + .plt : { *(.plt) } + .iplt : { *(.iplt) } + /* Stabs debugging sections. */ + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } + .gnu.build.attributes : { *(.gnu.build.attributes .gnu.build.attributes.*) } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section so we begin them at 0. */ + /* DWARF 1. */ + .debug 0 : { *(.debug) } + .line 0 : { *(.line) } + /* GNU DWARF 1 extensions. */ + .debug_srcinfo 0 : { *(.debug_srcinfo) } + .debug_sfnames 0 : { *(.debug_sfnames) } + /* DWARF 1.1 and DWARF 2. */ + .debug_aranges 0 : { *(.debug_aranges) } + .debug_pubnames 0 : { *(.debug_pubnames) } + /* DWARF 2. */ + .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } + .debug_abbrev 0 : { *(.debug_abbrev) } + .debug_line 0 : { *(.debug_line .debug_line.* .debug_line_end) } + .debug_frame 0 : { *(.debug_frame) } + .debug_str 0 : { *(.debug_str) } + .debug_loc 0 : { *(.debug_loc) } + .debug_macinfo 0 : { *(.debug_macinfo) } + /* SGI/MIPS DWARF 2 extensions. */ + .debug_weaknames 0 : { *(.debug_weaknames) } + .debug_funcnames 0 : { *(.debug_funcnames) } + .debug_typenames 0 : { *(.debug_typenames) } + .debug_varnames 0 : { *(.debug_varnames) } + /* DWARF 3. */ + .debug_pubtypes 0 : { *(.debug_pubtypes) } + .debug_ranges 0 : { *(.debug_ranges) } + /* DWARF 5. */ + .debug_addr 0 : { *(.debug_addr) } + .debug_line_str 0 : { *(.debug_line_str) } + .debug_loclists 0 : { *(.debug_loclists) } + .debug_macro 0 : { *(.debug_macro) } + .debug_names 0 : { *(.debug_names) } + .debug_rnglists 0 : { *(.debug_rnglists) } + .debug_str_offsets 0 : { *(.debug_str_offsets) } + .debug_sup 0 : { *(.debug_sup) } + .ARM.attributes 0 : { KEEP (*(.ARM.attributes)) KEEP (*(.gnu.attributes)) } + .got : { *(.got.plt) *(.igot.plt) *(.got) *(.igot) } + /DISCARD/ : { *(.note.GNU-stack) *(.gnu_debuglink) *(.gnu.lto_*) *(.rela.*) } diff --git a/header.s b/header.s new file mode 100644 index 0000000..b8ebb76 --- /dev/null +++ b/header.s @@ -0,0 +1,53 @@ + .section .text.header + + .fill 12,1,0x0 /* Game Title */ + .ascii "CODE" /* Game Code */ + .ascii "00" /* Maker Code */ + .byte 0x0 /* Unit Code */ + .byte 0x0 /* Encryption Seed Select */ + .byte 0x8 /* Device capacity */ + .fill 7,1,0x0 /* Reserved */ + .byte 0x0 /* Reserved */ + .byte 0x0 /* NDS region */ + .byte 0x0 /* ROM version */ + .byte 0x0 /* Autostart */ + .long _arm9_offset /* ARM9 rom offset */ + .long _arm9_entry /* ARM9 entry address */ + .long _arm9_addr /* ARM9 ram address */ + .long _arm9_size /* ARM9 size */ + .long _arm7_offset /* ARM7 rom offset */ + .long _arm7_entry /* ARM7 entry address */ + .long _arm7_addr /* ARM7 ram address */ + .long _arm7_size /* ARM7 size */ + .long 0x00000000 /* File name table offset */ + .long 0x00000000 /* File name table size */ + .long 0x00000000 /* File allocation table offset */ + .long 0x00000000 /* file allocation table size */ + .long 0x00000000 /* ARM9 overlay offset */ + .long 0x00000000 /* ARM9 overlay size */ + .long 0x00000000 /* ARM7 overlay offset */ + .long 0x00000000 /* ARM7 overlay size */ + .long 0x00586000 /* 040001a4 setting for normal commands */ + .long 0x001808F8 /* 040001a4 setting for KEY1 commands */ + .long 0x00000000 /* Icon/Title offset */ + .short 0x8e6e /* Secure Area Checksum */ + .short 0x0d7e /* Secure Area Delay */ + .long 0x02000a58 /* ARM9 auto load list hook ram address */ + .long 0x02380158 /* ARM7 auto load list hook ram address */ + .fill 8,1,0x0 /* Secure Area Disable */ + .long _rom_size /* Total used rom size */ + .long _header_size /* ROM header size */ + .fill 4,1,0x0 /* Reserved */ + .fill 8,1,0x0 /* Reserved */ + .short 0x0000 /* NAND end of ROM area */ + .short 0x0000 /* NAND start of RW area */ + .fill 24,1,0x0 /* Reserved */ + .fill 16,1,0x0 /* Reserved */ + .include "logo.s" /* Nintendo logo */ + .short 0xcf56 /* Nintendo logo checksum */ + .short 0xffff /* Header checksum */ + .long 0x00000000 /* Debug rom offset */ + .long 0x00000000 /* Debug rom size */ + .long 0x00000000 /* Debug ram address */ + .fill 4,1,0x0 /* Reserved */ + .balign 0x8000,0x0 /* Padding */ diff --git a/logo.s b/logo.s new file mode 100644 index 0000000..8875450 --- /dev/null +++ b/logo.s @@ -0,0 +1,20 @@ + .byte 0x24, 0xff, 0xae, 0x51, 0x69, 0x9a, 0xa2, 0x21 + .byte 0x3d, 0x84, 0x82, 0x0a, 0x84, 0xe4, 0x09, 0xad + .byte 0x11, 0x24, 0x8b, 0x98, 0xc0, 0x81, 0x7f, 0x21 + .byte 0xa3, 0x52, 0xbe, 0x19, 0x93, 0x09, 0xce, 0x20 + .byte 0x10, 0x46, 0x4a, 0x4a, 0xf8, 0x27, 0x31, 0xec + .byte 0x58, 0xc7, 0xe8, 0x33, 0x82, 0xe3, 0xce, 0xbf + .byte 0x85, 0xf4, 0xdf, 0x94, 0xce, 0x4b, 0x09, 0xc1 + .byte 0x94, 0x56, 0x8a, 0xc0, 0x13, 0x72, 0xa7, 0xfc + .byte 0x9f, 0x84, 0x4d, 0x73, 0xa3, 0xca, 0x9a, 0x61 + .byte 0x58, 0x97, 0xa3, 0x27, 0xfc, 0x03, 0x98, 0x76 + .byte 0x23, 0x1d, 0xc7, 0x61, 0x03, 0x04, 0xae, 0x56 + .byte 0xbf, 0x38, 0x84, 0x00, 0x40, 0xa7, 0x0e, 0xfd + .byte 0xff, 0x52, 0xfe, 0x03, 0x6f, 0x95, 0x30, 0xf1 + .byte 0x97, 0xfb, 0xc0, 0x85, 0x60, 0xd6, 0x80, 0x25 + .byte 0xa9, 0x63, 0xbe, 0x03, 0x01, 0x4e, 0x38, 0xe2 + .byte 0xf9, 0xa2, 0x34, 0xff, 0xbb, 0x3e, 0x03, 0x44 + .byte 0x78, 0x00, 0x90, 0xcb, 0x88, 0x11, 0x3a, 0x94 + .byte 0x65, 0xc0, 0x7c, 0x63, 0x87, 0xf0, 0x3c, 0xaf + .byte 0xd6, 0x25, 0xe4, 0x8b, 0x38, 0x0a, 0xac, 0x72 + .byte 0x21, 0xd4, 0xf8, 0x07 diff --git a/main.c b/main.c new file mode 100644 index 0000000..dd74991 --- /dev/null +++ b/main.c @@ -0,0 +1,9 @@ +#include "registers/graphics_engine_a.h" + +void main() +{ + graphics_engine_a.DISPCNT = (1 << 16); // DISPLAY_ON + + // palette ram + *((volatile uint16_t *)(0x05000000)) = (7 << 10) | (31 << 5) | (19 << 0); +} diff --git a/patch.py b/patch.py new file mode 100644 index 0000000..33819f4 --- /dev/null +++ b/patch.py @@ -0,0 +1,59 @@ +def crc16_modbus(b: bytes) -> int: + crc = 0xFFFF + for n in range(len(b)): + crc ^= b[n] + for i in range(8): + if crc & 1: + crc >>= 1 + crc ^= 0xA001 + else: + crc >>= 1 + return crc + +logo = [ + 0x24, 0xff, 0xae, 0x51, 0x69, 0x9a, 0xa2, 0x21, + 0x3d, 0x84, 0x82, 0x0a, 0x84, 0xe4, 0x09, 0xad, + 0x11, 0x24, 0x8b, 0x98, 0xc0, 0x81, 0x7f, 0x21, + 0xa3, 0x52, 0xbe, 0x19, 0x93, 0x09, 0xce, 0x20, + 0x10, 0x46, 0x4a, 0x4a, 0xf8, 0x27, 0x31, 0xec, + 0x58, 0xc7, 0xe8, 0x33, 0x82, 0xe3, 0xce, 0xbf, + 0x85, 0xf4, 0xdf, 0x94, 0xce, 0x4b, 0x09, 0xc1, + 0x94, 0x56, 0x8a, 0xc0, 0x13, 0x72, 0xa7, 0xfc, + 0x9f, 0x84, 0x4d, 0x73, 0xa3, 0xca, 0x9a, 0x61, + 0x58, 0x97, 0xa3, 0x27, 0xfc, 0x03, 0x98, 0x76, + 0x23, 0x1d, 0xc7, 0x61, 0x03, 0x04, 0xae, 0x56, + 0xbf, 0x38, 0x84, 0x00, 0x40, 0xa7, 0x0e, 0xfd, + 0xff, 0x52, 0xfe, 0x03, 0x6f, 0x95, 0x30, 0xf1, + 0x97, 0xfb, 0xc0, 0x85, 0x60, 0xd6, 0x80, 0x25, + 0xa9, 0x63, 0xbe, 0x03, 0x01, 0x4e, 0x38, 0xe2, + 0xf9, 0xa2, 0x34, 0xff, 0xbb, 0x3e, 0x03, 0x44, + 0x78, 0x00, 0x90, 0xcb, 0x88, 0x11, 0x3a, 0x94, + 0x65, 0xc0, 0x7c, 0x63, 0x87, 0xf0, 0x3c, 0xaf, + 0xd6, 0x25, 0xe4, 0x8b, 0x38, 0x0a, 0xac, 0x72, + 0x21, 0xd4, 0xf8, 0x07, +] +logo_b = bytes(logo) +assert crc16_modbus(logo_b) == 0xcf56 + +import sys +with open(sys.argv[1], 'rb') as f: + buf = bytearray(f.read()) + +assert buf[0x15c] == 0x56 +assert buf[0x15d] == 0xcf + +logo_crc = crc16_modbus(buf[0x0c0:0xc0 + 0x9c]) +print(hex(logo_crc)) +assert logo_crc == 0xcf56 + +header_crc = crc16_modbus(buf[0:0x15e]) +print(hex(header_crc)) + +import struct +header_crc_b = struct.pack('') print('#include ') -print('#include ') +print('#define static_assert _Static_assert') print('') print(f'struct {struct_name} {{') for line in c_source(registers): diff --git a/registers/graphics_engine_a.h b/registers/graphics_engine_a.h index 56818a3..b721dec 100644 --- a/registers/graphics_engine_a.h +++ b/registers/graphics_engine_a.h @@ -1,6 +1,6 @@ #include #include -#include +#define static_assert _Static_assert struct graphics_engine_a { volatile uint32_t DISPCNT; diff --git a/registers/graphics_engine_b.h b/registers/graphics_engine_b.h index e2720c7..1369205 100644 --- a/registers/graphics_engine_b.h +++ b/registers/graphics_engine_b.h @@ -1,6 +1,6 @@ #include #include -#include +#define static_assert _Static_assert struct graphics_engine_b { volatile uint32_t DISPCNT; diff --git a/start.s b/start.s new file mode 100644 index 0000000..d0783ae --- /dev/null +++ b/start.s @@ -0,0 +1,65 @@ + .macro FILL_ZERO_32_BYTE_ALIGNED + cmp r1, r10 + beq _fill_break.\@ + .irp i, 2, 3, 4, 5, 6, 7, 8, 9 + mov r\i, #0 + .endr +_fill_loop.\@: + stmia r1!, {r2 - r9} + cmp r1, r10 + blt _fill_loop.\@ +_fill_break.\@: + .endm + + .macro COPY_32_BYTE_ALIGNED + cmp r1, r10 + beq _fill_break.\@ +_fill_loop.\@: + ldmia r0!, {r2 - r9} + stmia r1!, {r2 - r9} + cmp r1, r10 + bne _fill_loop.\@ +_fill_break.\@: + .endm + + .section .text.9start + .global _start +_start: + /* +_link_text: + ldr r0, =__text_load_start + ldr r1, =__text_link_start + ldr r10, =__text_link_end + COPY_32_BYTE_ALIGNED + +_link_data: + ldr r0, =__data_load_start + ldr r1, =__data_link_start + ldr r10, =__data_link_end + COPY_32_BYTE_ALIGNED + +_link_rodata: + ldr r0, =__rodata_load_start + ldr r1, =__rodata_link_start + ldr r10, =__rodata_link_end + COPY_32_BYTE_ALIGNED + */ + +_link_bss: + ldr r1, =__bss_link_start + ldr r10, =__bss_link_end + FILL_ZERO_32_BYTE_ALIGNED + +_c_runtime: + /* set stack pointer */ + ldr sp, =0x23ffffc + + /* jump to main */ + ldr r0, =main + bx r0 + + .section .text.7start + .global _7start +_7start: + mov r1, #0x7 + b _7start diff --git a/symbols.lds b/symbols.lds new file mode 100644 index 0000000..0f700e6 --- /dev/null +++ b/symbols.lds @@ -0,0 +1,33 @@ +__stack_end = ORIGIN(ram) + LENGTH(ram) - 4; + +__text_link_start = ADDR(.text); +__text_link_end = ADDR(.text) + SIZEOF(.text); +__text_load_start = LOADADDR(.text); + +__data_link_start = ADDR(.data); +__data_link_end = ADDR(.data) + SIZEOF(.data); +__data_load_start = LOADADDR(.data); + +__rodata_link_start = ADDR(.rodata); +__rodata_link_end = ADDR(.rodata) + SIZEOF(.rodata); +__rodata_load_start = LOADADDR(.rodata); + +__ctors_link_start = ADDR(.ctors); +__ctors_link_end = ADDR(.ctors) + SIZEOF(.ctors); + +__bss_link_start = ADDR(.bss); +__bss_link_end = ADDR(.bss) + SIZEOF(.bss); + +/* header symbols */ +_arm9_offset = LOADADDR(.text.arm9); +_arm9_entry = ADDR(.text.arm9); +_arm9_addr = ADDR(.text.arm9); +_arm9_size = SIZEOF(.text.arm9); + +_arm7_offset = LOADADDR(.text.arm7); +_arm7_entry = ADDR(.text.arm7); +_arm7_addr = ADDR(.text.arm7); +_arm7_size = SIZEOF(.text.arm7); + +_rom_size = SIZEOF(.text.header) + SIZEOF(.text.arm9) + SIZEOF(.text.arm7); +_header_size = SIZEOF(.text.header);