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