Arm Linux Kernel Hacks

rousalome.egloos.com

포토로그 Kernel Crash


통계 위젯 (화이트)

3440
557
422296


[라즈베리파이]리눅스 커널 매크로 분석 방법 부록

매크로 분석에 도움 되는 두 가지 방법을 소개합니다. 전처리 파일 추출과 바이너리 유틸리티를 활용해서 어셈블리 코드를 보는 방법입니다. 매크로를 분석할 때는 물론 평소 커널 코드 읽을 때는 이 방법을 적극적으로 활용해서 분석하기를 바랍니다. C 코드만 볼 때 보다 훨씬 효율적으로 코드를 읽을 수 있고 더 유용한 디버깅 정보를 볼 수 있거든요.

전처리 파일 추출
이번에는 전처리 코드를 추출하는 방법을 소개합니다.

보통 리눅스 커널 코드를 분석할 때 C 코드를 열어 봅니다. 그런데 C 코드를 전처리 파일과 함께 분석하면 효율적으로 리눅스 커널 코드를 읽을 수 있습니다. 그 이유는 컴파일러가 전처리 과정에서 매크로를 모두 풀어서 표현한 정보를 전처리 파일이 담고 있기 때문입니다.

그럼 리눅스 커널 코드에서 전처리 파일을 어떻게 생성할까요? 방법은 매우 간단합니다. 리눅스 커널을 빌드하는 Makefile을 다음과 같이 수정하고 빌드하면 됩니다.
diff --git a/Makefile b/Makefile
index 4a7e6df..313dbbe 100644
--- a/Makefile
+++ b/Makefile
@@ -395,6 +395,7 @@ KBUILD_CFLAGS   := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs
                   -fno-strict-aliasing -fno-common
                   -Werror-implicit-function-declaration
                   -Wno-format-security
+                  -save-temps=obj
                   -std=gnu89
 KBUILD_CPPFLAGS := -D__KERNEL__
 KBUILD_AFLAGS_KERNEL :=

위와 같이 Makefile을 수정하여 커널 빌드를 완료하면 전처리 파일이 생성됩니다. 그럼 전처리 파일은 어디에서 볼 수 있나요? 아래 명령어로 전처리 파일을 각 커널 디렉터리에서 확인할 수 있습니다.
austindh.kim@~/src/raspberry_kernel/linux$ find . -name *.i | more
./mm/.tmp_filemap.i
./mm/.tmp_dmapool.i
./mm/.tmp_highmem.i
./mm/.tmp_mmu_context.i
./mm/.tmp_slab_common.i
./mm/.tmp_readahead.i

평소 전처리 파일은 특정 폴더에 저장해 놓고 코드 분석에 활용하면 좋습니다.

바이너리 유틸리티로 어셈블리 코드 분석

라즈베리파이 github에서 크로스 컴파일 툴 체인 프로그램을 다운로드 할 수 있는데요.
다음 명령어를 입력하면 다운로드 받을 수 있습니다. 참고로 이 명령어는 라즈베리파이 커뮤니티에서 확인할 수 있어요.
git clone https://github.com/raspberrypi/tools

다운로드가 끝나면 여러 가지 폴더가 생성됩니다. 이 중에서 arm-bcm2708 하위 폴더로 이동하면 다음과 같은 바이너리 유틸리티를 확인할 수 있습니다. 디렉터리 위치는 다음과 같습니다.
[./arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian/bin]

바이너리 유틸리티 프로그램 설치 방법을 설명 드리는 이유는 바이너리 유틸리티 중 arm-linux-gnueabihf-objdump를 써서 어셈블리 코드를 볼 수 있기 때문입니다. 

그럼 어셈블리 코드를 어떻게 생성할까요? 라즈베리안을 리눅스 커널을 컴파일하면 디버깅 정보가 포함된 vmlinux가 생성됩니다. 이 vmlinux를 arm-linux-gnueabihf-objdump란 바이너리 유틸리티로 실행하면 됩니다. arm-linux-gnueabihf-objdump 파일과 vmlinux을 같은 폴더에 위치시키고 다음 명령어를 입력하면, 라즈베리안 리눅스 커널 코드를 어셈블리 형태로 볼 수 있습니다.
./arm-linux-gnueabihf-objdump -S -d vmlinux  > rasberian_kernel_code.c

잠깐 여기서 리눅스 커널을 익힐 때 어셈블리 코드 분석이 얼마나 중요한지에 대해서 잠깐 말씀 드리려고해요. 그동안 리눅스 커널을 C 코드 형태로 읽었던 분이 어셈블리 명령어를 함께 분석하면 다양한 지식을 얻을 수 있습니다. 왜냐면 리눅스 커널 핵심 코드는 어셈블리 코드로 구현돼 있기 때문이죠. 사실 리눅스 커널 이론서에 있는 많은 내용은 어셈블리 코드를 분석한 결과를 요약한 것이거든요. 리눅스 커널의 핵심 개념을 제대로 이해하려면 어셈블리 명령어를 잘 알아야겠죠.

여기까지 리눅스 커널 코드를 분석하는데 유용한 두 가지 기법을 소개했습니다. 그럼 앞으로 전처리 파일과 어셈블리 코드를 활용해서 어떻게 매크로를 분석하는지 기대하세요.



# Reference: For more information on 'Linux Kernel';

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 1

디버깅을 통해 배우는 리눅스 커널의 구조와 원리. 2


 



핑백

덧글

  • 쾌도난마 2019/02/08 10:28 # 답글

    좋은 정보글 감사합니다.

    전처리 관련하여 다른 방법을 공유하면

    make file.i

    하면 쉽게 원하는 파일만 전처리된 것으로 볼 수 있습니다.

    ex>
    make drivers/i2c/i2c-core.i

    kernel feature 가 생성된 상태(.config)에서 가능합니다~
  • AustinKim 2019/02/08 11:03 #

    유익한 정보 감사합니다. 알려주신 팁 잘 활용해야 겠습니다.
댓글 입력 영역