summaryrefslogtreecommitdiffstats
path: root/firmware/target/arm
diff options
context:
space:
mode:
authorAmaury Pouly <pamaury@rockbox.org>2011-09-23 20:40:52 +0000
committerAmaury Pouly <pamaury@rockbox.org>2011-09-23 20:40:52 +0000
commit1322b58b17201ba70d35e6121ddaa87c0dceaf5b (patch)
treee18ac4ea1ca21a4c1ad00c987cf2e9038d19f883 /firmware/target/arm
parentd1e241f55a4b09149019d459f4db1ae79e6d8c1b (diff)
downloadrockbox-1322b58b17201ba70d35e6121ddaa87c0dceaf5b.tar.gz
rockbox-1322b58b17201ba70d35e6121ddaa87c0dceaf5b.tar.bz2
rockbox-1322b58b17201ba70d35e6121ddaa87c0dceaf5b.zip
imx233/fuze+: rework crt0 and linker script to be able to load at any address and self-copy at the right one
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30587 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/target/arm')
-rw-r--r--firmware/target/arm/imx233/app.lds10
-rw-r--r--firmware/target/arm/imx233/boot.lds10
-rw-r--r--firmware/target/arm/imx233/crt0.S33
3 files changed, 48 insertions, 5 deletions
diff --git a/firmware/target/arm/imx233/app.lds b/firmware/target/arm/imx233/app.lds
index a961222749..0eeecc1ab8 100644
--- a/firmware/target/arm/imx233/app.lds
+++ b/firmware/target/arm/imx233/app.lds
@@ -34,6 +34,11 @@ SECTIONS
{
loadaddress = UNCACHED_DRAM_ADDR;
_loadaddress = UNCACHED_DRAM_ADDR;
+
+ .dramcopystart (NOLOAD) :
+ {
+ _dramcopystart = .;
+ } > DRAM
.text :
{
@@ -76,6 +81,11 @@ SECTIONS
_initcopy = LOADADDR(.init);
+ .dramcopyend (NOLOAD) :
+ {
+ _dramcopyend = .;
+ } > DRAM
+
.stack (NOLOAD) :
{
*(.stack)
diff --git a/firmware/target/arm/imx233/boot.lds b/firmware/target/arm/imx233/boot.lds
index 206e0bb99f..d909b9fbd1 100644
--- a/firmware/target/arm/imx233/boot.lds
+++ b/firmware/target/arm/imx233/boot.lds
@@ -26,6 +26,11 @@ SECTIONS
_loadaddress = UNCACHED_DRAM_ADDR;
loadaddressend = UNCACHED_DRAM_ADDR + RAM_HOLE;
_loadaddressend = UNCACHED_DRAM_ADDR + RAM_HOLE;
+
+ .dramcopystart (NOLOAD) :
+ {
+ _dramcopystart = .;
+ } > DRAM
.text :
{
@@ -48,6 +53,11 @@ SECTIONS
_iramcopy = LOADADDR(.itext);
+ .dramcopyend (NOLOAD) :
+ {
+ _dramcopyend = .;
+ } > DRAM
+
.ibss (NOLOAD) :
{
_iedata = .;
diff --git a/firmware/target/arm/imx233/crt0.S b/firmware/target/arm/imx233/crt0.S
index 393411b83a..abbff5816a 100644
--- a/firmware/target/arm/imx233/crt0.S
+++ b/firmware/target/arm/imx233/crt0.S
@@ -33,15 +33,22 @@
ldr pc, =irq_handler
ldr pc, =fiq_handler
-/* When starting, we are running at 0x4xxxxxxx (uncached) but the code
- * assumes DRAM is somewhere else (cached) so we first need to
- * setup the MMU and then jump to the right location. */
+/* When starting, we will be running at 0x40000000 most probably
+ * but the code is expected to be loaded at 0x4xxxxxxx (uncached) and to be
+ * running at virtual address 0xyyyyyyyy (cached). So we first
+ * need to move everything to the right locationn then we setup the mmu and
+ * jump to the final virtual address. */
.text
.global start
+ /** The code below must be able to run at any address **/
start:
+ /* Copy running address */
+ sub r7, pc, #8
/* Save r0 */
mov r6, r0
- msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */
+
+ /* enter supervisor mode, disable IRQ/FIQ */
+ msr cpsr_c, #0xd3
/* Disable MMU, disable caching and buffering;
* use low exception range address (the core uses high range by default) */
mrc p15, 0, r0, c1, c0, 0
@@ -55,10 +62,25 @@ start:
/* Enable MMU */
bl memory_init
+
+ /* Copy the DRAM
+ * Assume the dram binary blob is located at the loading address (r5) */
+ mov r2, r7
+ ldr r3, =_dramcopystart
+ ldr r4, =_dramcopyend
+1:
+ cmp r4, r3
+ ldrhi r5, [r2], #4
+ strhi r5, [r3], #4
+ bhi 1b
+
+ mov r2, #0
+ mcr p15, 0, r2, c7, c5, 0 @ Invalidate ICache
+
/* Jump to real location */
ldr pc, =remap
remap:
-
+ /** The code below is be running at the right virtual address **/
/* Zero out IBSS */
ldr r2, =_iedata
ldr r3, =_iend
@@ -132,6 +154,7 @@ remap:
/* Jump to main */
mov r0, r6
+ mov r1, r7
bl main
1:
b 1b