shepherd's Blog

[ARM 11차 B조] 14.05.31 스터디 후기 본문

카테고리 없음

[ARM 11차 B조] 14.05.31 스터디 후기

shepherd.dev 2015. 7. 7. 15:58

2014년 5월 31일 7주차 스터디 후기

 

1. Study history

 - 5월 31일(7주차) 12:00 ~ 6:00 성수 서울앱창업센터에서 진행, 14명 참석

 - arch/arm/boot/compressed/head.S 진행 중

 - 6월 7일(8주차) 스터디 휴식

 

2. 이슈사항

 추가적인 이슈사항이나 고쳐야 할 부분 있을경우 댓글로 달아주세요. 수정해서 올리겠습니다.


 -1. 재배치 관련 이슈사항

 모기향책과 기타 참고자료들로 정리해봤습니다. 댓글로 태클점 주세요.

 

mov r4, pc                                                                                                                                                                 

 and r4, r4, #0xf8000000

 add r4, r4, #TEXT_OFFSET

 /* Set up a page table only if it won't overwrite ourself.

   * That means r4 < pc && r4 - 16k page directory > &_end.

   * Given that r4 > &_end is most unfrequent, we add a rough

   * additional 1MB of room for a possible appended DTB(device tree binary).

   */ 

 mov r0, pc

 cmp r0, r4

 @if r0 < r4 {

 ldrcc   r0, LC0+32      @ r0 < r4 일 때 LC0+32 = _end - restart + 16K(page_table) + 1M(DTB)

 addcc   r0, r0, pc

 cmpcc   r4, r0

 @ if r4 < r0 

 orrcc   r4, r4, #1      @ remember we skipped cache_on 

 }

 @ if r4 >= r0

 blcs    cache_on

 

 위의 값에서 압축해제된 커널을 올릴 주소를 r4에 넣어줍니다. 해당 주소와 현재 pc와 비교해서 재배치의 수행

여부를 결정하게 됩니다. 여기서 재배치가 결정되면 cache_on을 나중으로 미루게 됩니다.

 

참고1http://www.iamroot.org/xe/Kernel_10_ARM/186592#comment_186806

참고2http://www.iamroot.org/xe/index.php?mid=Kernel_10_ARM&document_srl=180812#comment_181518

 
질문1여기서 cmp r0, r4를 한번 살펴보겠습니다. 위의 부등호대로라면 pc의 값이 커널의 위치보다 작다면 재배치를
해주게 되는데 모기향책을 살펴볼 경우 zImage의 위치는 해당 위치보다 한참 위쪽인 0x--C0_0000에 위치합니다.
대충 그림은 다음과 같이 예상합니다.

+---------------------+

|                      |

|zImage            | <- 재배치 검사할 때의 pc(r0)

+---------------------+--0x--C0_0000

|빈공간?            |

+---------------------+--0x--00_----

|압축풀린 커널이|

|올라갈 공간     |

+---------------------+--0x--00_8000 <- r4(압축해제된 커널의 위치)

|TEXT_OFFSET  | -page_directory(16k)

|                      |

