Refactor DS ARM9/ARM7 crt0s/linkscripts to support DSi section loading

This commit is contained in:
fincs 2017-01-10 01:03:23 +01:00
parent 0e0f7eff77
commit e2600d9ac1
6 changed files with 224 additions and 87 deletions

View File

@ -37,26 +37,26 @@ SECTIONS
{
__arm7i_start__ = .;
*(.twl)
*.twl.*(.text .stub .text.* .gnu.linkonce.t.*)
*.twl.*(.rodata)
*.twl.*(.roda)
*.twl.*(.rodata.*)
*.twl.*(.data)
*.twl.*(.data.*)
*.twl.*(.gnu.linkonce.d*)
*.twl*(.text .stub .text.* .gnu.linkonce.t.*)
*.twl*(.rodata)
*.twl*(.roda)
*.twl*(.rodata.*)
*.twl*(.data)
*.twl*(.data.*)
*.twl*(.gnu.linkonce.d*)
__arm7i_end__ = .;
} >twl_iwram AT>twl_ewram :arm7i
.twl_bss ALIGN(4) (NOLOAD) :
{
__twl_bss_start__ = .;
*.(.twl_bss)
*(.twl_bss)
*.twl.*(.dynbss)
*.twl.*(.gnu.linkonce.b*)
*.twl.*(.bss*)
*.twl.*(COMMON)
__twl_bss_end__ = .;
}
} >twl_iwram :NONE
.crt0 :
{
@ -66,7 +66,7 @@ SECTIONS
__arm7_lma__ = .;
.text : /* ALIGN (4): */
.text :
{
__arm7_start__ = .;
KEEP (*(SORT_NONE(.init)))
@ -222,4 +222,4 @@ SECTIONS
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
/* These must appear regardless of . */
}
}

View File

