Nexus 5에 ARM DS-5를 붙여서 profiling을 해야 할 필요가 있어서 정리 해 본다. (ARM DS-5 Using ARM Streamline)
기본적으로 참고한 사이트는 NEXUS10에 동일한 작업을 하는 ARM의 포스팅이다. (Using DS-5 Streamline with Mali on Google Nexus 10)
ARM DS-5 Streamline을 붙이는 핵심은 관련 kernel config가 적용된 kernel과 gator daemon을 추가할 수 있는 루팅된 디바이스 이다. 개발 버전 이미지의 경우 상당히 간단할 수 있는 작업인데, 출시된 디바이스를 가지고 환경을 만들려고 하니까 정말 빡센거 같다;;
1. 우선 Kernel config 적용이다.
Top Menu |
Specific Options |
Keywords for .config |
General Setup |
Profiling Support |
CONFIG_PROFILING |
Kernel Performance Events And Counters > Kernel performance event and counters |
CONFIG_PERF_EVENTS |
Kernel Hacking |
Tracers |
CONFIG_FTRACE |
Kernel Features |
High Resolution Timer Support |
CONFIG_HIGH_RES_TIMERS |
Enable hardware performance counter support for perf events |
CONFIG_HW_PERF_EVENTS |
Use local timer interrupts (Symmetric MultiProcessing, SMP) |
CONFIG_LOCAL_TIMERS |
CPU Power Management |
CPU Frequency scaling > CPU Frequency scaling (To enable the CPU Freq Timeline view chart) |
CONFIG_CPU_FREQ |
(Top Menu는 menuconfig 화면의 top level에 보이는 항목이고, Specific Options는 해당메뉴 진입후 보이는 option들)
위 옵션들을 적용하라고 되어 있고 적용하면 된다. make menuconfig로 설정할 수 도 있겠지만, 나는 그냥 arch/arm/configs/hammerhead_defconfig에 위 config들을 추가해 주었다.
위 사이트에 보면 gator driver를 module로 빌드(gator.ko)하기위해 module관련 kernel config들을 추가 해 주었는데, 나는 module 관련 config를 추가 후 빌드하니 에러가 발생해서 그냥 built-in driver로 빌드를 해 버렸다.
CONFIG_MODULES
CONFIG_MODULE_FORCE_LOAD
CONFIG_MODULE_UNLOAD
CONFIG_MODULE_FORCE_UNLOAD
그리고, gator feature를 활성화 해 주기 위해 CONFIG_GATOR=m 또는 CONFIG_GATOR=y를 추가 한다.
(위의 CONFIG_MODULES config가 추가되지 않으면, CONFIG_GATOR=m은 .config 파일에 자동으로 CONFIG_GATOR=y로 변경되어 추가된다)
2. gator 관련 소스를 kernel에 추가하고, kernel을 빌드한다.
gator 관련 소스는 설치한 DS-5 경로에 포함되어 있다. <DS-5 Installation Directory>/arm/gator/
나의 경우, driver source(driver-src)는 kernel/drivers/gator에 복사를 했고, daemon source(daemon-src)는 kernel/tools/gator에 복사 해 두었다. (사실 daemon은 어디에 있어도 상관 없음)
그리고, kernel을 빌드할 때 gator driver가 함께 빌드될 수 있도록, Kconfig 파일과 Makefile에 관련 내용을 추가 해 주어야 한다.
kernel/drivers/Kconfig에
source "drivers/gator/Kconfig"
kernel/drivers/Makefile에
obj-$(CONFIG_GATOR) += gator/
그리고 kernel을 빌드한다.
3. 빌드한 zImage를 포함하는 boot.img를 생성한다.
문제없이 kernel을 빌드하고 나면, kernel directory에 vmlinux 파일이, arch/arm/boot/에 zImage-dtb 파일이 생성된다. 위 ARM 사이트에는 zImage를 가지고 생성하는 방법이 나와 있는데, 난 전체 소스를 가지고 빌드를 했었기 때문에, 이것을 이용했다.
위 파일들을 적절한 위치에 복사한다. 즉,
vmlinux를 bzip2로 압축한 vmlinux.bz2와 zImage-dtb를 device/lge/hammerhead-kernel/에 복사한다.
(사실 vmlinux.bz2의 용도는 디버깅용으로 넣어 뒀나 보군. 없어도 될지도 모른다ㅎㅎ 귀찮아서 확인은 패스;;)
kernel$ bzip2 --best vmlinux.bz2
kernel$ cp vmlinux.bz2 (android-root)/device/lge/hammerhead-kernel/
kernel$ cp arch/arm/boot/zImage-dtb (android-root)/device/lge/hammerhead-kernel/
위와 같이 복사하고 boot.img 새로 생성하면 된다.
http://source.android.com/source/building-kernels.html#building에 보면, TARGET_PREBUILT_KERNEL을 설정하면 내 kernel path에 있는 image를 이용해 boot.img를 생성할 수 있다고 되어 있다. 되긴 된다. 그런데 뭘 잘못했는지 booting이 안됨;
4. 생성한 boot.img로 정상부팅 확인(옵션)
정상 부팅이 되는지 확인 해 볼 수 있다. 다만 device를 루팅해야 되는데, 이때 순정 kernel이 아닌 custom kernel일 경우 문제가 생길지도 모르니(루팅은 이번이 처음이라 잘 모르겠음;;), 순정 image로 복원을 해야 할 수 도 있다.
(순정 이미지 복원은 https://dl.google.com/dl/android/aosp/hammerhead-ktu84p-factory-35ea0277.tgz 이용)
정상적으로 부팅이 되고, Settings > About phone > Kernel version에 자신이 빌드한 kernel 정보가 나오면 성공 임.
5. gator daemon 빌드
gator daemon을 빌드한다. 요건 device에서 실행되는 ARM binary로 NDK를 이용해서 빌드하면 된다.
위 ARM 사이트에 친절히 설명이 되어 있긴 한데, jni 디렉토리를 생성해서 gator daemon 소스를 몽땅 복사(혹은 이동) 후, ndk-build를 실행하면 libs/armeabi/gatord가 생성된다.
(gator-daemon 디렉토리가 있다면, 여기에서 jni 디렉토리를 생성하고 gator daemon 소스를 몽땅 복사한다. 이후 gator-daemon 디렉토리에서 ndk-build를 실행하면, gator-daemon/libs/armeabi/gatord 파일이 생성된다)
6. 디바이스 rooting이 필요한 시점!
gatord를 system partion에 넣어야 하므로 rooting이 필요하다. 루팅 방법은 아래 사이트에 잘 정리되어 있으니 참고하면 된다.
Nexus Root Toolkit: http://www.wugfresh.com/nrt/
NRT 사용법 설명1: http://ryueyes11.tistory.com/3066
NRT 사용법 설명2: http://greenz.tistory.com/9
7. gatord를 system/bin에 복사한다.
복사 방법은 ARM posting에서 복사 해 뒀다.
adb shell su -c 'mount -o remount /system'
adb push gatord /sdcard/
adb shell su -c 'cp /sdcard/gator* /system/bin/'
adb shell su -c 'chmod 777 /system/bin/gatord'
8. gatord 실행!
adb shell su -c 'mount -o remount /system'
adb forward tcp:8080 tcp:8080
adb shell su -c '/system/bin/gatord &'
여기에서, gator driver가 built-in으로 추가되어 있지 않은 경우, daemon이 실행되지 않는다.
9. host에서 Streamline 실행 후 연결 확인!
ARM DS-5 Streamline의 연결 방법은 구글링으로~
제대로 정리했나 모르겠네.ㅎㅎ 이제는 Streamline에서 android process 프로파일링 하는 방법 알아봐야겠군;;
google에서 주는 trace tool 들도 좀 알아봐야지.
2015-12-24 크리스마스 이브에 추가:
Android M OS로 업그레이드 되면서 linux kernel의 버전도 변경되어 gator driver의 Kconfig에서 dependency로 설정되어 있는, CONFIG_LOCAL_TIMERS feature는 더이상 지원이 되지 않는 듯 하다.
따라서, M OS에서 defconfig에 CONFIG_GATOR를 추가하면, 위의 dpendency 때문에 GATOR feature가 추가되지 않는 문제가 발생한다 gator driver의 Kconfig에서 해당 dependency를 제거 해 주면, 문제가 해결 된다! (이것땜에 온갖 삽질을 다 했구나...;;)
(위 내용들은 정상동작이 확인되지 않음;; daemon과 driver가 붙으면 target reset이 되어 버림;;)
추가로 발견한 사실은, defconfig에 아래 세 개의 feature만 추가 해 주면, 나머지 필요한 feature들은 자동으로 추가가 된다.
CONFIG_PROFILING=y
CONFIG_HIGH_RES_TIMERS=y
CONFIG_GATOR=y
* cat /sys/module/gator/version 으로 확인할 수 있는 버전은 ARM DS-5의 버전과 일치해야 하며, 예를들어 결과가 231인 경우 DS-5 v5.23.1과 대응되고, 20인 경우는 DS-5 v5.20과 대응된다. (소스상에서는 gator_main.c 에서 PROTOCOL_VERSION으로 확인 가능)
이상!!!