커널코드분석 20140628(head.s dtb check_done, wont_overwrite)2. !!! 분석 전에 잠깐 !!!
dtb_check_done 을 시작하는 시점에서 주요 register 의 상태는 다음과
같다 .
* r4 = final kernel address (possibly with LSB set)
* r9 = size of decompressed image
* r10 = end of this image, including bss/stack/malloc space if
non XIP
malloc
stack
bss
zImage
!!! Overwrite 과 Wont_Overwrite 여부를 판단하기 위한 4 가지 경우의 수
(2), (4) 번은 Overwrite 가 발생하므로 이미지 재배치 필요 .
Page Table (16k)
r10
Uncompressed
Image
r4
Page Table (16k)
Uncompressed
Image
r4
malloc
stack
bss
zImage
r10
Page Table (16k)
r10
Uncompressed
Image
r4
r9
wont_overwrite
r4 – 16k >= r10
OK
wont_overwrite 분기
r4 – 16k < r10
Overwrite
Relocation 필요
r4 + r9 <= r10
OK
wont_overwrite 분기
r10 wont_overwrite
Page Table (16k)
Uncompressed
Image
r4
r9
r4 + r9 > r10
Overwrite
Relocation 필요
(1
)
(2
)
(3
)
(4
)
3. !!! (2) 번과 (4) 번의 경우 Overwrite 을 회피하기 위해 이미지의 재배치 목적지를
어디로 해야할까 ? 개념적으로 보면 아래와 같다 .
Page Table (16k)
Uncompressed
Image
malloc
stack
bss
zImage
r10
(2
)
malloc
stack
bss
zImage
원래의 이미지를 Uncompressed
Image 의 End 위로 배치해야 한다
.
r10 wont_overwrite
Page Table (16k)
Uncompressed
Image
r4
(4
)
r4
malloc
stack
bss
zImage
재배치 시 현재의 Code 를
Overwrite 하지 않도록 마찬가지로
Uncompressed Image End 위로 배
치해야 한다 .
위와 같이 재배치를 수행한 후 PC 를 재배치한 이미지의 restart label 로 설정하여 , 다
시 restart 부터 수행하게 된다는 것이 restart, dtb_check_done, wont_overwrite label
들의 역할이다 .
5. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
Current Image 가 Page
Table 및 Uncompressed
Image 와 Overwrite 되는지
검사 .
Page Table (16k)
Uncompressed
Image
Current Image
(zImage ~ dtb end)
r10
r4
r9
6. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
Overwrite 되지 않으면 wont_overwrite
로 분기 (1) 번 경우
Page Table (16k)
Uncompressed
Image
Current Image
(zImage ~ dtb end)
r10
r4
r9
7. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
Current Image 가 Page
Table 및 Uncompressed
Image 와 Overwrite 됨 .
r10 Pointer 변경 .
Page Table (16k)
Uncompressed
Image
Current Image
(zImage ~ dtb end)
r10
r4
r9
wont_overwrite
8. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
r9 Pointer 변경 .
Page Table (16k)
Uncompressed
Image
Current Image
(zImage ~ dtb end)
r10
r4
r9wont_overwrite
9. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
wont_overwrite 이 Uncompressed Image
End 위에 있는지 검사
(3) 번 경우인지 (4) 번 경우인지 검사
Page Table (16k)
Uncompressed
Image
Current Image
(zImage ~ dtb end)
r10
r4
r9wont_overwrite
10. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
(3) 번 경우 분기
Decompressed Image End 가 Current Image 의 wont_overwrite 를
Overwrite 하지 않음 .
Page Table (16k)
Current Image
(zImage ~ dtb end)
r10
r4
r9wont_overwrite
Uncompressed
Image
11. 이제 재배치가 필요한 (2) 번과 (4) 번 , 즉 Overwrite 되는 경우라서
wont_overwrite 로 분기하지 않았던 Case 만 남았다 . !!!
12. Page Table (16k)
Uncompressed
Image
malloc
stack
bss
zImage
(2
)
그런데 , (2) 번과 (4) 번이 다른 Case 인가 ?
그렇지 않다 .
wont_overwrite
Page Table (16k)
Uncompressed
Image
(4
)
그냥 Current Image 가 조금 위에 있거나 아래에 있는게 다를 뿐이다 .
(2) 번은 아래쪽에 있어서 Page Table 및 Uncompressed Image 와
Overwrite 될 가능성이 있는 경우이고 , (4) 는 그보다 좀더 위쪽에 있
어서 Uncompress 시 Current Image 를 Overwrite 할 가능성이 있는
경우이다 .
13. 그렇다면 , 이를 어쩌나 ?
Current Image 의 위치를 재배치하고 다시 수행해야겠지 .
어느 위치로 ?
재배치 후의 restart 가 최소한 Decompressed Image 위에 오도록
Page Table (16k)
Uncompressed
Image
(2
)
restart
Page Table (16k)
Uncompressed
Image
restart
Page Table (16k)
Uncompressed
Image
Page Table (16k)
Uncompressed
Image
restart
(4
)
wont_overwrite
14. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
Overwrite 가 발생하는 경우임 . (2), (4)
Page Table (16k)
Current Image
(zImage ~ dtb end)
r10
r4
r9wont_overwrite
Uncompressed
Image
r10 의 위치 변경 (256 byte align)
재배치를 앞두고 이 만큼을 추가로 확보하는 이유는 ?
reloc_code_end
r10
restart
왜 하필 256 byte align 일까 ? 확인 필
요
restart ~ reloc_code_end
15. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
Overwrite 가 발생하는 경우임 . (2), (4)
Page Table (16k)
Current Image
(zImage ~ dtb end)
r4
r9wont_overwrite
Uncompressed
Image
r5 = restart 주소 (32 byte align)
reloc_code_end
r10
restartr5
restart ~ reloc_code_end
16. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
Overwrite 가 발생하는 경우임 . (2), (4)
Page Table (16k)
Current Image
(zImage ~ dtb end)
r4
r9wont_overwrite
Uncompressed
Image
Hyper mode 가 아니면 1f 분기
reloc_code_end
r10
restartr5
restart ~ reloc_code_end
17. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
Overwrite 가 발생하는 경우임 . (2), (4)
Page Table (16k)
Current Image
(zImage ~ dtb end)
r4
r9
wont_overwrite
Uncompressed
Image
restart ~ dtb end 차이 값을 32 byte
align r9
reloc_code_end
r10
restartr5
r6
restart ~ reloc_code_end
18. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
Overwrite 가 발생하는 경우임 . (2), (4)
Page Table (16k)
Current Image
(zImage ~ dtb end)
r4
r9
wont_overwrite
Uncompressed
Image
32 byte align 된 r5 와 r9 을 더하여 r6 위치 32
byte align 위치로 살짝 조정
이건 재배치의 Source 자리임 .
reloc_code_end
r10
restartr5
r6
restart ~ reloc_code_end
19. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
Overwrite 가 발생하는 경우임 . (2), (4)
Page Table (16k)
Current Image
(zImage ~ dtb end)
r4
r9
wont_overwrite
Uncompressed
Image
r9 위치 설정 r9 의 위치는 재배치의 Destination
위치임 .
reloc_code_end
r10
restartr5
r6
r9
restart ~ dtb end
restart ~ reloc_code_end
20. dtb_check_done:
add r10, r10, #16384
cmp r4, r10
bhs wont_overwrite
add r10, r4, r9
adr r9, wont_overwrite
cmp r10, r9
bls wont_overwrite
add r10, r10, #((reloc_code_end - restart
+ 256) & ~255)
bic r10, r10, #255
adr r5, restart
bic r5, r5, #31
#ifdef CONFIG_ARM_VIRT_EXT
mrs r0, spsr
and r0, r0, #MODE_MASK
cmp r0, #HYP_MODE
bne 1f
bl __hyp_get_vectors
sub r0, r0, r5
add r0, r0, r10
bl __hyp_set_vectors
1:
#endif
sub r9, r6, r5
add r9, r9, #31
bic r9, r9, #31
add r6, r9, r5
add r9, r9, r10
1: ldmdb r6!, {r0 - r3, r10 - r12, lr}
cmp r6, r5
stmdb r9!, {r0 - r3, r10 - r12, lr}
bhi 1b
Overwrite 가 발생하는 경우임 . (2), (4)
Page Table (16k)
r4
r9
Uncompressed
Image
r6 ~ restart 까지를 모두 r9 위치로 decremental 로
복사함 .
r10
restartr5
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
21. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
restartr5
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
r6 = 신규 dtb end 위치 (r9) 과 기존 dtb end (r6) 와의
offset
즉 , r6 는 재배치로 인해 이동한 Offset
r6
22. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
restartr5
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
기존의 sp 위치도 재배치 후의 위치로 변경시켜줌 .
r6
sp
23. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
restartr5
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
cache_on 을 skip 했을 경우 r4 의 LSB 가 1 로 설정되어
있다 .
cache_on 을 했다고 가정하면 flush 해야 함 .
r6
sp
24. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
restartr5
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
r0 값을 현재의 restart label 에서 재배치한 위치의 restart 값
으로 설정
r6
sp
r0
25. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
pc 값을 재배치한 restart 로 설정하여 restart 부터 다시 수행 .
다시 수행하게 되면 그 때부터는 Overwrite 가 발생하지 않는 (3)
번
Case 로 수행하게 되어 중간에 wont_overwrite 로 분기하게 된다 .
r6
sp
r0pc
26. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
재배치를 거쳤건 안거쳤건 restart 에서 분기해온 상태에서
r0 = delta offset (LC0 label 과 LC0 word 값 차이 )
r5 = dtb size
r6
sp
r0pc
27. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
(1) r0 = 0 | r5 = 0 -> 0 -> not reloc
(2) r0 = 1 | r5 = 0 -> 1 -> reloc
(3) r0 = 0 | r5 = 1 -> 1 -> reloc
(4) r0 = 1 | r5 = 1 -> 1 -> reloc
(1)의 경우는 확실히 재배치가 발생하지 않은 경우이다 .
재배치가 발생해서 restart 쪽을 다시 거쳤다면 delta offset 이 0 일
수가 없다 .
r6
sp
r0pc
28. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
GOT start (r11) 와 GOT end (r12) 의 위치도 재배치를 고려하여 delta
offset (r0) 만큼 이동시켜준다 .
r6
sp
r0pc
29. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
BSS start (r2) 와 BSS end (r3) 의 위치도 재배치를 고려하여 delta
offset (r0) 만큼 이동시켜준다 .
r6
sp
r0pc
30. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
GOT 의 첫번째 entry 값을 가져와서 delta offset 을 더해준다 .
r6
sp
r0pc
31. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
Delta offset 조정된 GOT Entry 값이 bss start ~ bss end 사이의 값이
면
r6
sp
r0pc
32. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
Entry 값에 dtb size 값을 더해준다 .
r6
sp
r0pc
33. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
다음 GOT Entry 에 대해 동일한 작업을 하기 위해 1b 로 이동한다 .
GOT end 를 만나면 Loop 를 끝낸다 .
결국 이는 GOT 의 모든 Entry 값들을 delta offset 과 dtb size 를 고
려하여 조정하는 것이다 . ( 재배치가 발생했을 수도 있으므로 )
r6
sp
r0pc
그런데 , 왜 GOT Entry 의 값이 bss start ~ end 내에 포함되는지를 검사하는 것일까
?
34. sub r6, r9, r6
#ifndef CONFIG_ZBOOT_ROM
add sp, sp, r6
#endif
tst r4, #1
bleq cache_clean_flush
adr r0, BSYM(restart)
add r0, r0, r6
mov pc, r0
wont_overwrite:
orrs r1, r0, r5
beq not_relocated
add r11, r11, r0
add r12, r12, r0
#ifndef CONFIG_ZBOOT_ROM
add r2, r2, r0
add r3, r3, r0
1: ldr r1, [r11, #0]
add r1, r1, r0
cmp r1, r2
cmphs r3, r1
addhi r1, r1, r5
str r1, [r11], #4
cmp r11, r12
blo 1b
add r2, r2, r5
add r3, r3, r5
#else
…
#endif
Page Table (16k)
r4
r9
Uncompressed
Image
r10
r6
restart ~ dtb end
restart ~ reloc_code_end
Current Image
(zImage ~ dtb end)
restart
bss start 와 bss end 의 값도 dtb size 를 더한 값으로 조정해준다 .
( 위쪽에서 delta offset 값은 이미 더해주었다 .)
r6
sp
r0pc
35. stack
bss
wont_overwrite 을 마친 후의 memory map 및 register 상태
재배치가 완료되었을 수도 있고 재배치가 불필요했을 수도 있다 .
Page Table (16k)
Uncompressed
Image
r10 r6 :
재배치했다면 이전 dtb end
를 가리키고 , 재배치 안했다
면 현재의 dtb _end 를 가리
킴 .
r4
r9
r0 : delta offset
r1 : temp
dtb
bss start
재배치한 대상
r7 : architecture ID
r8 :
dtb 가 있다면 dtb start 를
가리키고 , 없다면 atags
pointer 임 .
restart
r5 : dtb size
LC0
GOT start
GOT end
bss end
r2
r3
GOT 의 각 Entry 는 bss 영
역을 가리킴
sp
r11
r12
zImage