@ -23,13 +23,20 @@ _start:
msr cpsr, r0
ldr sp, =__sp_usr @ Set user stack
adr r1, __sync_start @ Perform ARM7<->ARM9 sync code
ldr r2, =__arm7_start__
mov r3, #(__sync_end-__sync_start)
mov r8, r2
bl CopyMem
mov r3, r8
bl _blx_r3_stub
@---------------------------------------------------------------------------------
@ Copy initialized data (data section) from LMA to VMA (EWRAM to IWRAM)
@---------------------------------------------------------------------------------
adr r0, arm7lma
adr r0, arm7lma @ Calculate ARM7 LMA
ldr r1, [r0]
add r1, r0
add r1, r1, r0
ldr r2, =__arm7_start__
ldr r4, =__arm7_end__
bl CopyMemCheck
@ -39,6 +46,22 @@ _start:
sub r1, r1, r0
bl ClearMem
cmp r10, #1
bne NotTWL
ldr r1, =__dsimode @ set DSi mode flag
strb r10, [r1]
ldr r1, =__arm7i_lma
ldr r2, =__arm7i_start__
ldr r4, =__arm7i_end__
bl CopyMemCheck
ldr r0, =__twl_bss_start__ @ Clear TWL BSS section to 0x00
ldr r1, =__twl_bss_end__
sub r1, r1, r0
bl ClearMem
NotTWL:
ldr r3, =__libc_init_array @ global constructors
bl _blx_r3_stub
@ -46,17 +69,49 @@ _start:
mov r1, #0 @ char *argv[]
ldr r3, =main
ldr lr,=__libnds_exit
@---------------------------------------------------------------------------------
mov r12, #0x4000000 @ tell arm9 we are ready
mov r9, #0
str r9, [r12, #0x180]
_blx_r3_stub:
@---------------------------------------------------------------------------------
bx r3
arm7lma:
.word __arm7_lma__ - .
.word __arm7_lma__ - .
.pool
@---------------------------------------------------------------------------------
@ ARM7<->ARM9 synchronization code
@---------------------------------------------------------------------------------
__sync_start:
push {lr}
mov r12, #0x4000000
mov r9, #0x0
bl IPCSync
mov r9, #(0x9<<8)
str r9, [r12, #0x180]
mov r9, #0xA
bl IPCSync
mov r9, #(0xB<<8)
str r9, [r12, #0x180]
mov r9, #0xC
bl IPCSync
mov r9, #(0xD<<8)
str r9, [r12, #0x180]
IPCRecvFlag:
ldr r10, [r12, #0x180]
and r10, r10, #0xF
cmp r10, #0xC
beq IPCRecvFlag
pop {pc}
IPCSync:
ldr r10, [r12, #0x180]
and r10, r10, #0xF
cmp r10, r9
bne IPCSync
bx lr
__sync_end:
@---------------------------------------------------------------------------------
@ Clear memory to 0x00 if length != 0
@ r0 = Start Address

View File

@ -2,11 +2,9 @@ OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
__vectors_start = ORIGIN(vectors);
__itcm_start = ORIGIN(itcm);
__ewram_end = ORIGIN(ewram) + LENGTH(ewram);
__eheap_end = ORIGIN(ewram) + LENGTH(ewram);
__dtcm_start = ORIGIN(dtcm);
__dtcm_top = ORIGIN(dtcm) + LENGTH(dtcm);
__irq_flags = __dtcm_top - 0x08;
__irq_vector = __dtcm_top - 0x04;
@ -15,60 +13,67 @@ __sp_svc = __dtcm_top - 0x100;
__sp_irq = __sp_svc - 0x100;
__sp_usr = __sp_irq - 0x100;
PHDRS {
main PT_LOAD FLAGS(7);
dtcm PT_LOAD FLAGS(7);
itcm PT_LOAD FLAGS(7);
vectors PT_LOAD FLAGS(7);
twl PT_LOAD FLAGS(0x100007);
}
SECTIONS
{
/* Secure area crap */
.secure : { *(.secure) } >ewram = 0
.secure : { *(.secure) } >ewram :main = 0
.crt0 :
{
__text_start = . ;
KEEP (*(.crt0))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ewram = 0xff
} >ewram :main = 0x00
.plt : { *(.plt) } >ewram = 0xff
.plt : { *(.plt) } >ewram :main = 0xff
.init :
{
KEEP (*(SORT_NONE(.init)))
} >ewram
} >ewram :main
.text : /* ALIGN (4): */
{
*(EXCLUDE_FILE (*.itcm*) .text)
*(.text.*)
*(.stub)
*(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .text)
*(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .stub)
*(EXCLUDE_FILE(*.itcm* *.vectors* *.twl*) .text.*)
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.gnu.linkonce.t*)
*(EXCLUDE_FILE(*.twl*) .gnu.warning)
*(EXCLUDE_FILE(*.twl*) .gnu.linkonce.t*)
*(.glue_7)
*(.glue_7t)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ewram = 0xff
} >ewram :main = 0xff
.fini :
{
KEEP (*(.fini))
} >ewram =0xff
} >ewram :main =0xff
__text_end = . ;
.rodata :
{
*(.rodata)
*(EXCLUDE_FILE(*.twl*) .rodata)
*all.rodata*(*)
*(.roda)
*(.rodata.*)
*(.gnu.linkonce.r*)
*(EXCLUDE_FILE(*.twl*) .roda)
*(EXCLUDE_FILE(*.twl*) .rodata.*)
*(EXCLUDE_FILE(*.twl*) .gnu.linkonce.r*)
SORT(CONSTRUCTORS)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ewram = 0xff
} >ewram :main = 0xff
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ewram :main
__exidx_start = .;
ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram
ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ewram :main
__exidx_end = .;
/* Ensure the __preinit_array_start label is properly aligned. We
@ -79,21 +84,21 @@ SECTIONS
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { KEEP (*(.preinit_array)) } >ewram = 0xff
.preinit_array : { KEEP (*(.preinit_array)) } >ewram :main = 0xff
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array :
{
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
} >ewram = 0xff
} >ewram :main = 0xff
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array :
{
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
} >ewram = 0xff
} >ewram :main = 0xff
PROVIDE (__fini_array_end = .);
@ -110,7 +115,7 @@ SECTIONS
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ewram = 0xff
} >ewram :main = 0xff
.dtors :
{
@ -119,21 +124,21 @@ SECTIONS
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ewram = 0xff
} >ewram :main = 0xff
.eh_frame :
{
KEEP (*(.eh_frame))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ewram = 0xff
} >ewram :main = 0xff
.gcc_except_table :
{
*(.gcc_except_table)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ewram = 0xff
.jcr : { KEEP (*(.jcr)) } >ewram = 0
.got : { *(.got.plt) *(.got) *(.rel.got) } >ewram = 0
} >ewram :main = 0xff
.jcr : { KEEP (*(.jcr)) } >ewram :main = 0
.got : { *(.got.plt) *(.got) *(.rel.got) } >ewram :main = 0
.ewram ALIGN(4) :
{
@ -141,52 +146,51 @@ SECTIONS
*(.ewram)
*ewram.*(.text)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ewram = 0xff
} >ewram :main = 0xff
.data ALIGN(4) :
{
__data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
*(EXCLUDE_FILE(*.twl*) .data)
*(EXCLUDE_FILE(*.twl*) .data.*)
*(EXCLUDE_FILE(*.twl*) .gnu.linkonce.d*)
CONSTRUCTORS
. = ALIGN(4);
__data_end = ABSOLUTE(.) ;
} >ewram = 0xff
} >ewram :main = 0xff
__dtcm_lma = . ;
__bss_vma = . ;
.dtcm __dtcm_start : AT (__dtcm_lma)
.dtcm :
{
__dtcm_lma = LOADADDR(.dtcm);
__dtcm_start = ABSOLUTE(.);
*(.dtcm)
*(.dtcm.*)
. = ALIGN(4);
__dtcm_end = ABSOLUTE(.);
} >dtcm = 0xff
} >dtcm AT>ewram :dtcm = 0xff
__itcm_lma = __dtcm_lma + SIZEOF(.dtcm);
.itcm __itcm_start : AT (__itcm_lma)
.itcm :
{
__itcm_lma = LOADADDR(.itcm);
__itcm_start = ABSOLUTE(.);
*(.itcm)
*itcm.*(.text)
*.itcm*(.text .stub .text.*)
. = ALIGN(4);
__itcm_end = ABSOLUTE(.);
} >itcm = 0xff
__vectors_lma = __itcm_lma + SIZEOF(.itcm);
} >itcm AT>ewram :itcm = 0xff
.vectors __vectors_start : AT (__vectors_lma)
.vectors :
{
__vectors_lma = LOADADDR(.vectors);
__vectors_start = ABSOLUTE(.);
*(.vectors)
*vectors.*(.text)
*.vectors*(.text .stub .text.*)
. = ALIGN(4);
__vectors_end = ABSOLUTE(.);
} >vectors = 0xff
} >vectors AT>ewram :vectors = 0xff
.sbss __dtcm_end (NOLOAD):
{
@ -195,22 +199,48 @@ SECTIONS
*(.sbss)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
__sbss_end = ABSOLUTE(.);
} >dtcm
} >dtcm :NONE
.bss __bss_vma (NOLOAD):
{
__bss_start = ABSOLUTE(.);
__bss_start__ = ABSOLUTE(.);
*(.dynbss)
*(.gnu.linkonce.b*)
*(.bss*)
*(COMMON)
*(EXCLUDE_FILE(*.twl*) .dynbss)
*(EXCLUDE_FILE(*.twl*) .gnu.linkonce.b*)
*(EXCLUDE_FILE(*.twl*) .bss*)
*(EXCLUDE_FILE(*.twl*) COMMON)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
__bss_end__ = ABSOLUTE(.) ;
__end__ = ABSOLUTE(.) ;
} AT>ewram
} >ewram :NONE
.twl __end__ : AT(MAX(0x2400000,MAX(__end__,LOADADDR(.vectors)+SIZEOF(.vectors))))
{
__arm9i_lma = LOADADDR(.twl);
__arm9i_start__ = ABSOLUTE(.);
*(.twl)
*.twl*(.text .stub .text.* .gnu.linkonce.t.*)
*.twl*(.rodata)
*.twl*(.roda)
*.twl*(.rodata.*)
*.twl*(.data)
*.twl*(.data.*)
*.twl*(.gnu.linkonce.d*)
__arm9i_end__ = ABSOLUTE(.);
} :twl
.twl_bss __arm9i_end__ (NOLOAD):
{
__twl_bss_start__ = ABSOLUTE(.);
*(.twl_bss)
*.twl*(.dynbss)
*.twl*(.gnu.linkonce.b*)
*.twl*(.bss*)
*.twl*(COMMON)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
__twl_bss_end__ = ABSOLUTE(.);
__twl_end__ = ABSOLUTE(.);
} :NONE
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }

View File

@ -1,7 +1,5 @@
MEMORY {
rom : ORIGIN = 0x08000000, LENGTH = 32M
ewram : ORIGIN = 0x02000000, LENGTH = 4M - 48k
ewram : ORIGIN = 0x02000000, LENGTH = 4M - 512k
dtcm : ORIGIN = 0x0b000000, LENGTH = 16K
vectors : ORIGIN = 0x01000000, LENGTH = 256
itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256

View File

@ -16,7 +16,7 @@
@---------------------------------------------------------------------------------
_start:
@---------------------------------------------------------------------------------
mov r0, #0x04000000 @ IME = 0;
mov r0, #0x04000000 @ IME = 0;
str r0, [r0, #0x208]
@ set sensible stacks to allow bios call
@ -46,6 +46,28 @@ _start:
msr cpsr, r0
ldr sp, =__sp_usr @ Set user stack
mov r12, #0x4000000 @ Read system ROM status (NTR/TWL)
ldrb r11, [r12,r12,lsr #12]
and r11, r11, #0x3
mov r9, #(0x0<<8) @ Synchronize with ARM7
str r9, [r12, #0x180]
mov r9, #0x9
bl IPCSync
mov r9, #(0xA<<8)
str r9, [r12, #0x180]
mov r9, #0xB
bl IPCSync
mov r9, #(0xC<<8)
str r9, [r12, #0x180]
mov r9, #0xD
bl IPCSync
mov r9, r11, lsl #8
str r9, [r12, #0x180]
mov r9, #0
bl IPCSync
str r9, [r12, #0x180]
ldr r1, =__itcm_lma @ Copy instruction tightly coupled memory (itcm section) from LMA to VMA
ldr r2, =__itcm_start
ldr r4, =__itcm_end
@ -61,6 +83,9 @@ _start:
ldr r4, =__dtcm_end
bl CopyMemCheck
cmp r11, #1
ldrne r10, =__end__ @ (DS mode) heap start
ldreq r10, =__twl_end__ @ (DSi mode) heap start
bl checkARGV @ check and process argv trickery
ldr r0, =__bss_start__ @ Clear BSS section
@ -72,14 +97,32 @@ _start:
ldr r1, =__sbss_end
sub r1, r1, r0
bl ClearMem
cmp r11, #1
bne NotTWL
ldr r9, =__dsimode @ set DSi mode flag
strb r11, [r9]
ldr r1, =__arm9i_lma @ Copy TWL area (arm9i section) from LMA to VMA
ldr r2, =__arm9i_start__
cmp r1, r2 @ skip copy if LMA=VMA
ldrne r4, =__arm9i_end__
blne CopyMemCheck
ldr r0, =__twl_bss_start__ @ Clear TWL BSS section
ldr r1, =__twl_bss_end__
sub r1, r1, r0
bl ClearMem
NotTWL:
ldr r0, =_libnds_argv
@ reset heap base
ldr r2, [r0,#20] @ newheap base
ldr r1,=fake_heap_start
str r2,[r1]
cmp r2, #0
moveq r2, r10
ldr r1, =fake_heap_start @ set heap start
str r2, [r1]
ldr r1, =fake_heap_end @ set heap end
sub r8, r8,#0xc000
@ -122,7 +165,7 @@ checkARGV:
ldr r2, [r0, #8] @ length of command line
@ copy to heap
ldr r3, =__end__ @ initial heap base
mov r3, r10 @ initial heap base
str r3, [r0, #4] @ set command line address
cmp r2, #0
@ -162,7 +205,7 @@ ClearMem:
@---------------------------------------------------------------------------------
mov r2, #3 @ Round down to nearest word boundary
add r1, r1, r2 @ Shouldn't be needed
bics r1, r1, r2 @ Clear 2 LSB (and set Z)
bics r1, r1, r2 @ Clear 2 LSB (and set Z)
bxeq lr @ Quit if copy size is 0
mov r2, #0
@ -192,7 +235,7 @@ CopyMem:
@---------------------------------------------------------------------------------
mov r0, #3 @ These commands are used in cases where
add r3, r3, r0 @ the length is not a multiple of 4,
bics r3, r3, r0 @ even though it should be.
bics r3, r3, r0 @ even though it should be.
bxeq lr @ Length is zero, so exit
CIDLoop:
ldmia r1!, {r0}
@ -202,6 +245,17 @@ CIDLoop:
bx lr
@---------------------------------------------------------------------------------
@ Synchronize with ARM7
@---------------------------------------------------------------------------------
IPCSync:
@---------------------------------------------------------------------------------
ldr r10, [r12, #0x180]
and r10, r10, #0xF
cmp r10, r9
bne IPCSync
bx lr
@---------------------------------------------------------------------------------
.align
.pool

View File

@ -1,5 +1,5 @@
MEMORY {
ewram : ORIGIN = 0x02000000, LENGTH = 16M - 48k
ewram : ORIGIN = 0x02000000, LENGTH = 15M - 512k
dtcm : ORIGIN = 0x0b000000, LENGTH = 16K
vectors : ORIGIN = 0x01000000, LENGTH = 256
itcm : ORIGIN = 0x01000100, LENGTH = 32K - 256