1. 안드로이드 구조와 원리
수원 안드로이드 스터디
Linux Kernel Source 분석 스터디
이백
2. 안드로이드
• Android is an open-source software stack
for mobile devices
http://developer.android.com/guide/basics/what-is-android.html
OS(kernel) + root fil
OS(k l) t filesystem + GUI 프레임워크
t
컴파일러 + 라이브러리 + 개발 툴 + 디버깅 + 가상 디바이스
3. 안드로이드를 선택하는 이유?
• 단말기 제조사
- 잘 만들었는데, 컨텐츠 개발이 부담된다 .
• 시스템 프로그래머
- OS, 툴체인, GUI 프레임워크는 무엇으로 하지?
- SDK 구성 및 배포 책임
• 애플리케이션 프로그래머
- 단말기에 종속 되지 않는다 않는다.
- 저기요. 툴체인 및 sdk 주세요.
- 저기요. LCD on/off 어떻게 합니까?
5. 사운드 프레임워크 구조
Application
애플리케이션
애플리케이션 프레임워크 MediaPlayer
JNI ( 달빅 )
서비스 프레임워크 MediaPlayer AudioFlinger
RPC ( 바인더 )
libaudio.so
HAL
Alsa Library
Library
Alsa Driver
디바이스 드라이버
6. Application 개발 환경
• SDK 다운 다운로드
• Eclipse 설치
p
• ADT(Android
• Development Tool) 설치
• http://developer.android.com/sdk/index.html
• http://www.androidpub.com/41231
9. 안드로이드 플랫폼 소스
# cd ~
d
# mkdir bin
# echo $PATH
# curl http://android.git.kernel.org/repo >~/bin/repo
# chmod a+x ~/bin/repo
# export PATH=$PATH:/root/bin
# cd /android_root/
# repo i it -u git://android.git.kernel.org/platform/manifest.git
init it // d id it k l / l tf / if t it
# repo sync
http://source.android.com/source/download.html
10. 안드로이드 플랫폼 소스 구조
• bionic
bi i : 안드로이드 표준 라이브러리
• bootable : 참고용 안드로이드 부트로더
• build : 안드로이드 빌드 시스템
• cts : 안드로이드 호환성 테스트 프로그램
• dalvik : 달빅 가상 머신
• development : 개발 관련 지원 소스
• external : 공개용 라이브러리
• frameworks : 안드로이드 프레임워크
• hardware : 안드로이드 HAL
• out : 빌드 후 모음
• packages : 안드로이드 기본 애플리케이션
• prebuilt : 컴파일러
• system : 안드이드 코어 프로그램, init 프로세스
11. bionic 라이브러리
Why build a custom libc library?
• License: we want to keep GPL out of user-space
• Size: will load in each process, so it needs to be small
• Fast: limited CPU power means we need to be fast
• BSD License
• Small size and fast code paths
• Very fast and small custom pthread implementation
Built-in support for important Android-specific services
• system properties
getprop(“my.system.property”, buff, default);
• log capabilities
LOGI(“Logging a message with priority ‘Info’”);
bionic/libc/SYSCALLS.TXT (지원하는 시 템 콜 목록
bi i lib 지원하는 시스템 목록)
http://andstudy.springnote.com/pages/3660069 (스터디에서 조사한 추가 자료)
/etc/passwd, /etc/group 없음,
// system/core/include/private/android_filesystem_config.h
y / / /p / _ y _ g
#define AID_ROOT 0 /* traditional unix root user */
#define AID_SYSTEM 1000 /* system server */
#define AID_RADIO 1001 /* telephony subsystem, RIL */
#define AID_BLUETOOTH 1002 /* bluetooth subsystem */
:
12. 안드로이드 소스 빌드
• 빌드
export LANG=c
export JAVA_HOME=/usr/jdk1.5.0_19
export PATH=$JAVA_HOME/bin:$PATH
export ANDROID_JAVA_HOME=$JAVA_HOME
$ make
k
• 파일 복사
out/target/product/generic/ramdisk.img -> platforms/android-7/images/
out/target/product/generic/system.img -> platforms/android-7/images/
out/target/product/generic/userdata.img -> platforms/android-7/images/
13. Goldfish 리눅스 커널 빌드
• 다운로드 및 빌드
# git clone git://android.kernel.org/kernel/common.git kernel-goldfish
# cd kernel-goldfish
# git branch -r
g /
origin/HEAD
origin/android-2.6.25
origin/android-2.6.27
origin/android-2.6.29
origin/android-goldfish-2.6.27
origin/android-goldfish-2.6.29
i i d id ldfi h
# git checkout --track -b android-goldfish-2.6.29 origin/android-goldfish-2.6.29
# export ARCH=arm
# export CROSS_COMPILE=/android_root/prebuilt/linux-x86/toolchain/arm-eabi-4.3.1/bin/arm-eabi-
# make goldfish_defconfig
# make
• 파일 복사
arch/arm/boot/zImage -> platforms/android-7/images/kernel-qemu
14. 파티션 구조 비교
기본 임베디드 linux 환경의 파티션 안드로이드 환경의 파티션
부트로더 <- u-boot.bin 부트로더 <- u-boot.bin
커널 <- zImage 커널 <- zImage
루트파일시스템 <- rootfs 루트파일시스템 <- ramdisk.img
User 영역 ( APP, 추가 데이터 ) system <- system.img
cache
userdata <- userdata.img
/
:
/system
/cache
/data
15. 안드로이드 커널
• Linux kernel 2.6 기반
• ashmem/pmem – 프로세스간 메모리 공유
p
• Binder - RPC
• Power Management
• Low Memory Killer
• Logger
16. Runtime Walkthrough
Content Telephony Bluetooth Connectivity Location
Manager
M Service Service Service Manager
Window Activity Package Power
…
Manager Manager Manager Manager
JNI
AudioFlinger Surface
MediaPlayerService Flinger
System
CameraService
Server
컨텍스트 데몬 Media
매니저 데몬
데몬 Zygote Dalvi VM
Server
init
18. init.rc
init rc
• init.rc int.hardware.rc
init rc , int hardware rc ( /proc/cpuinfo의 Hardware 필드 ) 파일 분석
on init
sysclktz 0
loglevel 3
g
export PATH /sbin:/system/sbin:/system/bin:/system/xbin
export LD_LIBRARY_PATH /system/lib
:
on boot
ifup lo
setrlimit 13 40 40
:
service console /system/bin/sh
console
service adbd /sbin/adbd
disabled 출처 : [책] 인사이드 안드로이드
:
• system/core/init/readme.txt : 구조에 대한 설명
• system/core/rootdir/init.rc : 기본 init.rc 파일
19. 디바이스 노드 생성
• 빌드 시 만들어 지는 루트파일 시스템에는 /d 가 존재하지 않는다/dev 않는다.
• 콜드플러그(Cold Plug)/핫 플러그(Hot Plug)
• uevent 사용 – 커널에서 사용자 공간으로의 정보 전달
• /sys 의 uevent 파일 검색 -> “add” uevent 강제 발생
> add
• 퍼미션 변경이 필요한 경우 소스 내에 기록된 퍼미션 적용 ( 기본 0600, root, root )
“addn” struct uevent {
const char *action; // "add"
/sys/devices/mydd/uevent const char *path;
const char *subsystem;
subsystem;
my Device Driver const char *firmware;
int major; // xx
int minor; // xx
;
}
// system/core/init/devices.c
static struct perms devperms[] = {
perms_ uevent socket
{ "/dev/null", 0666, AID_ROOT, AID_ROOT, 0 },
{ "/dev/zero", 0666, AID_ROOT, AID_ROOT, 0 },
:
20. 펌웨어 업데이트
• 리눅스에서 처리되는 uevent ( / /bi /h t l
t /usr/bin/hotplug )
SUBSYSTEM=module
DEVPATH=/module/firmware_sample_driver
LD_LIBRARY_PATH=/lib:/usr/lib
PATH=/sbin:/bin:/usr/sbin:/usr/bin
PATH / bi /bi / / bi / /bi
echo 1 > /sys/$DEVPATH/loading
cat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
echo 0 > /sys/$DEVPATH/loading
$
• init 의 처리 ( 시간이 다소 걸리는 것을 고려해서 이 루틴은 별도의 프로세스(fork)로 동작한다. )
// system/core/init/devices.c
static int load_firmware(int fw_fd, int loading_fd, int data_fd)
{
// 1) loading_fd 에 1 를 write 하여 다운로드 시작 알림
// 2) 바이너리 펌웨어를 읽어서 (fw_fd), 드라이버의 버퍼로 복사(data_fd)
// 3) loading_fd 에 0 를 wirte 하여 다운로드 완료 알림
}
21. 프로퍼티
• ashmem(Android Sh d M
h (A d id Shared Memory) 영역
)
• 모든 프로세스에서 조회 가능 및 init에게 변경 요청
bionic 의 start 코드에서 이 영역의 정보를 가진다.
-> _start
-> __libc_init() 함수
> libc init()
-> __libc_init_common() 함수
-> __system_properties_init() 함수
-> main 함수
# default.prop
# ADDITIONAL DEFAULT PROPERTIES
ADDITIONAL_DEFAULT_PROPERTIES
#
ro.secure=0
ro.allow.mock.location=1
ro.debuggable 1
ro.debuggable=1
출처
출 : [책] 인사이드 안드로이드
persist.service.adb.enable=1
[command line] # setprop net.dns1 168.126.63.1
22. 자식 프로세스
• service 키워드로 기술된 내용
i
• 자식 프로세스가 종료(SIGCHILD) 될 때 필요한 작업을 수행한다. ( 리소스 해제 및 재
시작 )
service servicemanager /system/bin/servicemanager
user system
critical
onrestart restart zygote
onrestart restart media
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
service b
i bootanim /
i /system/bin/bootanimation
/bi /b i i
user graphics
group graphics
disabled
oneshot
23. POLL 서버(메인루프)
ufds[0].fd device_fd;
ufds[0] fd = device fd; // 디바이드의 uevent 서비스
ufds[0].events = POLLIN;
ufds[1].fd = property_set_fd; // 프러퍼티 변경 서비스
ufds[1].events = POLLIN;
ufds[2].fd = signal_recv_fd; // 자식 프로세스 종료 처리 서비스
ufds[2].events
ufds[2] events = POLLIN;
fd_count = 3;
:
for(;;) {
nr = poll(ufds, fd_count, timeout);
p ( , , );
// 자식 프로세스 종료 처리 및 재 시작
// 디바이스 노드 생성
// 프로퍼티 변경
}
출처 : [책] 인사이드 안드로이드
24. 그외
• 초기에 디렉 리 생성 및 마
기에 디렉토리 마운트
• stdin, stdout, stderr 를 사용 못함
• “ANDROID” 글자 출력
( /initlogo.rle 파일이 있으면 화면 출력 )
• 리눅스의 숨겨진 기능을 활용하는 잘 짜여진 코드
25. logcat
# logcat
I/DEBUG ( 1780): debuggerd: Jun 9 2009 13:56:46
E/flash_image( 1788): can't find recovery partition
I/ServiceManager( 1778): sm : start
I/Binder ( 1778): [BLEE] binder_open fd=6, mapped=0x40008000
mapsize=131072
D/qemud ( 1790): main: can't find 'android.qemud=' in /proc/cmdline
/q ) q /p /
I/vold ( 1779): Android Volume Daemon version 2.0
E/vold ( 1779): Unable to open '/sys/class/mmc_host' (m)
D/vold ( 1779): Bootstrapping complete
D/AndroidRuntime( 1782):
D/AndroidRuntime( 1782): >>>>>>>>>>>>>> AndroidRuntime START
<<<<<<<<<<<<<<
D/AndroidRuntime( 1782): CheckJNI is
D/A d idR ti ( 1782) Ch kJNI i ON
I/ ( 1783): ServiceManager: 0xac38
26. JNI
JNI(Java N ti I t f
JNI(J Native Interface)
)
출처 : [책] 인사이드 안드로이드
27. 안드로이드 JNI Application
classes.dex Hello.java
Hello.apk resources.arsc *.xml
libhello-jni.so Hello.cpp
Hello.java public native String printHello(String str); so 파일 로딩 시 심볼을
검색 후 동적 테이블을 생성한다.
default JNI_OnLoad(..)
달빅 가상머신
Hello.cpp jstringJava_com_example_hellojni_HelloJni_printHello(
JNIEnv* env, jobject thiz, jstring srt )
NDK ( Native Development Kit ) - http://developer.android.com/sdk/ndk/index.html
- Hello.cpp 컴파일 하여 hello-jni.so 생성해 준다.
- so 바이너리를 생성하기 위한 툴일 뿐이며, 코드 작성 및 필요한 사항은 개발자가 해 주어야 한다. 필 한 한다
28. NDK 컴파일
$ cd android ndk r3
android-ndk-r3
$ ./build/host-setup.sh
$ make APP=hello-jni
New -> Project -> Android Project
android-ndk-r3/apps/hello-jni/project
29. system server - 정적 테이블
public class SystemServer
/* {
* JNI registration. native public static void init1(String[] args);
}
*/
static JNINativeMethod gMethods[] = {
g []
/* name, signature, funcPtr */
{ "init1", "([Ljava/lang/String;)V", (void*) android_server_SystemServer_init1 },
};
int register_android_server_SystemServer(JNIEnv* env)
{
return jniRegisterNativeMethods(env "com/android/server/SystemServer",
jniRegisterNativeMethods(env, com/android/server/SystemServer
gMethods, NELEM(gMethods));
}
JNI_OnLoad(..)
JNI OnLoad(..) 에서 구현
static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
system_init();
system init();
}
• frameworks/base/services/jni/*
30. zygote
• 달빅(Dalvik)
달빅(D l ik) 초기화 수행
• 애플리케이션 실행 속도 향상
• System Server 를 실행
// init.rc
service zygote / y
yg /system/bin/app_process -Xzygote /system/bin --zygote --
/ / pp_p yg / y / yg
start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_state wake
onrestart write /sys/power/state on
onrestart restart media
31. zygote – 동작 원리
출처 : [책] 인사이드 안드로이드
zygote 에서 새로운 애플리케이션 실행
# sh B – 리눅스에서 새로운
리눅 에서 새 운
프로세스 실행
33. 서비스
출처 : [책] 인사이드 안드로이드
https://sites.google.com/site/io/anatomy--physiology-of-an-android
34. 애플리케이션 서비스
출처 : [책] 인사이드 안드로이드
<로컬서비스>
로컬서비스
서비스의 레퍼런스를 가져온다 <리모트서비스>
AIDL(Android Interface Definition Language)를
사용한 바인더 IPC
http://developer.android.com/guide/developing/tools/aidl.html
35. 시스템 서비스
• 네이티브 서비스
AudioFlinger – 오디오 입/출력
SurfaceFlinger – 화면 출력
CameraService – 카메라 입/출력
• 코어 플랫폼 서비스
Activity Manager Service – 액티비트 관리
Window Manager Service – 화면 그리기 관리
Package Manager Service – 패키지(apk) 관리
• 하드웨어 서비스
출처 : [책] 인사이드 안드로이드
Alarm Manager Service – 타이머 관리
Connectivity Service – 네트웍 상태 정보
Location Service – 단말의 위치 정보
Power Service – 전원 관리
Sensor Service – 센서 디바이스 관리
Telephony Service – 전화 서비스
Wifi Service – 무선 검색, 연결 관리
36. Layer Interaction
• There are 3 main fl
h flavors of Android l
f d d layer cake:
k
• App -> Runtime Service -> lib
• App -> Runtime Service -> Native Service -> lib
• App -> Runtime Service -> Native Daemon -> lib
41. 컨텍스트 매니저
네
네, 저한테 저는 foo라
맡겨 주십 는 서비스
시요. 입니다.
컨텍스트 매니저 서비스
컨텍
컨텍스트 매니저!
매니저
foo라는 서비스를
찾습니다.
// init.rc 서비스 사용자
service servicemanager /system/bin/servicemanager
user system
t
critical
onrestart restart zygote
onrestart restart media
49. 서비스 프레임워크
• P ProcessState
St t
– biner open, mmap 할당
• IPCThreadState
- 바인더 프로토콜, IPC 처리
콜
• BpBinder / BBinder
- 서비스 프록시 / 서비스 스텁 인터페이스 IInterface
• IInterface
- 바인더 공통 부분 IFooService
서비스 인터페이스
• BpXXX / BnXXX
- 서비스 프록시 / 서비스 스텁 BnFooService BpFooService
서비스 스텁 서비스 프록시
• 서비스 매니저 FooService
- 서비스 등록, 서비스 검색 서비스
50. 서비스 프레임워크 - 레이어
서비스 클라이언트 서비스 서버
서비스 사용자
IFooService IFooService
서비스 인터페이스 서비스 서비스 인터페이스
레이어 FooService
F S i
서비스
BpFooService RPC BnFooService
서비스 프록시 레이어 서비스 스텁
BpBinder BBinder
IPC
IPCThreadState 레이어 IPCThreadState
바인더 드라이버
51. 서비스 프레임워크 - 프록시
서비
서비스 사용자
서비스 레이어 함수 호출 인자 전달
서비스 프록시
RPC 레이어 바인더 RPC 코드 바인더 RPC 데이터
BpBinder 서비스 핸들
IPC 레이어 IPCThreadState
바인더 프로토콜
바인더 IPC 데이터
바인더 binder_transaction_data
프로토콜
handle code buffer
BC_TRANSACTION 1 바인더 RPC 코드 바인더 RPC 데이터
ioctl i
i l write
바인더 드라이버
52. 서비스 프레임워크 - 스텁
서비
서비스
서비스 레이어 함수 호출 인자 전달
서비스 스텁
RPC 레이어 바인더 RPC 코드 바인더 RPC 데이터
BBinder 서비스 인스턴스
IPC 레이어 IPCThreadState
바인더 프로토콜
바인더 IPC 데이터
바인더 binder_transaction_data
프로토콜
cookie code buffer
BR_TRANSACTION xxx 바인더 RPC 코드 바인더 RPC 데이터
ioctl
i l read
d
바인더 드라이버
57. 서비스 프레임워크 상호 동작
프로세스 A의 프로세스 B의
사용자 메모리 영역 바인더 mmap 영역
프로세스 A 용어1 - 바인더 RPC
데이터
용어1 - 바인더 RPC 데
이터
프로세스 B
value value
BpAudioFlinger AudioFlinger ( 서비스)
(서비스 프록시)
setMasterVolume(float value)
setMasterVolume(float value)
{
... 바인더 RPC {
...
}
}
서비스 서비스
프레임워크 바인더 IPC 프레임워크
용어2 - 바인더 IPC 데이터 용어2 - 바인더 IPC 데이터
바인더 binder_transaction_data 바인더 binder_transaction_data
프로토콜 프로토콜
handle code buffer cookie code buffer
SET_MASTER_VOLUME SET_MASTER_VOLUME
ioctl ioctl
바인더 드라이버