* This \ * after relocating the monitor code. * * r3 = dest * r4 = src
* r5 = length in bytes * r6 = cachelinesize */
.globl
relocate_code
relocate_code: mr r1, r3 /* Set new stack pointer :r1=r3*/
mr r9, r4 /* Save copy of Global Data pointer r9=r4*/ mr r10, r5
/* Save copy of Destination Address r10=r5*/
mr r3, r5 /* Destination Address r3=r5*/
lis r4, CONFIG_SYS_MONITOR_BASE@h
/* Source Address */
ori r4, r4, CONFIG_SYS_MONITOR_BASE@l //r4=0xfe00_0000 lwz r5, GOT(__bss_start)
sub r5, r5, r4 //r5=r5-r4=r5-0xfe00_0000; li
r6, CONFIG_SYS_CACHELINE_SIZE
/* Cache Line Size */
/*
* Fix GOT pointer:
*
41
* New GOT-PTR = (old GOT-PTR - CONFIG_SYS_MONITOR_BASE) * + Destination Address
* * Offset: */
sub r15, r10, r4 //r15=r10-0xfe00_0000=r5-0xfe00_0000
/* First our own GOT */
add r14, r14, r15 // r14=r14+ r5-0xfe00_0000 /* then the one used by the C code */
add r30, r30, r15 //r30=r30+ r5-0xfe00_0000
/*
* Now relocate code */
cmplw cr1,r3,r4
addi r0,r5,3 srwi. r0,r0,2 beq cr1,4f
/* In place copy is not necessary */
beq 7f /* Protect against 0 count
*/
mtctr
r0
bge cr1,2f la
r8,-4(r4)
42
la r7,-4(r3)
/* copy */
1: lwzu r0,4(r8) stwu r0,4(r7) bdnz 1b
addi r0,r5,3 srwi. r0,r0,2 mtctr r0
la r8,-4(r4) la
r7,-4(r3)
/* and compare */ 20: lwzu r20,4(r8) lwzu r21,4(r7) xor. r22, r20, r21 bne 30f bdnz 20b b 4f
/* compare failed */ 30: li r3, 0
blr
43
2: slwi r0,r0,2 /* re copy in reverse order ... y do we needed it? */ add r8,r4,r0
add r7,r3,r0
3: lwzu r0,-4(r8) stwu r0,-4(r7) bdnz 3b
/*
* Now flush the cache: note that we must start from a cache aligned * address. Otherwise we might miss one cache line. */ 4: cmpwi r6,0
add r5,r3,r5 beq 7f /* Always flush prefetch queue in any case */
subi r0,r6,1 andc r3,r3,r0
mr r4,r3
5: dcbst 0,r4
add r4,r4,r6 cmplw r4,r5
blt 5b sync
/* Wait for all dcbst to complete on bus */
mr r4,r3
44
6: icbi 0,r4
add r4,r4,r6 cmplw blt 6b
/* Wait for all icbi to complete on bus */ r4,r5
7: sync /*
isync
* We are done. Do not return, instead branch to second part of board * initialization, now running from RAM. */
addi r0, r10, in_ram - _start + EXC_OFF_SYS_RESET mtlr r0 blr
关于这段复制代码后面有时间再仔细分析,现在跳到in_ram标号处执行。这个将其作为第二阶段去分析。 4.2 启动第二阶段 3.2.1 in_ram in_ram:
/*
* Relocation Function, r14 point to got2+0x8000 *
* Adjust got2 pointers, no need to check for 0, this code
45