Teach the kernel and the ELF trampoline how to boot from onboard flash.

This commit is contained in:
Olivier Houchard 2007-02-19 00:57:27 +00:00
parent 0d9fc1e6e1
commit db599c2f20
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=166819
2 changed files with 82 additions and 37 deletions

View File

@ -103,7 +103,7 @@ memcpy(void *dst, const void *src, int len)
char *d = dst;
while (len) {
if (len >= 4 && !((vm_offset_t)d & 3) &&
if (0 && len >= 4 && !((vm_offset_t)d & 3) &&
!((vm_offset_t)s & 3)) {
*(uint32_t *)d = *(uint32_t *)s;
s += 4;
@ -143,6 +143,37 @@ _start(void)
int physaddr = KERNPHYSADDR;
int tmp1;
unsigned int sp = ((unsigned int)&_end & ~3) + 4;
#if defined(FLASHADDR) && defined(LOADERRAMADDR)
unsigned int pc;
__asm __volatile("adr %0, _start\n"
: "=r" (pc));
if ((FLASHADDR > LOADERRAMADDR && pc >= FLASHADDR) ||
(FLASHADDR < LOADERRAMADDR && pc < LOADERRAMADDR)) {
/*
* We're running from flash, so just copy the whole thing
* from flash to memory.
* This is far from optimal, we could do the relocation or
* the unzipping directly from flash to memory to avoid this
* needless copy, but it would require to know the flash
* physical address.
*/
unsigned int target_addr;
unsigned int tmp_sp;
target_addr = (unsigned int)&_start - PHYSADDR + LOADERRAMADDR;
tmp_sp = target_addr + 0x100000 +
(unsigned int)&_end - (unsigned int)&_start;
memcpy((char *)target_addr, (char *)pc,
(unsigned int)&_end - (unsigned int)&_start);
/* Temporary set the sp and jump to the new location. */
__asm __volatile(
"mov sp, %1\n"
"mov pc, %0\n"
: : "r" (target_addr), "r" (tmp_sp));
}
#endif
#ifdef KZIP
sp += KERNSIZE + 0x100;
sp &= ~(L1_TABLE_SIZE - 1);

View File

@ -66,47 +66,53 @@ __FBSDID("$FreeBSD$");
ENTRY_NP(btext)
ASENTRY_NP(_start)
/* Check if we are running on RAM, if not move ourself to RAM */
#if 0
cmp pc, #PHYSADDR
bhi start_inram /* XXX: This is wrong */
#endif
b start_inram /*
* XXX: this is even more wrong, but RedBoot
* use 0x00000000-0x100000000 as virtual
* addresses for the RAM.
*/
/* move me to RAM
* XXX: we can use memcpy if it is PIC
#if defined (FLASHADDR) && defined(LOADERRAMADDR)
/* Check if we're running from flash. */
ldr r7, =FLASHADDR
/*
* If we're running with MMU disabled, test against the
* physical address instead.
*/
ldr r1, Lcopy_size
adr r0, _C_LABEL(_start)
add r1, r1, #3
mov r1, r1, LSR #2
mov r2, #PHYSADDR
add r2, r2, #0x00200000
mov r4, r2
5: ldr r3,[r0],#4
str r3,[r2],#4
subs r1,r1,#1
bhi 5b
/* Jump to RAM */
ldr r0, Lstart_off
add pc, r4, r0
Lcopy_size: .word _edata-_C_LABEL(_start)
Lstart_off: .word start_inram-_C_LABEL(_start)
start_inram:
mrc p15, 0, r2, c1, c0, 0
ands r2, r2, #CPU_CONTROL_MMU_ENABLE
ldreq r8, =PHYSADDR
ldrne r8, =LOADERRAMADDR
cmp r7, r8
bls flash_lower
cmp r7, pc
bhi from_ram
b do_copy
flash_lower:
cmp r8, pc
bls from_ram
do_copy:
ldr r9, =KERNBASE
adr r1, _start
ldr r0, Lreal_start
ldr r2, Lend
sub r2, r2, r0
sub r0, r0, r9
add r0, r0, r8
mov r4, r0
/* Make sure _arm_memcpy is NULL */
ldr r3, .L_arm_memcpy
ldr r3, [r3]
mov r5, #0
str r5, [r3]
bl memcpy
ldr r0, Lram_offset
add pc, r4, r0
Lram_offset: .word from_ram-_C_LABEL(_start)
from_ram:
nop
#endif
adr r7, Lunmapped
bic r7, r7, #0xff000000
orr r7, r7, #PHYSADDR
disable_mmu:
/* Disable MMU for a while */
mrc p15, 0, r2, c1, c0, 0
bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\
@ -120,7 +126,6 @@ start_inram:
nop
mov pc, r7
Lunmapped:
#ifdef STARTUP_PAGETABLE_ADDR
/* build page table from scratch */
ldr r0, Lstartup_pagetable
@ -191,6 +196,10 @@ Lvirtaddr:
.word KERNVIRTADDR
Lphysaddr:
.word KERNPHYSADDR
Lreal_start:
.word _start
Lend:
.word _edata
Lstartup_pagetable:
.word STARTUP_PAGETABLE_ADDR
mmu_init_table:
@ -207,6 +216,11 @@ mmu_init_table:
.word _end
.word svcstk + INIT_ARM_STACK_SIZE
#if defined(FLASHADDR) && defined(LOADERRAMADDR)
.L_arm_memcpy:
.word _C_LABEL(_arm_memcpy)
#endif
.Lvirt_done:
.word virt_done
.Lmainreturned: