coding, photo, plant and demo

*Android 4.2.2 emulator and kernel build on Ubuntu12.10 x64

android tech 20130322 233611
毎回ググってしまうので、メモっておく。
普通はsdkのemulatorでいいけど、ちょっと改造したい時とか、bionicのシンボルが欲しい時などには自分でビルドしておくのが吉。

vmware上のUbuntu 12.10 x64上で試した。
shellはzsh。
android sdkは既に入れた状態。

jdk6を入れる。
http://www.oracle.com/technetwork/java/javase/downloads/index.html

http://www.oracle.com/technetwork/java/javase/downloads/jdk6downloads-1902814.html
からjdk-6u43-linux-x64.bin落とす。ファイル名やサイトはアップデートがあると変わるので注意。

chmod u+x jdk-6u*-linux-x64.bin
./jdk-6u*-linux-x64.bin
sudo mv jdk1.6.0_* /usr/lib/jvm/

.zshrcに
export JAVA_HOME=/usr/lib/jvm
export PATH=$JAVA_HOME/bin:$PATH
等と加えておいて、再ロード。

環境を整えてソースを落とす。今回は4.2.2_r1を使おう。
sudo apt-get install git gnupg flex bison gperf build-essential \
  zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
  libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
  libgl1-mesa-dev g++-multilib mingw32 tofrodos \
  python-markdown libxml2-utils xsltproc zlib1g-dev:i386
sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so

curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > repo
chmod +x repo
./repo init -u https://android.googlesource.com/platform/manifest -b android-4.2.2_r1
./repo sync -j4

ビルド開始。
zshだとenvsetup.shの前にunsetopt NOMATCHした方がいい。
unsetopt NOMATCH && source build/envsetup.sh && lunch full-eng
make -j4

ビルドしたエミュレータを起動。
emualtor

このままだとgdbが起動しないのでpython2.6を入れる。
sudo add-apt-repository ppa:fkrull/deadsnakes
sudo apt-get update
sudo apt-get install python2.6 python2.6-dev

envsetup.shの便利関数、gdbclientを使うとプロセスへのアタッチが簡単にできる。
試しにsystem_serverにアタッチすると、
gdbclient app_process :5039 system_server
[4] 9412
Attached; pid = 278
Listening on port 5039
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs></http:>...
Reading symbols from /home/mtm/proj/jb/out/target/product/generic/symbols/system/bin/app_process...done.
Remote debugging from host 127.0.0.1
__ioctl () at bionic/libc/arch-arm/syscalls/__ioctl.S:10
10          ldmfd   sp!, {r4, r7}
(gdb) bt
#0  __ioctl () at bionic/libc/arch-arm/syscalls/__ioctl.S:10
#1  0x4004a930 in ioctl (fd=<optimized out>, request=-1072143871) at bionic/libc/bionic/ioctl.c:41
#2  0x40101ba4 in android::IPCThreadState::talkWithDriver (this=0x2a146f28, doReceive=<optimized out>) at frameworks/native/libs/binder/IPCThreadState.cpp:806
#3  0x40102366 in android::IPCThreadState::joinThreadPool (this=0x2a146f28, isMain=<optimized out>) at frameworks/native/libs/binder/IPCThreadState.cpp:457
#4  0x4a779312 in system_init () at frameworks/base/cmds/system_server/library/system_init.cpp:101
#5  0x4074e294 in dvmPlatformInvoke () at dalvik/vm/arch/arm/CallEABI.S:258
#6  0x4077d1fc in dvmCallJNIMethod (args=0x44c49ea4, pResult=0x2a00bbb8, method=0x44f16ca8, self=0x2a00bba8) at dalvik/vm/Jni.cpp:1155
#7  0x40768b48 in dvmCheckCallJNIMethod (args=<optimized out>, pResult=0x2a00bbb8, method=0x44f16ca8, self=0x2a00bba8) at dalvik/vm/CheckJni.cpp:145
#8  0x407576a4 in dalvik_mterp () at dalvik/vm/mterp/out/InterpAsm-armv7-a.S:16240
#9  0x4075b544 in dvmInterpret (self=0x2a00bba8, method=<optimized out>, pResult=0xbe9b88a0) at dalvik/vm/interp/Interp.cpp:1956
#10 0x4078fcae in dvmInvokeMethod (obj=<optimized out>, method=<optimized out>, argList=<optimized out>, params=0x40e5bd18, returnType=0x40a632a8, noAccessCheck=false) at dalvik/vm/interp/Stack.cpp:737
#11 0x407974c4 in Dalvik_java_lang_reflect_Method_invokeNative (args=<optimized out>, pResult=0x2a00bbb8) at dalvik/vm/native/java_lang_reflect_Method.cpp:101
#12 0x407576a4 in dalvik_mterp () at dalvik/vm/mterp/out/InterpAsm-armv7-a.S:16240
#13 0x4075b544 in dvmInterpret (self=0x2a00bba8, method=<optimized out>, pResult=0xbe9b8a30) at dalvik/vm/interp/Interp.cpp:1956
#14 0x4078f9d8 in dvmCallMethodV (self=0x2a00bba8, method=0x44cde108, obj=<optimized out>, fromJni=<optimized out>, pResult=0xbe9b8a30, args=...) at dalvik/vm/interp/Stack.cpp:526
#15 0x4077984e in CallStaticVoidMethodV (env=<optimized out>, jclazz=<optimized out>, methodID=0x44cde108, args=<optimized out>) at dalvik/vm/Jni.cpp:2092
#16 0x4076ce9c in Check_CallStaticVoidMethodV (env=<optimized out>, clazz=0x1d400015, methodID=0x44cde108, args=...) at dalvik/vm/CheckJni.cpp:1679
#17 0x40155872 in _JNIEnv::CallStaticVoidMethod (this=<optimized out>, clazz=<optimized out>, methodID=0x44cde108) at libnativehelper/include/nativehelper/jni.h:793
#18 0x40156536 in android::AndroidRuntime::start (this=<optimized out>, className=0x2a000ffb "com.android.internal.os.ZygoteInit", options=<optimized out>) at frameworks/base/core/jni/AndroidRuntime.cpp:888
#19 0x2a000dba in main (argc=4, argv=0xbe9b8be8) at frameworks/base/cmds/app_process/app_main.cpp:197
シンボル取れますね。

ついでにkernelもデバッグしたくなるかもしれないから、ビルドしておこう。
cd $ANDROID_BUILD_TOP
mkdir kernel
cd kernel
git clone https://android.googlesource.com/kernel/goldfish.git
git checkout origin/android-goldfish-2.6.29
export ARCH=arm
export SUBARCH=arm
export CROSS_COMPILE=arm-eabi-
make goldfish_armv7_defconfig
make

設定を変えたいときは、makeの前に
make menuconfig
とする。
Kernel hacking -> Compile the kernel with debug infoを有効にすると普通にデバッグできるようになる。

ただ今回試したらmenuconfigのビルド時に
mconf.c:(.text.startup+0x68): undefined reference to `stdscr'
scripts/kconfig/lxdialog/checklist.o: In function `print_arrows':
checklist.c:(.text+0x40): undefined reference to `wmove'
checklist.c:(.text+0x60): undefined reference to `acs_map'
等のエラーが出たので、
sudo apt-get install libncurses5-dev
とした。

ビルドしたkernelを使ってエミュレータをgdbとの通信ポート付(localhost:1234)で起動。
emulator -kernel $ANDROID_BUILD_TOP/kernel/goldfish/arch/arm/boot/zImage -qemu -s

ではカーネルにアタッチ。
arm-eabi-gdb
target remote localhost:1234
file vmlinux

試しにdo_sys_openに引っ掛ける様子。
GNU gdb (GDB) 7.3.1-gg2
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "--host=x86_64-linux-gnu --target=arm-linux-android".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs></http:>.
(gdb) target remote localhost:1234
Remote debugging using localhost:1234
vmlinux
0xc002ec4c in ?? ()
(gdb) file vmlinux
A program is being debugged already.
Are you sure you want to change the file? (y or n) y
Reading symbols from /home/mtm/proj/jb/kernel/goldfish/vmlinux...done.
(gdb) bt
#0  cpu_v7_do_idle () at arch/arm/mm/proc-v7.S:68
#1  0xc00286d8 in arch_idle () at arch/arm/mach-goldfish/include/mach/system.h:23
#2  default_idle () at arch/arm/kernel/process.c:137
#3  default_idle () at arch/arm/kernel/process.c:130
#4  0xc00288a8 in cpu_idle () at arch/arm/kernel/process.c:167
#5  0xc027df98 in rest_init () at init/main.c:472
#6  0xc00088e0 in start_kernel () at init/main.c:687
#7  0x00008034 in ?? ()
Cannot access memory at address 0x0
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb) b do_sys_open
Breakpoint 1 at 0xc008b390: file fs/open.c, line 1028.
(gdb) c
Continuing.

Breakpoint 1, do_sys_open (dfd=-100, filename=0xbeab6afc "/acct/uid/0/tasks", flags=131138, mode=438) at fs/open.c:1028
1028    {
(gdb) bt
#0  do_sys_open (dfd=-100, filename=0xbeab6afc "/acct/uid/0/tasks", flags=131138, mode=438) at fs/open.c:1028
#1  0xc008b4a0 in sys_open (filename=<optimized out>, flags=<optimized out>, mode=<optimized out>) at fs/open.c:1056
#2  0xc0027c80 in ?? ()
Cannot access memory at address 0x0
Backtrace stopped: previous frame inner to this frame (corrupt stack?)
(gdb)


参考ページ
Initializing a Build Environment
http://source.android.com/source/initializing.html
http://source.android.com/source/building-kernels.html

AndroidエミュレータでLinuxカーネルをデバッグ!!
http://monoist.atmarkit.co.jp/mn/articles/1008/03/news086.html

How to compile the Android Goldfish kernel
http://blog.markloiseau.com/2012/07/how-to-compile-the-android-goldfish-emulator-kernel