Compressed vmlinux 압축 해제 과정 디버깅

TRACE32
Admin (토론 | 기여) 사용자의 2015년 4월 9일 (목) 17:22 판

(비교) ← 이전 판 | 최신판 (비교) | 다음 판 → (비교)
이동: 둘러보기, 검색

Introduction

문서 소개

많은 업체에서 open OS인 Linux 를 이용해 제품 개발을 하고 있다. 일반적인 u-boot, kernel, application이 아닌 bootloader에서 kernel 로 넘어가는 과정에 압축 해제가 문제가 있을 경우 해당 부분을 어떻게 디버깅 해야 할지 확인하도록 한다.

decompressed vmlinux 디버깅

① Bootloader 에서는 do_bootm_linux() 함수에서 kernel 압축 해제 코드로 jump 하도록 되어 있다. do_bootm_linux() 까지 breakpoint 로 진행하여 확인한다.

 

② cleanup_before_linux() 함수에서 cache disable 등을 진행한다.

 

③ kernel_entry 로 jump 한다.

 

④ compressed vmlinux가 load되는 주소를 확인하여 vmlinux 이미지를 load 한다. load 주소는 ${kernel}\arch\<core architecture>\<project name>\Makefile.boot 에서 확인 하거나 boot_jump_linux() 함수 내의 kernel_entry 변수 값으로도 확인이 가능하다.

 

⑤ decompress_kernel() 함수에 breakpoint를 걸고 디버깅 할 수 있다.

relocation 과정이 추가 되는 경우

CPU의 boot sequence 에 따라 relocation 과정이 추가될 수 있다.

일반적으로는 bootloader 진행 시에 relocation 과정이 추가된다. do_bootm_linux() 에 on-chip breakpoint가 hit되지 않거나 SW breakpoint 가 hit된 후 assembly code가 bkpt #0x0 으로 변경되는 경우 symbol relocation을 진행해야 한다.

 

u-boot relocation 예제

① do_bootm_linux() 에 SW breakpoint를 설정한다.

 

② do_bootm_linux() 가 아닌 엉뚱한 위치에 breakpoint가 hit되면, Assembly가 bkpt #0x0으로 변경된다.

 

③ symbol relocation 계산

u-boot relocation address = do_bootm_linux() hit address - do_bootm_linux() symbol address + u-boot entry address

ex) 0x7ff99000 = 0x7FF9AB10 - 0x43E01B10 + 0x43E00000

 

④ symbol relocation 진행

-u-boot entry address+u-boot relocation address 에 relocation 하도록 한다.

ex) Data.LOAD.ELF  *\u-boot -0x43e00000+0x7ff99000 /Nocode

 

compress vmlinux 의 경우 relocation 예제

① vmlinux 파일 load 주소 확인 후 symbol load 합니다.

(${kernel}\arch\<core architecture>\<project name>\Makefile.boot에서 확인 하거나 boot_jump_linux() 함수 내의 kernel_entry 변수 값으로도 확인이 가능)

ex) Data.LOAD.ELF *\kernel\arch\arm\boot\compressed\vmlinux 0x40008000 /NOCODE /NOCLEAR

 

② restart label을 수행한다.

 

③ vmlinux 코드를 진행하다 보면 restart label을 두 번 수행하게 된다.
Head.s 의 Cache clean 이후 cpy pc, r0 명령을 만나면 symbol relocation 을 진행한다.

 

④ cpy pc, R0 명령에서 R0의 값이 0x40741208이고 restart label의 address가 0x400080A8 이므로 해당 address 를 relocation 시킨다.

Y.Reloc.Shift 0x40741208-0x400080A8

 

⑤ Relocation 된 vmlinux 를 디버깅 할 수 있다

 

Kernel 이미지(zImage or uImage)가 제대로 load 되지 않아 발생하는 경우 또는 압축 해제가 제대로 되지 않을 경우 위와 같은 과정을 통해 문제를 해결 할 수 있다.