From a8ee5a092af9ec6b2d3a95587d8a258dc5fdb31c Mon Sep 17 00:00:00 2001 From: Dark <dark@dark.ski> Date: Fri, 19 Jan 2024 21:05:42 -0500 Subject: [PATCH 1/6] Split GM9 across two sections in memory. This is needed to implement support for Lua. Lua is way to big to fit in a single contigious section of memory without overwriting our copy of boot9 and boot11, so some clever linker manipulation was used to place things in the free space after it. This uses the following memory map: ``` AHBWRAM: 0x08000000 - 0x08080000 .vectors .text .ARM.exidx AHBWRAM2: 0x080a0000 - 0x08100000 .text (files in arm9/source/lua) .rodata .data .bss ``` --- Makefile | 16 +++++++++++--- arm9/Makefile | 4 ++-- arm9/link.ld | 61 +++++++++++++++++++++++++++++---------------------- 3 files changed, 50 insertions(+), 31 deletions(-) diff --git a/Makefile b/Makefile index 986522e7..87108380 100644 --- a/Makefile +++ b/Makefile @@ -91,15 +91,25 @@ $(VRAM_TAR): $(SPLASH) $(OVERRIDE_FONT) $(VRAM_DATA) $(VRAM_SCRIPTS) arm9/arm9.elf: $(VRAM_TAR) -firm: $(ELF) +$(OUTDIR)/AHBWRAM.bin: $(ELF) + @$(OBJCOPY) -O binary arm9/arm9.elf --only-section=AHBWRAM $@ + +$(OUTDIR)/AHBWRAM2.bin: $(ELF) + @$(OBJCOPY) -O binary arm9/arm9.elf --only-section=AHBWRAM2 $@ + +BINS := $(OUTDIR)/AHBWRAM.bin $(OUTDIR)/AHBWRAM2.bin + +firm: $(ELF) $(BINS) @mkdir -p $(call dirname,"$(FIRM)") $(call dirname,"$(FIRMD)") @echo "[FLAVOR] $(FLAVOR)" @echo "[VERSION] $(VERSION)" @echo "[BUILD] $(DBUILTL)" @echo "[FIRM] $(FIRM)" - @$(PY3) -m firmtool build $(FIRM) $(FTFLAGS) -g -D $(ELF) -C NDMA XDMA + @$(PY3) -m firmtool build $(FIRM) $(FTFLAGS) -g -D $(BINS) arm11/arm11.elf \ + -A 0x08000000 0x080a0000 -C NDMA NDMA XDMA -n 0x08000040 @echo "[FIRM] $(FIRMD)" - @$(PY3) -m firmtool build $(FIRMD) $(FTDFLAGS) -g -D $(ELF) -C NDMA XDMA + @$(PY3) -m firmtool build $(FIRMD) $(FTDFLAGS) -g -D $(BINS) arm11/arm11.elf \ + -A 0x08000000 0x080a0000 -C NDMA NDMA XDMA -n 0x08000040 vram0: $(VRAM_TAR) .FORCE # legacy target name diff --git a/arm9/Makefile b/arm9/Makefile index 0c5b8520..370eea54 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -10,8 +10,8 @@ INCDIRS := source source/common source/filesys source/crypto source/fatfs source INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)") ASFLAGS += $(SUBARCH) $(INCLUDE) -CFLAGS += $(SUBARCH) $(INCLUDE) -fno-builtin-memcpy -flto -LDFLAGS += $(SUBARCH) -Wl,--use-blx,-Map,$(TARGET).map -flto +CFLAGS += $(SUBARCH) $(INCLUDE) -fno-builtin-memcpy +LDFLAGS += $(SUBARCH) -Wl,--use-blx,-Map,$(TARGET).map include ../Makefile.common include ../Makefile.build diff --git a/arm9/link.ld b/arm9/link.ld index 5ff9a635..8567beb3 100644 --- a/arm9/link.ld +++ b/arm9/link.ld @@ -4,44 +4,53 @@ ENTRY(_start) MEMORY { - VECTORS (RX) : ORIGIN = 0x08000000, LENGTH = 64 - AHBWRAM (RWX) : ORIGIN = 0x08000040, LENGTH = 512K - 64 + AHBWRAM (RWX) : ORIGIN = 0x08000000, LENGTH = 512K + AHBWRAM2 (RWX) : ORIGIN = 0x080a0000, LENGTH = 384K } SECTIONS { - .vectors : ALIGN(4) { - __vectors_lma = LOADADDR(.vectors); - __vectors_vma = ABSOLUTE(.); - KEEP(*(.vectors)); - . = ALIGN(4); - __vectors_len = ABSOLUTE(.) - __vectors_vma; - } >VECTORS AT>AHBWRAM + /* this must come *first* so it picks up lua */ + AHBWRAM2 : ALIGN(4) { + build/lua*(.text*); - .text : ALIGN(4) { - __text_s = ABSOLUTE(.); - *(.text.start); - *(.text*); . = ALIGN(4); - __text_e = ABSOLUTE(.); - } >AHBWRAM - - .rodata : ALIGN(4) { *(.rodata*); - . = ALIGN(4); - } >AHBWRAM - .data : ALIGN(4) { - *(.data*); + /* .data */ . = ALIGN(4); - } >AHBWRAM + *(.data*); - .bss : ALIGN(4) { + . = ALIGN(4); __bss_start = .; *(.bss*); - . = ALIGN(4); __bss_end = .; - } >AHBWRAM - __end__ = ABSOLUTE(.); + __end__ = .; + } >AHBWRAM2 + + + AHBWRAM : ALIGN(4) { + __vectors_lma = .; + /* this needs to be absolute otherwise GM9 won't boot */ + __vectors_vma = ABSOLUTE(.); + KEEP(*(.vectors)); + . = ALIGN(4); + __vectors_len = . - __vectors_vma; + . = . + 0x10; + + + + . = ALIGN(4); + __text_s = .; + *(.text.start); + *(.text*); + __text_e = .; + + /* .ARM.exidx (needed for lua) */ + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + __exidx_end = .; + } >AHBWRAM } From c3189c1945aa82dfff52a7b2a74a6b4baa494b82 Mon Sep 17 00:00:00 2001 From: Dark <dark@dark.ski> Date: Fri, 19 Jan 2024 22:08:15 -0500 Subject: [PATCH 2/6] move AHBWRAM forward by 40 bytes --- Makefile | 4 ++-- arm9/link.ld | 5 +++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index 87108380..5ce3d6b6 100644 --- a/Makefile +++ b/Makefile @@ -106,10 +106,10 @@ firm: $(ELF) $(BINS) @echo "[BUILD] $(DBUILTL)" @echo "[FIRM] $(FIRM)" @$(PY3) -m firmtool build $(FIRM) $(FTFLAGS) -g -D $(BINS) arm11/arm11.elf \ - -A 0x08000000 0x080a0000 -C NDMA NDMA XDMA -n 0x08000040 + -A 0x08000040 0x080a0000 -C NDMA NDMA XDMA -n 0x08000080 @echo "[FIRM] $(FIRMD)" @$(PY3) -m firmtool build $(FIRMD) $(FTDFLAGS) -g -D $(BINS) arm11/arm11.elf \ - -A 0x08000000 0x080a0000 -C NDMA NDMA XDMA -n 0x08000040 + -A 0x08000040 0x080a0000 -C NDMA NDMA XDMA -n 0x08000080 vram0: $(VRAM_TAR) .FORCE # legacy target name diff --git a/arm9/link.ld b/arm9/link.ld index 8567beb3..ac2f9606 100644 --- a/arm9/link.ld +++ b/arm9/link.ld @@ -4,7 +4,7 @@ ENTRY(_start) MEMORY { - AHBWRAM (RWX) : ORIGIN = 0x08000000, LENGTH = 512K + AHBWRAM (RWX) : ORIGIN = 0x08000040, LENGTH = 512K - 64 AHBWRAM2 (RWX) : ORIGIN = 0x080a0000, LENGTH = 384K } @@ -30,8 +30,9 @@ SECTIONS } >AHBWRAM2 + + __vectors_lma = 0x08000000; AHBWRAM : ALIGN(4) { - __vectors_lma = .; /* this needs to be absolute otherwise GM9 won't boot */ __vectors_vma = ABSOLUTE(.); KEEP(*(.vectors)); From 9411b3821ddcc6a0ab8e3b7f78750326b56b81c4 Mon Sep 17 00:00:00 2001 From: Dark <dark@dark.ski> Date: Sat, 20 Jan 2024 09:27:55 -0500 Subject: [PATCH 3/6] apply feedback from code review --- Makefile | 14 +++++++------- arm9/Makefile | 5 +++-- arm9/link.ld | 20 ++++++++------------ arm9/source/system/xrq.c | 3 +-- 4 files changed, 19 insertions(+), 23 deletions(-) diff --git a/Makefile b/Makefile index 5ce3d6b6..5a458391 100644 --- a/Makefile +++ b/Makefile @@ -91,13 +91,13 @@ $(VRAM_TAR): $(SPLASH) $(OVERRIDE_FONT) $(VRAM_DATA) $(VRAM_SCRIPTS) arm9/arm9.elf: $(VRAM_TAR) -$(OUTDIR)/AHBWRAM.bin: $(ELF) - @$(OBJCOPY) -O binary arm9/arm9.elf --only-section=AHBWRAM $@ +$(OUTDIR)/AHBWRAM_LO.elf: $(ELF) + @$(OBJCOPY) arm9/arm9.elf -j AHBWRAM_LO $@ -$(OUTDIR)/AHBWRAM2.bin: $(ELF) - @$(OBJCOPY) -O binary arm9/arm9.elf --only-section=AHBWRAM2 $@ +$(OUTDIR)/AHBWRAM_HI.elf: $(ELF) + @$(OBJCOPY) arm9/arm9.elf -j AHBWRAM_HI $@ -BINS := $(OUTDIR)/AHBWRAM.bin $(OUTDIR)/AHBWRAM2.bin +BINS := $(OUTDIR)/AHBWRAM_LO.elf $(OUTDIR)/AHBWRAM_HI.elf firm: $(ELF) $(BINS) @mkdir -p $(call dirname,"$(FIRM)") $(call dirname,"$(FIRMD)") @@ -106,10 +106,10 @@ firm: $(ELF) $(BINS) @echo "[BUILD] $(DBUILTL)" @echo "[FIRM] $(FIRM)" @$(PY3) -m firmtool build $(FIRM) $(FTFLAGS) -g -D $(BINS) arm11/arm11.elf \ - -A 0x08000040 0x080a0000 -C NDMA NDMA XDMA -n 0x08000080 + -C NDMA NDMA XDMA @echo "[FIRM] $(FIRMD)" @$(PY3) -m firmtool build $(FIRMD) $(FTDFLAGS) -g -D $(BINS) arm11/arm11.elf \ - -A 0x08000040 0x080a0000 -C NDMA NDMA XDMA -n 0x08000080 + -C NDMA NDMA XDMA vram0: $(VRAM_TAR) .FORCE # legacy target name diff --git a/arm9/Makefile b/arm9/Makefile index 370eea54..0315f482 100644 --- a/arm9/Makefile +++ b/arm9/Makefile @@ -10,8 +10,9 @@ INCDIRS := source source/common source/filesys source/crypto source/fatfs source INCLUDE := $(foreach dir,$(INCDIRS),-I"$(shell pwd)/$(dir)") ASFLAGS += $(SUBARCH) $(INCLUDE) -CFLAGS += $(SUBARCH) $(INCLUDE) -fno-builtin-memcpy -LDFLAGS += $(SUBARCH) -Wl,--use-blx,-Map,$(TARGET).map +CFLAGS += $(SUBARCH) $(INCLUDE) -fno-builtin-memcpy +LDFLAGS += $(SUBARCH) -Wl,--use-blx,-Map,$(TARGET).map \ + -Xlinker --no-warn-rwx-segments include ../Makefile.common include ../Makefile.build diff --git a/arm9/link.ld b/arm9/link.ld index ac2f9606..be2b80a1 100644 --- a/arm9/link.ld +++ b/arm9/link.ld @@ -4,15 +4,15 @@ ENTRY(_start) MEMORY { - AHBWRAM (RWX) : ORIGIN = 0x08000040, LENGTH = 512K - 64 - AHBWRAM2 (RWX) : ORIGIN = 0x080a0000, LENGTH = 384K + AHBWRAM_LO (RWX) : ORIGIN = 0x08000040, LENGTH = 512K - 64 + AHBWRAM_HI (RWX) : ORIGIN = 0x080a0000, LENGTH = 386K } SECTIONS { /* this must come *first* so it picks up lua */ - AHBWRAM2 : ALIGN(4) { - build/lua*(.text*); + AHBWRAM_HI : ALIGN(4) { + *build/lua*(.text*); . = ALIGN(4); *(.rodata*); @@ -27,12 +27,11 @@ SECTIONS __bss_end = .; __end__ = .; - } >AHBWRAM2 - + } >AHBWRAM_HI __vectors_lma = 0x08000000; - AHBWRAM : ALIGN(4) { + AHBWRAM_LO : ALIGN(4) { /* this needs to be absolute otherwise GM9 won't boot */ __vectors_vma = ABSOLUTE(.); KEEP(*(.vectors)); @@ -40,18 +39,15 @@ SECTIONS __vectors_len = . - __vectors_vma; . = . + 0x10; - - . = ALIGN(4); - __text_s = .; *(.text.start); *(.text*); - __text_e = .; /* .ARM.exidx (needed for lua) */ . = ALIGN(4); __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; - } >AHBWRAM + } >AHBWRAM_LO + } diff --git a/arm9/source/system/xrq.c b/arm9/source/system/xrq.c index c8367f2a..7d5c2960 100644 --- a/arm9/source/system/xrq.c +++ b/arm9/source/system/xrq.c @@ -18,7 +18,6 @@ #define PC_DUMPRAD (0x10) #define SP_DUMPLEN (0x80) -extern u32 __text_s, __text_e; static bool sp_dumpable(u32 sp, u32 *sp_lower, u32 *sp_upper) { @@ -31,7 +30,7 @@ static bool sp_dumpable(u32 sp, u32 *sp_lower, u32 *sp_upper) static bool pc_dumpable(u32 pc, u32 *pc_lower, u32 *pc_upper) { - u32 code_start = (u32)(&__text_s), code_end = (u32)(&__text_e); + u32 code_start = __A9RAM0_ADDR, code_end = __A9RAM0_ADDR + __A9RAM0_LEN; if ((pc >= code_end) || (pc < code_start)) return false; From 0785e33064f1db28bec2b7429142ef80c916f948 Mon Sep 17 00:00:00 2001 From: Dark <dark@dark.ski> Date: Sat, 20 Jan 2024 09:40:14 -0500 Subject: [PATCH 4/6] remove unused space from AHBWRAM_LO --- arm9/link.ld | 1 - 1 file changed, 1 deletion(-) diff --git a/arm9/link.ld b/arm9/link.ld index be2b80a1..84bdc258 100644 --- a/arm9/link.ld +++ b/arm9/link.ld @@ -37,7 +37,6 @@ SECTIONS KEEP(*(.vectors)); . = ALIGN(4); __vectors_len = . - __vectors_vma; - . = . + 0x10; . = ALIGN(4); *(.text.start); From dedd63e15af8128e4fad4fc34fad7fa89b706bbf Mon Sep 17 00:00:00 2001 From: Dark <dark@dark.ski> Date: Mon, 22 Jan 2024 18:34:44 -0500 Subject: [PATCH 5/6] use a better memory layout --- arm9/link.ld | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/arm9/link.ld b/arm9/link.ld index 84bdc258..18da7676 100644 --- a/arm9/link.ld +++ b/arm9/link.ld @@ -13,20 +13,9 @@ SECTIONS /* this must come *first* so it picks up lua */ AHBWRAM_HI : ALIGN(4) { *build/lua*(.text*); + libm*(.text*); + *(.rodata.vram_data); - . = ALIGN(4); - *(.rodata*); - - /* .data */ - . = ALIGN(4); - *(.data*); - - . = ALIGN(4); - __bss_start = .; - *(.bss*); - __bss_end = .; - - __end__ = .; } >AHBWRAM_HI @@ -47,6 +36,20 @@ SECTIONS __exidx_start = .; *(.ARM.exidx* .gnu.linkonce.armexidx.*) __exidx_end = .; + + . = ALIGN(4); + *(.rodata*); + + /* .data */ + . = ALIGN(4); + *(.data*); + + . = ALIGN(4); + __bss_start = .; + *(.bss*); + __bss_end = .; + + __end__ = .; } >AHBWRAM_LO } From 1cefa190157d7f351d712b8d9d2f3bedfd93ceb8 Mon Sep 17 00:00:00 2001 From: Dark <dark@dark.ski> Date: Tue, 23 Jan 2024 19:54:22 -0500 Subject: [PATCH 6/6] fix vectors --- arm9/link.ld | 6 +++--- arm9/source/start.s | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arm9/link.ld b/arm9/link.ld index 18da7676..0e28f4d1 100644 --- a/arm9/link.ld +++ b/arm9/link.ld @@ -19,13 +19,13 @@ SECTIONS } >AHBWRAM_HI - __vectors_lma = 0x08000000; + __vectors_vma = 0x08000000; AHBWRAM_LO : ALIGN(4) { /* this needs to be absolute otherwise GM9 won't boot */ - __vectors_vma = ABSOLUTE(.); + __vectors_lma = ABSOLUTE(.); KEEP(*(.vectors)); . = ALIGN(4); - __vectors_len = . - __vectors_vma; + __vectors_len = . - __vectors_lma; . = ALIGN(4); *(.text.start); diff --git a/arm9/source/start.s b/arm9/source/start.s index 547f11bd..19595b0a 100644 --- a/arm9/source/start.s +++ b/arm9/source/start.s @@ -83,7 +83,7 @@ _start: @ Install exception handlers ldr r0, =__vectors_lma ldr r1, =__vectors_len - ldr r2, =XRQ_Start + ldr r2, =__vectors_vma add r1, r0, r1 .LXRQ_Install: cmp r0, r1