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
diff --git a/bootloader/imx233.c b/bootloader/imx233.c
index 86edc24..41dd3e9 100644
--- a/bootloader/imx233.c
+++ b/bootloader/imx233.c
@@ -101,8 +101,8 @@
}
#endif /* HAVE_BOOTLOADER_USB_MODE */
-void main(uint32_t arg) NORETURN_ATTR;
-void main(uint32_t arg)
+void main(uint32_t arg, uint32_t addr) NORETURN_ATTR;
+void main(uint32_t arg, uint32_t addr)
{
unsigned char* loadbuffer;
int buffer_size;
@@ -124,7 +124,7 @@
button_init();
//button_debug_screen();
- printf("arg=%x", arg);
+ printf("arg=%x addr=%x", arg, addr);
#ifdef SANSA_FUZEPLUS
extern void imx233_mmc_disable_window(void);
diff --git a/firmware/target/arm/imx233/app.lds b/firmware/target/arm/imx233/app.lds
index a961222..0eeecc1 100644
--- a/firmware/target/arm/imx233/app.lds
+++ b/firmware/target/arm/imx233/app.lds
@@ -34,6 +34,11 @@
{
loadaddress = UNCACHED_DRAM_ADDR;
_loadaddress = UNCACHED_DRAM_ADDR;
+
+ .dramcopystart (NOLOAD) :
+ {
+ _dramcopystart = .;
+ } > DRAM
.text :
{
@@ -76,6 +81,11 @@
_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 206e0bb..d909b9f 100644
--- a/firmware/target/arm/imx233/boot.lds
+++ b/firmware/target/arm/imx233/boot.lds
@@ -26,6 +26,11 @@
_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 @@
_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 393411b..abbff58 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 @@
/* 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 @@
/* Jump to main */
mov r0, r6
+ mov r1, r7
bl main
1:
b 1b