Teach the kernel and the ELF trampoline how to boot from onboard flash.
This commit is contained in:
parent
0d9fc1e6e1
commit
db599c2f20
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=166819
@ -103,7 +103,7 @@ memcpy(void *dst, const void *src, int len)
|
|||||||
char *d = dst;
|
char *d = dst;
|
||||||
|
|
||||||
while (len) {
|
while (len) {
|
||||||
if (len >= 4 && !((vm_offset_t)d & 3) &&
|
if (0 && len >= 4 && !((vm_offset_t)d & 3) &&
|
||||||
!((vm_offset_t)s & 3)) {
|
!((vm_offset_t)s & 3)) {
|
||||||
*(uint32_t *)d = *(uint32_t *)s;
|
*(uint32_t *)d = *(uint32_t *)s;
|
||||||
s += 4;
|
s += 4;
|
||||||
@ -143,6 +143,37 @@ _start(void)
|
|||||||
int physaddr = KERNPHYSADDR;
|
int physaddr = KERNPHYSADDR;
|
||||||
int tmp1;
|
int tmp1;
|
||||||
unsigned int sp = ((unsigned int)&_end & ~3) + 4;
|
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
|
#ifdef KZIP
|
||||||
sp += KERNSIZE + 0x100;
|
sp += KERNSIZE + 0x100;
|
||||||
sp &= ~(L1_TABLE_SIZE - 1);
|
sp &= ~(L1_TABLE_SIZE - 1);
|
||||||
|
@ -66,47 +66,53 @@ __FBSDID("$FreeBSD$");
|
|||||||
ENTRY_NP(btext)
|
ENTRY_NP(btext)
|
||||||
|
|
||||||
ASENTRY_NP(_start)
|
ASENTRY_NP(_start)
|
||||||
|
#if defined (FLASHADDR) && defined(LOADERRAMADDR)
|
||||||
|
/* Check if we're running from flash. */
|
||||||
/* Check if we are running on RAM, if not move ourself to RAM */
|
ldr r7, =FLASHADDR
|
||||||
#if 0
|
/*
|
||||||
cmp pc, #PHYSADDR
|
* If we're running with MMU disabled, test against the
|
||||||
bhi start_inram /* XXX: This is wrong */
|
* physical address instead.
|
||||||
#endif
|
|
||||||
b start_inram /*
|
|
||||||
* XXX: this is even more wrong, but RedBoot
|
|
||||||
* use 0x00000000-0x100000000 as virtual
|
|
||||||
* addresses for the RAM.
|
|
||||||
*/
|
*/
|
||||||
|
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
|
||||||
|
|
||||||
/* move me to RAM
|
flash_lower:
|
||||||
* XXX: we can use memcpy if it is PIC
|
cmp r8, pc
|
||||||
*/
|
bls from_ram
|
||||||
ldr r1, Lcopy_size
|
do_copy:
|
||||||
adr r0, _C_LABEL(_start)
|
ldr r9, =KERNBASE
|
||||||
add r1, r1, #3
|
adr r1, _start
|
||||||
mov r1, r1, LSR #2
|
ldr r0, Lreal_start
|
||||||
mov r2, #PHYSADDR
|
ldr r2, Lend
|
||||||
add r2, r2, #0x00200000
|
sub r2, r2, r0
|
||||||
mov r4, r2
|
sub r0, r0, r9
|
||||||
|
add r0, r0, r8
|
||||||
5: ldr r3,[r0],#4
|
mov r4, r0
|
||||||
str r3,[r2],#4
|
/* Make sure _arm_memcpy is NULL */
|
||||||
subs r1,r1,#1
|
ldr r3, .L_arm_memcpy
|
||||||
bhi 5b
|
ldr r3, [r3]
|
||||||
|
mov r5, #0
|
||||||
/* Jump to RAM */
|
str r5, [r3]
|
||||||
ldr r0, Lstart_off
|
bl memcpy
|
||||||
|
ldr r0, Lram_offset
|
||||||
add pc, r4, r0
|
add pc, r4, r0
|
||||||
|
Lram_offset: .word from_ram-_C_LABEL(_start)
|
||||||
Lcopy_size: .word _edata-_C_LABEL(_start)
|
from_ram:
|
||||||
Lstart_off: .word start_inram-_C_LABEL(_start)
|
nop
|
||||||
start_inram:
|
#endif
|
||||||
adr r7, Lunmapped
|
adr r7, Lunmapped
|
||||||
bic r7, r7, #0xff000000
|
bic r7, r7, #0xff000000
|
||||||
orr r7, r7, #PHYSADDR
|
orr r7, r7, #PHYSADDR
|
||||||
|
|
||||||
|
|
||||||
|
disable_mmu:
|
||||||
/* Disable MMU for a while */
|
/* Disable MMU for a while */
|
||||||
mrc p15, 0, r2, c1, c0, 0
|
mrc p15, 0, r2, c1, c0, 0
|
||||||
bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\
|
bic r2, r2, #(CPU_CONTROL_MMU_ENABLE | CPU_CONTROL_DC_ENABLE |\
|
||||||
@ -120,7 +126,6 @@ start_inram:
|
|||||||
nop
|
nop
|
||||||
mov pc, r7
|
mov pc, r7
|
||||||
Lunmapped:
|
Lunmapped:
|
||||||
|
|
||||||
#ifdef STARTUP_PAGETABLE_ADDR
|
#ifdef STARTUP_PAGETABLE_ADDR
|
||||||
/* build page table from scratch */
|
/* build page table from scratch */
|
||||||
ldr r0, Lstartup_pagetable
|
ldr r0, Lstartup_pagetable
|
||||||
@ -191,6 +196,10 @@ Lvirtaddr:
|
|||||||
.word KERNVIRTADDR
|
.word KERNVIRTADDR
|
||||||
Lphysaddr:
|
Lphysaddr:
|
||||||
.word KERNPHYSADDR
|
.word KERNPHYSADDR
|
||||||
|
Lreal_start:
|
||||||
|
.word _start
|
||||||
|
Lend:
|
||||||
|
.word _edata
|
||||||
Lstartup_pagetable:
|
Lstartup_pagetable:
|
||||||
.word STARTUP_PAGETABLE_ADDR
|
.word STARTUP_PAGETABLE_ADDR
|
||||||
mmu_init_table:
|
mmu_init_table:
|
||||||
@ -207,6 +216,11 @@ mmu_init_table:
|
|||||||
.word _end
|
.word _end
|
||||||
.word svcstk + INIT_ARM_STACK_SIZE
|
.word svcstk + INIT_ARM_STACK_SIZE
|
||||||
|
|
||||||
|
#if defined(FLASHADDR) && defined(LOADERRAMADDR)
|
||||||
|
.L_arm_memcpy:
|
||||||
|
.word _C_LABEL(_arm_memcpy)
|
||||||
|
#endif
|
||||||
|
|
||||||
.Lvirt_done:
|
.Lvirt_done:
|
||||||
.word virt_done
|
.word virt_done
|
||||||
.Lmainreturned:
|
.Lmainreturned:
|
||||||
|
Loading…
Reference in New Issue
Block a user