Skip to content

Commit

Permalink
Cleaned up linker.ld / start.s
Browse files Browse the repository at this point in the history
... thanks to @AuroraWright
  • Loading branch information
d0k3 authored and devinshoemaker committed Apr 20, 2016
1 parent 224232f commit 1e66180
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 350 deletions.
136 changes: 9 additions & 127 deletions source/arm9/bootstrap.ld
@@ -1,130 +1,12 @@
OUTPUT_FORMAT("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)

MEMORY
{
ram : ORIGIN = 0x23F00000, LENGTH = 0x100000
}

SECTIONS
{
.init :
{
__text_start = . ;
KEEP (*(.init))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff
.plt : { *(.plt) } >ram = 0xff

.text : /* ALIGN (4): */
{
*(.text .stub .text.* .gnu.linkonce.t.*)
KEEP (*(.text.*personality*))
/* .gnu.warning sections are handled specially by elf32.em. */
*(.gnu.warning)
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff

.fini :
{
KEEP (*(.fini))
} >ram =0xff

__text_end = . ;

.rodata :
{
*(.rodata)
*all.rodata*(*)
*(.roda)
*(.rodata.*)
*(.gnu.linkonce.r*)
SORT(CONSTRUCTORS)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff

.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >ram
__exidx_start = .;
.ARM.exidx : { *(.ARM.exidx* .gnu.linkonce.armexidx.*) } >ram
__exidx_end = .;

/* Ensure the __preinit_array_start label is properly aligned. We
could instead move the label definition inside the section, but
the linker would then create the section even if it turns out to
be empty, which isn't pretty. */
. = ALIGN(32 / 8);
PROVIDE (__preinit_array_start = .);
.preinit_array : { KEEP (*(.preinit_array)) } >ram = 0xff
PROVIDE (__preinit_array_end = .);
PROVIDE (__init_array_start = .);
.init_array : { KEEP (*(.init_array)) } >ram = 0xff
PROVIDE (__init_array_end = .);
PROVIDE (__fini_array_start = .);
.fini_array : { KEEP (*(.fini_array)) } >ram = 0xff
PROVIDE (__fini_array_end = .);

.ctors :
{
/* gcc uses crtbegin.o to find the start of the constructors, so
we make sure it is first. Because this is a wildcard, it
doesn't matter if the user does not actually link against
crtbegin.o; the linker won't look for a file to match a
wildcard. The wildcard also means that it doesn't matter which
directory crtbegin.o is in. */
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*(.ctors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff

.dtors :
{
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*(.dtors))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff

.eh_frame :
{
KEEP (*(.eh_frame))
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff

.gcc_except_table :
{
*(.gcc_except_table)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
} >ram = 0xff
.jcr : { KEEP (*(.jcr)) } >ram = 0
.got : { *(.got.plt) *(.got) } >ram = 0

.data ALIGN(4) : {
__data_start = ABSOLUTE(.);
*(.data)
*(.data.*)
*(.gnu.linkonce.d*)
CONSTRUCTORS
. = ALIGN(4);
__data_end = ABSOLUTE(.) ;
} >ram = 0xff

.bss ALIGN(4) :
{
__bss_start = ABSOLUTE(.);
__bss_start__ = ABSOLUTE(.);
*(.dynbss)
*(.gnu.linkonce.b*)
*(.bss*)
*(COMMON)
. = ALIGN(4); /* REQUIRED. LD is flaky without it. */
__bss_end__ = ABSOLUTE(.);
__end__ = ABSOLUTE(.);
} >ram

.stack 0x80000 : { _stack = .; *(.stack) }
}
. = 0x23F00000;
.text.start : { *(.text.start) }
.text : { *(.text) }
.data : { *(.data) }
.bss : { *(.bss COMMON) }
.rodata : { *(.rodata) }
. = ALIGN(4);
__end__ = ABSOLUTE(.);
}
139 changes: 48 additions & 91 deletions source/arm9/source/bs-start.s
@@ -1,106 +1,63 @@
#ifdef EXEC_BOOTSTRAP

.section ".init"
.global _start
.extern main
.section .text.start
.align 4
.arm

#define SIZE_32KB 0b01110
#define SIZE_128KB 0b10000
#define SIZE_512KB 0b10010
#define SIZE_2MB 0b10100
#define SIZE_128MB 0b11010
#define SIZE_256MB 0b11011
#define SIZE_4GB 0b11111

@ Makes a MPU partition value
#define MAKE_PARTITION(offset, size_enum) \
(((offset) >> 12 << 12) | ((size_enum) << 1) | 1)


.global _start
_start:
b _init

@ required, don't move :)
@ will be set to FIRM ARM9 entry point by BRAHMA
arm9ep_backup: .long 0xFFFF0000

_mpu_partition_table:
.word MAKE_PARTITION(0x00000000, SIZE_4GB) @ 0: Background region
.word MAKE_PARTITION(0x00000000, SIZE_128MB) @ 1: Instruction TCM (mirrored every 32KB)
.word MAKE_PARTITION(0x08000000, SIZE_2MB) @ 2: ARM9 internal memory
.word MAKE_PARTITION(0x10000000, SIZE_128MB) @ 3: IO region
.word MAKE_PARTITION(0x18000000, SIZE_128MB) @ 4: external device memory
.word MAKE_PARTITION(0x1FF80000, SIZE_512KB) @ 5: AXI WRAM
.word MAKE_PARTITION(0x20000000, SIZE_256MB) @ 6: FCRAM
.word 0 @ 7: Unused

_populate_mpu:
push {r4-r5, lr}
ldr r4, =_mpu_partition_table

ldr r5, [r4, #0x0] @ mmu_partition_table[0] load
mcr p15, 0, r5, c6, c0, 0 @ mmu_partition_table[0] write
ldr r5, [r4, #0x4]
mcr p15, 0, r5, c6, c1, 0
ldr r5, [r4, #0x8]
mcr p15, 0, r5, c6, c2, 0
ldr r5, [r4, #0xC]
mcr p15, 0, r5, c6, c3, 0
ldr r5, [r4, #0x10]
mcr p15, 0, r5, c6, c4, 0
ldr r5, [r4, #0x14]
mcr p15, 0, r5, c6, c5, 0
ldr r5, [r4, #0x18]
mcr p15, 0, r5, c6, c6, 0
ldr r5, [r4, #0x1C]
mcr p15, 0, r5, c6, c7, 0
@ Change the stack pointer
mov sp, #0x27000000

@ Give read/write access to all the memory regions
ldr r5, =0x03333333
mcr p15, 0, r5, c5, c0, 2 @ data access
ldr r5, =0x03300330
mcr p15, 0, r5, c5, c0, 3 @ instruction access

mov r5, #0x66
mcr p15, 0, r5, c2, c0, 0 @ data cachable
mcr p15, 0, r5, c2, c0, 1 @ instruction cachable

mov r5, #0x10
mcr p15, 0, r5, c3, c0, 0 @ data bufferable

pop {r4-r5, pc}

_enable_caches:
push {r4-r5, lr}

bl _populate_mpu
ldr r5, =0x33333333
mcr p15, 0, r5, c5, c0, 2 @ write data access
mcr p15, 0, r5, c5, c0, 3 @ write instruction access

@ Sets MPU permissions and cache settings
ldr r0, =0xFFFF001D @ ffff0000 32k
ldr r1, =0x01FF801D @ 01ff8000 32k
ldr r2, =0x08000027 @ 08000000 1M
ldr r3, =0x10000021 @ 10000000 128k
ldr r4, =0x10100025 @ 10100000 512k
ldr r5, =0x20000035 @ 20000000 128M
ldr r6, =0x1FF00027 @ 1FF00000 1M
ldr r7, =0x1800002D @ 18000000 8M
mov r10, #0x25
mov r11, #0x25
mov r12, #0x25
mcr p15, 0, r0, c6, c0, 0
mcr p15, 0, r1, c6, c1, 0
mcr p15, 0, r2, c6, c2, 0
mcr p15, 0, r3, c6, c3, 0
mcr p15, 0, r4, c6, c4, 0
mcr p15, 0, r5, c6, c5, 0
mcr p15, 0, r6, c6, c6, 0
mcr p15, 0, r7, c6, c7, 0
mcr p15, 0, r10, c3, c0, 0 @ Write bufferable 0, 2, 5
mcr p15, 0, r11, c2, c0, 0 @ Data cacheable 0, 2, 5
mcr p15, 0, r12, c2, c0, 1 @ Inst cacheable 0, 2, 5

@ Enable caches
mrc p15, 0, r4, c1, c0, 0 @ read control register
orr r4, r4, #(1<<18) @ - itcm enable
orr r4, r4, #(1<<12) @ - instruction cache enable
orr r4, r4, #(1<<2) @ - data cache enable
orr r4, r4, #(1<<0) @ - mpu enable
mcr p15, 0, r4, c1, c0, 0 @ write control register

@ Flush caches
mov r5, #0
mcr p15, 0, r5, c7, c5, 0 @ flush I-cache
mcr p15, 0, r5, c7, c6, 0 @ flush D-cache
mcr p15, 0, r5, c7, c10, 4 @ drain write buffer

mrc p15, 0, r4, c1, c0, 0
orr r4, r4, #(1<<12) @ instruction cache enable
orr r4, r4, #(1<<2) @ data cache enable
orr r4, r4, #(1<<0) @ mpu enable
mcr p15, 0, r4, c1, c0, 0

pop {r4-r5, pc}

_init:
push {r0-r12, lr}
@ Fixes mounting of SDMC
ldr r0, =0x10000020
mov r1, #0x340
str r1, [r0]

bl _enable_caches
bl main

mrc p15, 0, r4, c1, c0, 0
bic r4, r4, #(1<<0) @ mpu disable
mcr p15, 0, r4, c1, c0, 0

pop {r0-r12, lr}

@ return control to FIRM
ldr pc, arm9ep_backup
.die:
b .die

#endif // EXEC_BOOTSTRAP

0 comments on commit 1e66180

Please sign in to comment.