+---------------------+

 그럼 pc값이 커널의 위치보다 작아질 일이 없을것 같은데 왜 해당 코드를 넣었는지 이해가 안갑니다. 부트로더에서 실수로 _TEXT_BASE를 잘못 대입했을 때를 대비해서 넣어둔 코드인가요? 주석내용을 보면 pagetable과 관련된 이슈로 넣어둔것 같은데 잘 모르겠내요. 

 

 

 -2. 재배치 이 후 LC0 위치 조절

 위의 재배치 문제가 발생할 경우 재배치 이 후 restart를 한번 더 실행하게 된다. 재배치를 수행했다면  _edata(bss시작 주소)와 압축 풀린 커널 사이즈가 있는 주소(r10)의 위치를 조절해주게 된다.

 

 adr r0, LC0   

 ldmia   r0, {r1, r2, r3, r6, r10, r11, r12}

 ldr sp, [r0, #28]

 sub r0, r0, r1      @ calculate the delta offset

 add r6, r6, r0      @ _edata

 add r10, r10, r0  @ inflated kernel size location

 

 -3. 리틀-엔디안 방식으로 인한 로드 방법

 해당 코드에서 로드하는 r10은 LC0에서 받아온 값으로 압축 풀린 커널의 크기가 들어있는 메모리의 주소이다. 해당 사이즈를 받아와서 나중에 어딘가에 쓰기 위해 저장을 해두는 것 같은데, 리틀 엔디안의 경우 메모리에서 레지스터로 값을 로드할 경우 상위 주소와 하위 주소가 다른 문제가 생긴다.

 예를 들어 커널 사이즈 0x12345678가 리틀 엔디안 방식에서 메모리에 저장된다면 0x78563412로 저장됩니다. 이 상태에서 빅엔디안에서 해당 메모리에 있는 값을 r9로 불러온다면, 0x78563412 그대로 불러와지게 되기 때문에 아래와 같은 루틴으로 원하는 값을 레지스터에 적재한다.

 참고 홈페이지를 보시면 더 자세한 설명이 있습니다. ㅎ

                          

  ldrb    r9, [r10, #0]        @ r9 = 0x00000078

  ldrb    lr, [r10, #1]         @ lr = 0x00000056
  orr     r9, r9, lr, lsl #8     @ r9 = 0x00005678
  ldrb    lr, [r10, #2]         @ lr = 0x00000034
  ldrb    r10, [r10, #3]      @ r10 = 0x00000012
  orr     r9, r9, lr, lsl #16    @ r9 = 0x00345678
  orr     r9, r9, r10, lsl #24 @ r9 = 0x12345678


참고http://www.iamroot.org/xe/Kernel_8_ARM/60066#comment_60161

 

3. 참고 + 질문

혹시 참고가 될까 해서 올려드립니다. 추가적인 참고자료 및 의문점도 댓글로 부탁드립니다.

 

-1. arch/arm/boot/compressed/vmware 덤프로 알아본 LC0

공부하다가 LC0에 저장된 값들 _end, _edata같은녀석들이 먼가 싶어서 이것 저것 찾아본 결과입니다. 맞는지 잘 모르겠어서 검증차 올려둡니다. 그리고 질문도 더해서요. ㅎ

 

 #arm-linux-eabi-objdump arch/arm/boot/compressed/vmware                                                                                            

...

000002d8 <LC0>:

       2d8:   000002d8 002a3638 002a3660 002a3638    ....86*.`6*.86*.

       2e8:   002a35e9 002a35fc 002a3630 002a4660    .5*..5*.06*.`F*.

       2f8:   003a7598 e320f000                                   .u:... .

...
 
#arm-linux-eabi-readelf -S arch/arm/boot/compressed/vmware
...
Section Headers:
  [Nr] Name              Type            Addr         Off       Size      ES  Flg  Lk   Inf  Al
  [ 0]                      NULL            00000000  000000  000000 00        0    0   0
  [ 1] .text            PROGBITS       00000000  008000  0059d0 00  AX  0   0  32
  [ 2] .rodata          PROGBITS       000059d0  00d9d0  000d4c 00   A   0   0   4
  [ 3] .piggydata      PROGBITS       0000671c  00e71c  29ced1 00   A   0   0   1
  [ 4] .got.plt          PROGBITS       002a35f0   2ab5f0  00000c  04  WA  0   0  4
  [ 5] .got              PROGBITS        002a35fc   2ab5fc   000034 00  WA  0   0  4
  [ 6] .pad              PROGBITS        002a3630  2ab630  000008 00  WA  0   0  1
  [ 7] .bss                NOBITS          002a3638  2ab638  000028 00  WA  0   0  4
  [ 8] .stack            NOBITS          002a3660  2ab638  001000 00  WA  0   0  1
  [ 9] .comment      PROGBITS        00000000 2ab638   000030 01  MS  0   0  1
...


 LC0에서 _end와 _edata는 3번째와 4번째에 들어가있습니다. 덤프파일을 보면 _end: 002a3660, _edata: 002a3638와 같습니다. 해당 값들은 섹션 헤더에서 .stack과 .bss의 주소로 나옵니다. 그렇다면 재배치에서 사용하는 LC0의 _end -restart + 16Kb + 1Mb값은 스택 시작주소에서 restart를 뺀값으로 보이는데 재배치해줄때 스택 사이즈는 제외한다는 말처럼 보입니다.

 그리고 5번째에는 inputdata - 4가 들어간다고 합니다. 압축된 커널의 끝에 압축 해제된 커널의 사이즈가 붙어있다는 문구가 있길래 살펴보니 살펴보면 002a35e9가 들어가 있으며, 해당 주소는 piggydata 시작주소 + piggydata size - 4를 한 값과 같습니다.

 하나씩 맞춰가는 재미가 있내요 ㅋ; 여기서 의문점이 생겨서 질문 드려요.

 

질문1. vmware덤프 파일에서 user_stack섹션으로 공간이 잡아진 부분이 보이는데 해당 부분은 필요없다는 말일까요?

질문2. off는 elf파일에서 해당 오프셋만큼의 위치에 해당 섹션이 존재한다는 말인가요?