안드로이드 플랫폼 설명
DESCRIPTION
수원 안드로이드 스터디 안드로이드 구조와 원리 세미나 자료TRANSCRIPT
안드로이드 구조와 원리
수원 안드로이드 스터디수원 안드로이드 스터디Linux Kernel Source 분석 스터디
이백이백
안드로이드안드로이드
• Android is an open-source software stack for mobile devices
http://developer.android.com/guide/basics/what-is-android.html
OS(k l) t fil t GUI 프레임워크OS(kernel) + root filesystem + GUI 프레임워크컴파일러 + 라이브러리 + 개발 툴 + 디버깅 + 가상 디바이스
안드로이드를 선택하는 이유?안드로이드를 선택하는 이유?
단말기 제조사• 단말기 제조사- 잘 만들었는데, 컨텐츠 개발이 부담된다.
• 시스템 프로그래머시스템 프로그래머- OS, 툴체인, GUI 프레임워크는 무엇으로 하지?- SDK 구성 및 배포 책임
• 애플리케이션 프로그래머- 단말기에 종속 되지 않는다단말기에 종속 되지 않는다.- 저기요. 툴체인 및 sdk 주세요. - 저기요. LCD on/off 어떻게 합니까?
안드로이드 플랫폼안드로이드 플랫폼
사운드 프레임워크 구조사운드 프레임워크 구조
Application애플리케이션
MediaPlayer애플리케이션 프레임워크JNI ( 달빅 )
MediaPlayer AudioFlinger서비스 프레임워크RPC ( 바인더 )
libaudio.so
Alsa Library
HAL
Alsa Driver
Alsa LibraryLibrary
디바이스 드라이버디바이스 드라이버
Application 개발 환경Application 개발 환경
SDK 다운• SDK 다운로드• Eclipse 설치p 설치• ADT(Android
) 설치• Development Tool) 설치
• http://developer.android.com/sdk/index.html• http://www.androidpub.com/41231
SDK 업데이트SDK 업데이트
Application 개발 준비 완료Application 개발 준비 완료
안드로이드 플랫폼 소스안드로이드 플랫폼 소스
# d# cd ~# mkdir bin# echo $PATH# echo $PATH# curl http://android.git.kernel.org/repo >~/bin/repo # chmod a+x ~/bin/repo# export PATH=$PATH:/root/bin# cd /android_root/# i it it // d id it k l / l tf / if t it# repo init -u git://android.git.kernel.org/platform/manifest.git# repo sync
http://source.android.com/source/download.html
안드로이드 플랫폼 소스 구조안드로이드 플랫폼 소스 구조
bi i 안드로이드 표준 라이브러리• bionic : 안드로이드 표준 라이브러리• bootable : 참고용 안드로이드 부트로더• build : 안드로이드 빌드 시스템
cts : 안드로이드 호환성 테스트 프로그램• cts : 안드로이드 호환성 테스트 프로그램• dalvik : 달빅 가상 머신• development : 개발 관련 지원 소스• external : 공개용 라이브러리• external : 공개용 라이브러리• frameworks : 안드로이드 프레임워크• hardware : 안드로이드 HAL• out : 빌드 후 모음out : 빌드 후 모음• packages : 안드로이드 기본 애플리케이션• prebuilt : 컴파일러• system : 안드이드 코어 프로그램, init 프로세스system : 안드이드 코어 프로그램, init 프로세스
bionic 라이브러리bionic 라이브러리Why build a custom libc library?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• Small size and fast code paths• Very fast and small custom pthread implementation
Built-in support for important Android-specific services• system propertiessystem properties
getprop(“my.system.property”, buff, default);• log capabilities
LOGI(“Logging a message with priority ‘Info’”);
bi i lib 지원하는 시 템 콜 목록bionic/libc/SYSCALLS.TXT (지원하는 시스템 콜 목록)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 */::
안드로이드 소스 빌드안드로이드 소스 빌드• 빌드• 빌드export LANG=cexport JAVA_HOME=/usr/jdk1.5.0_19export PATH=$JAVA_HOME/bin:$PATHexport ANDROID_JAVA_HOME=$JAVA_HOME$ k$ make
파일 복사• 파일 복사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/
Goldfish 리눅스 커널 빌드Goldfish 리눅스 커널 빌드• 다운로드 및 빌드• 다운로드 및 빌드# git clone git://android.kernel.org/kernel/common.git kernel-goldfish# cd kernel-goldfish# git branch -r
origin/HEADg /origin/android-2.6.25origin/android-2.6.27origin/android-2.6.29origin/android-goldfish-2.6.27
i i d id ldfi horigin/android-goldfish-2.6.29
# git checkout --track -b android-goldfish-2.6.29 origin/android-goldfish-2.6.29
# export ARCH=arm# 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
파티션 구조 비교파티션 구조 비교
기본 임베디드 linux 환경의 파티션 안드로이드 환경의 파티션
부트로더 <- u-boot.bin
커널 <- zImage
루트파일시스템 <- rootfs
부트로더 <- u-boot.bin
커널 <- zImage
루트파일시스템 <- ramdisk.img
User 영역 ( APP, 추가 데이터 ) system <- system.img
cache
userdata <- userdata.img
/:/system/cache/data
안드로이드 커널안드로이드 커널
• Linux kernel 2.6 기반• ashmem/pmem – 프로세스간 메모리 공유p• Binder - RPC• Power Management• Power Management• Low Memory Killer• Logger
Runtime WalkthroughRuntime WalkthroughContentM
TelephonyService
BluetoothService
ConnectivityService
LocationManagerManager Service Service Service Manager
WindowManager
ActivityManager
PackageManager
PowerManager
…
JNI
SurfaceAudioFlinger
Flinger
SystemServer
MediaPlayerService
CameraService
컨텍스트매니저 Zygote Dalvi VM
데몬데몬데몬MediaServer
init
initinit
출처 : [책] 인사이드 안드로이드
init rcinit.rc• init rc int hardware rc ( /proc/cpuinfo의 Hardware 필드 ) 파일 분석• init.rc , int.hardware.rc ( /proc/cpuinfo의 Hardware 필드 ) 파일 분석
on initsysclktz 0loglevel 3gexport PATH /sbin:/system/sbin:/system/bin:/system/xbinexport LD_LIBRARY_PATH /system/lib:on bootifup loifup losetrlimit 13 40 40:service console /system/bin/sh
console
service adbd /sbin/adbddisabled
:
출처 : [책] 인사이드 안드로이드
• system/core/init/readme.txt : 구조에 대한 설명• system/core/rootdir/init.rc : 기본 init.rc 파일
디바이스 노드 생성디바이스 노드 생성빌드 시 만들어 지는 루트파일 시스템에는 /d 가 존재하지 않는다• 빌드 시 만들어 지는 루트파일 시스템에는 /dev 가 존재하지 않는다.
• 콜드플러그(Cold Plug)/핫 플러그(Hot Plug)• uevent 사용 – 커널에서 사용자 공간으로의 정보 전달• /sys 의 uevent 파일 검색 -> “add” uevent 강제 발생/sys 의 uevent 파일 검색 > add uevent 강제 발생• 퍼미션 변경이 필요한 경우 소스 내에 기록된 퍼미션 적용 ( 기본 0600, root, root )
“add\n” struct uevent {
/sys/devices/mydd/uevent
struct uevent {const char *action; // "add"const char *path; const char *subsystem;
my Device Driver
const char subsystem; const char *firmware; int major; // xxint minor; // xx; //}
uevent socket// system/core/init/devices.cstatic struct perms devperms[] = {static struct perms_ devperms[] {{ "/dev/null", 0666, AID_ROOT, AID_ROOT, 0 },{ "/dev/zero", 0666, AID_ROOT, AID_ROOT, 0 },:
펌웨어 업데이트펌웨어 업데이트리눅스에서 처리되는 t ( / /bi /h t l )• 리눅스에서 처리되는 uevent ( /usr/bin/hotplug )
SUBSYSTEM=moduleDEVPATH=/module/firmware_sample_driverLD_LIBRARY_PATH=/lib:/usr/libPATH / bi /bi / / bi / /biPATH=/sbin:/bin:/usr/sbin:/usr/bin
echo 1 > /sys/$DEVPATH/loadingcat $HOTPLUG_FW_DIR/$FIRMWARE > /sys/$DEVPATH/data
$echo 0 > /sys/$DEVPATH/loading
• init 의 처리 ( 시간이 다소 걸리는 것을 고려해서 이 루틴은 별도의 프로세스(fork)로 동작한다. )// system/core/init/devices.cstatic 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 하여 다운로드 완료 알림
}
프로퍼티프로퍼티h (A d id Sh d M ) 영역• ashmem(Android 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=0ro.allow.mock.location=1ro.debuggable=1
출ro.debuggable 1persist.service.adb.enable=1
[command line] # setprop net.dns1 168.126.63.1
출처 : [책] 인사이드 안드로이드
자식 프로세스자식 프로세스i 키워드로 기술된 내용• service 키워드로 기술된 내용
• 자식 프로세스가 종료(SIGCHILD) 될 때 필요한 작업을 수행한다. ( 리소스 해제 및 재시작 )
service servicemanager /system/bin/servicemanageruser systemcriticalonrestart restart zygoteonrestart restart media
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server socket zygote stream 666socket zygote stream 666onrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart media
i b i / /bi /b i iservice bootanim /system/bin/bootanimationuser graphicsgroup graphicsdisabledoneshot
POLL 서버(메인루프)POLL 서버(메인루프)ufds[0] fd = device fd; // 디바이드의 uevent 서비스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 = POLLIN;ufds[2].events POLLIN;fd_count = 3;:for(;;) {
nr = poll(ufds, fd count, timeout);p ( , _ , );// 자식 프로세스 종료 처리 및 재 시작// 디바이스 노드 생성// 프로퍼티 변경}
출처 : [책] 인사이드 안드로이드
그외그외
기에 디렉 리 생성 및 마• 초기에 디렉토리 생성 및 마운트• stdin, stdout, stderr 를 사용 못함• “ANDROID” 글자 출력( /initlogo.rle 파일이 있으면 화면 출력 )• 리눅스의 숨겨진 기능을 활용하는 잘 짜여진 코드
logcatlogcat# logcat# logcatI/DEBUG ( 1780): debuggerd: Jun 9 2009 13:56:46E/flash_image( 1788): can't find recovery partitionI/ServiceManager( 1778): sm : startI/ServiceManager( 1778): sm : startI/Binder ( 1778): [BLEE] binder_open fd=6, mapped=0x40008000
mapsize=131072D/qemud ( 1790): main: can't find 'android.qemud=' in /proc/cmdline/q ( ) q /p /I/vold ( 1779): Android Volume Daemon version 2.0E/vold ( 1779): Unable to open '/sys/class/mmc_host' (m)D/vold ( 1779): Bootstrapping completeD/AndroidRuntime( 1782): D/AndroidRuntime( 1782): >>>>>>>>>>>>>> AndroidRuntime START
<<<<<<<<<<<<<<D/A d idR ti ( 1782) Ch kJNI i OND/AndroidRuntime( 1782): CheckJNI is ONI/ ( 1783): ServiceManager: 0xac38
JNIJNIJNI(J N ti I t f )JNI(Java Native Interface)
출처 : [책] 인사이드 안드로이드
안드로이드 JNI Application안드로이드 JNI Application
Hello.java
Hello.apk
classes.dex
resources.arsc *.xml
Hello.cpplibhello-jni.so
public native String printHello(String str);Hello.java
달빅 가상머신
so 파일 로딩 시 심볼을검색 후 동적 테이블을 생성한다.
default JNI_OnLoad(..)
jstringJava_com_example_hellojni_HelloJni_printHello( JNIEnv* env, jobject thiz, jstring srt )
Hello.cpp
NDK ( Native Development Kit ) - http://developer.android.com/sdk/ndk/index.html- Hello.cpp 컴파일 하여 hello-jni.so 생성해 준다. - so 바이너리를 생성하기 위한 툴일 뿐이며, 코드 작성 및 필요한 사항은 개발자가 해 주어야 한다.바이너리를 생성하기 위한 툴일 뿐이며, 작성 및 필 한 사항은 개발자가 해 주어야 한다
NDK 컴파일NDK 컴파일$ cd android ndk r3$ cd android-ndk-r3$ ./build/host-setup.sh$ make APP=hello-jni
New -> Project -> Android Project android-ndk-r3/apps/hello-jni/project
system server 정적 테이블system server - 정적 테이블/*
public class SystemServer{/*
* JNI registration.*/static JNINativeMethod gMethods[] = {
{native public static void init1(String[] args);}
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"return 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();
• frameworks/base/services/jni/*
system_init();}
zygotezygote달빅(D l ik) 초기화 수행• 달빅(Dalvik) 초기화 수행
• 애플리케이션 실행 속도 향상• System Server 를 실행
// init.rcservice zygote /system/bin/app_process -Xzygote /system/bin --zygote --yg / y / / pp_p yg / y / ygstart-system-server
socket zygote stream 666onrestart write /sys/android_power/request_state wakeonrestart write /sys/power/state ononrestart restart media
zygote 동작 원리zygote – 동작 원리
출처 : [책] 인사이드 안드로이드
# sh B – 리눅스에서 새로운
zygote 에서 새로운 애플리케이션 실행
리눅 에서 새 운프로세스 실행
zygote - Preload classes & ygResoures
출처 : [책] 인사이드 안드로이드
서비스서비스
출처 : [책] 인사이드 안드로이드
https://sites.google.com/site/io/anatomy--physiology-of-an-android
애플리케이션 서비스애플리케이션 서비스
로컬서비스출처 : [책] 인사이드 안드로이드
<로컬서비스>서비스의 레퍼런스를 가져온다 <리모트서비스>
AIDL(Android Interface Definition Language)를사용한 바인더 IPC사용한 바인더 IPC
http://developer.android.com/guide/developing/tools/aidl.html
시스템 서비스시스템 서비스네이티브 서비스• 네이티브 서비스
AudioFlinger – 오디오 입/출력SurfaceFlinger – 화면 출력CameraService – 카메라 입/출력CameraService 카메라 입/출력
• 코어 플랫폼 서비스Activity Manager Service – 액티비트 관리Window Manager Service – 화면 그리기 관리Package Manager Service – 패키지(apk) 관리
하드웨어 서비스• 하드웨어 서비스Alarm Manager Service – 타이머 관리Connectivity Service – 네트웍 상태 정보Location Service – 단말의 위치 정보
출처 : [책] 인사이드 안드로이드
Location Service 단말의 위치 정보Power Service – 전원 관리Sensor Service – 센서 디바이스 관리Telephony Service – 전화 서비스Wifi Service – 무선 검색, 연결 관리
Layer InteractionLayer Interaction
h fl f d d l k• There are 3 main flavors of Android layer cake:• App -> Runtime Service -> lib• App -> Runtime Service -> Native Service -> lib• App -> Runtime Service -> Native Daemon -> lib
App > Runtime Service > libApp -> Runtime Service -> lib
App > Runtime Service > Native Service > libApp -> Runtime Service -> Native Service -> lib
App > Runtime Service > Native Daemon > libApp -> Runtime Service -> Native Daemon -> lib
Media Server / System ServerMedia Server / System Server
출출처 : [책] 인사이드 안드로이드
컨텍스트 매니저컨텍스트 매니저저는 foo라네, 저한테는 서비스입니다.
네 저한테맡겨 주십
시요.
컨텍스트 매니저!
컨텍스트 매니저 서비스
컨텍 매니저foo라는 서비스를
찾습니다.
// init.rcservice servicemanager /system/bin/servicemanager
t
서비스 사용자
user systemcriticalonrestart restart zygoteonrestart restart media
서비스 서비스 사용자서비스, 서비스 사용자
바인더바인더
• IPC ( Inter Process Communication)• RPC ( Remote Procedure Call)RPC ( Remote Procedure Call)
프로세스 구분 명령 함수구분 인자
프로세스
프로세스A
프로세스B
프로세스CC
바인더 프로토콜바인더 프로토콜
출처 : [책] 인사이드 안드로이드
바인더 어드레싱 서비스 등록바인더 어드레싱 - 서비스 등록
출처 : [책] 인사이드 안드로이드
바인더 어드레싱 서비스 검색바인더 어드레싱 – 서비스 검색
출처 : [책] 인사이드 안드로이드
바인더 어드레싱 서비스 사용바인더 어드레싱 – 서비스 사용
출처 : [책] 인사이드 안드로이드
바인더 mmap 영역바인더 mmap 영역
출처 : [책] 인사이드 안드로이드
서비스 프레임워크서비스 프레임워크P St t• ProcessState
– biner open, mmap 할당• IPCThreadState
바인더 콜 처리- 바인더 프로토콜, IPC 처리• BpBinder / BBinder- 서비스 프록시 / 서비스 스텁 인터페이스 IInterface
• IInterface- 바인더 공통 부분• BpXXX / BnXXX
IFooService서비스 인터페이스
- 서비스 프록시 / 서비스 스텁
• 서비스 매니저
BpFooService서비스 프록시
BnFooService서비스 스텁
FooService- 서비스 등록, 서비스 검색
FooService서비스
서비스 프레임워크 레이어서비스 프레임워크 - 레이어
서비스 클라이언트
서비스 사용자
서비스 서버
F S i
IFooService서비스 인터페이스
IFooService서비스 인터페이스서비스
레이어
BpFooService서비스 프록시
BnFooService서비스 스텁
FooService서비스
레이어
RPC레이어
IPCThreadState
BpBinder
IPCThreadState
BBinderIPC레이어IPCThreadState IPCThreadState
바인더 드라이버
서비스 프레임워크 프록시서비스 프레임워크 - 프록시서비스 사용자
서비스 레이어
서비스 프록시
서비 사용자함수 호출 인자 전달서비스 레이어
서비스 프록시바인더 RPC 코드 바인더 RPC 데이터
BpBinder
RPC 레이어
IPCThreadState
BpBinder
IPC 레이어
서비스 핸들
바인더 프로토콜
바인더 IPC 데이터
바인더프로토콜
binder_transaction_data
handle code buffer
BC_TRANSACTION 1 바인더 RPC 코드 바인더 RPC 데이터
i l i
바인더 드라이버
ioctl write
서비스 프레임워크 스텁서비스 프레임워크 - 스텁서비스
서비스 레이어
서비스 스텁
서비함수 호출 인자 전달서비스 레이어
서비스 스텁바인더 RPC 코드 바인더 RPC 데이터
BBinder
RPC 레이어
IPCThreadState
BBinder
IPC 레이어
서비스 인스턴스
바인더 프로토콜
바인더 IPC 데이터
바인더프로토콜
binder_transaction_data
cookie code buffer
BR_TRANSACTION xxx 바인더 RPC 코드 바인더 RPC 데이터
i l d
바인더 드라이버
ioctl read
서비스 프레임워크 주요 상속서비스 프레임워크 – 주요 상속
출처 : [책] 인사이드 안드로이드출처 : [책] 인사이드 안드로이드
서비스 프레임워크 바인더 연결서비스 프레임워크 – 바인더 연결
출처 : [책] 인사이드 안드로이드
서비스 매니저서비스 매니저
출처 : [책] 인사이드 안드로이드
서비스 매니저 구조서비스 매니저 구조
출처 : [책] 인사이드 안드로이드
서비스 프레임워크 상호 동작서비스 프레임워크 상호 동작
프로세스 A 프로세스 B
프로세스 A의사용자 메모리 영역
용어1 - 바인더 RPC
프로세스 B의바인더 mmap 영역
용어1 - 바인더 RPC 데프로세스 A 프로세스 B
BpAudioFlinger(서비스 프록시)
AudioFlinger ( 서비스)
setMasterVolume(float value){
용어1 바인더 RPC 데이터
value
용어1 바인더 RPC 데이터
value
setMasterVolume(float value){바인더 RPC
{...}
{...}
서비스프레임워크
서비스프레임워크
바인더 RPC
바인더 IPC
용어2 - 바인더 IPC 데이터 용어2 - 바인더 IPC 데이터
프레임워크 프레임워크바인더 IPC
바인더프로토콜
binder_transaction_data
handle code buffer
SET_MASTER_VOLUME
바인더프로토콜
binder_transaction_data
cookie code buffer
SET_MASTER_VOLUME
바인더 드라이버ioctl ioctl
자바 서비스 프레임워크자바 서비스 프레임워크
JNI출처 : [책] 인사이드 안드로이드
네이티브 서비스 프레임워크
자바 서비스 프레임워크 특징자바 서비스 프레임워크 특징
< FooManager 랩퍼 클래스 제공 >
< 네이티브 서비스 프레임워크 재 사용>출처 : [책] 인사이드 안드로이드
자바 서비스 프레임워크 동작자바 서비스 프레임워크 동작
출처 : [책] 인사이드 안드로이드
바인더 드라이버
출처 : [책] 인사이드 안드로이드
자바 서비스 프레임워크 상호작용자바 서비스 프레임워크 상호작용
출처 : [책] 인사이드 안드로이드
Q & AQ & A