안드로이드는 리눅스 커널을 이용한다. 따라서 리눅스의 시작 시퀀스 이후에 안드로이드 고유 시스템이 동작하게 된다.
기본적인 동작을 잘 설명한 곳( http://samse.tistory.com/
|
리눅스는 기본적으로 init이 가장먼저 실행된다. init.rc 라는 이름의 파일에는 init이 해야할 작업들이 기록되어 있다. 파일시스템 마운팅, 폴더 권한설정, 캐시폴더 삭제, 시작프로그램 동작 등이 기록되어 있다. 우선 데몬을 올린다. 데몬은 init에 의해 리눅스와 같이 시작되었다가 리눅스가 종료될 때 없어지는 프로그램으로서 데몬을 작성하는 규격에 따라 만들어져야 한다. Zygote가 Dalvik을 초기화 한다. C 밑에 있는 기본라이브러리들은 런타임을 통해 실행되고 상위 서비스들은 Dalvik을 통해 실행된다. 이러한 과정들을 위한 설정은 해당하는 config 파일을 수정하면 된다. 어떤 동작들을 바꾸고 싶으면 기본적으로 init.rc를 바꾸면 되고 Zygote를 바꾸고 싶으면 그 설정파일을 바꾸면 된다. 그리고 시스템서버, 서페이스매니저, 오디오매니저들이 올라간다. 그 다음에는 시스템 서비스들이 활성화 된다. 이들은 서비스이므로 서비스매니저에 등록된다.
init은 /system/core/init 디렉토리에 관련 소스가 있다. init.rc 파일은 /system/core/rootdir/에 있다.
init이 하는 일과 init.rc 파일을 작성하는 방법에 대해서는 여기( http://www.aesop.or.kr/?
init이 하는 일을 정리하면 다음과 같다.
1. log system 초기화
2. /init.rc와 /init.%hardware$.rc 파일 파싱
3. 2번 스텝의 2개 파일에서 초기 선동작(early-init action) 수행
4. 디바이스 종속적인 초기화 작업 (예를 들어 /dev 에 모든 디바이스 노드 만듬)
5. property system 초기화 (property system은 공유 메모리로 동작하며 윈도우의 레지스트리와 같은 역활이다)
6. 2번 스텝의 2개 파일에서 초기 동작(init action) 수행
7. property service 시작
8. 2번 스텝의 2개 파일에서 선부팅(early boot), 부팅(boot) 동작 수행
9. 2번 스텝의 2개 파일에서 property 동작 수행
10. device/property가 /child process를 셋할때까지 대기하면서 rc 파일에 정의된 명령어를 수행한다.
위의 설명처럼 /out/target/product/XXX/init.
Demon을 올리는 작업을 하도록 되어 있다. 이를 정리하면 다음과 같다.
1) console : shell 을 시작 (system/core/sh/)
## Daemon processes to be run by init.
##
service console /system/bin/sh
console
2) abdb : abdb daemon을 시작 (system/core/adb/)
# adbd on at boot in emulator
on property:ro.kernel.qemu=1
start adbd
on property:persist.service.adb.
start adbd
on property:persist.service.adb.
stop adbd
3) servicemanager : binder system을 시작 (framework/base/cmds/
service servicemanager /system/bin/servicemanager
user system
critical
onrestart restart zygote
onrestart restart media
4) vold : volume daemon 시작 (system/core/vold/)
socket vold stream 0660 root mount
#service mountd /system/bin/mountd
# socket mountd stream 0660 root mount
5) debuggerd : debug system을 시작 (system/debuggerd/)
service debuggerd /system/bin/debuggerd
6) rild : radio interface layer daemon을 시작 (hardware/ril/rild/)
service ril-daemon /system/bin/rild
socket rild stream 660 root radio
socket rild-debug stream 660 radio system
user root
group radio cache inet misc
7) Zygote : (frameworks/base/cmds/app_
service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
socket zygote stream 666
onrestart write /sys/android_power/request_
onrestart write /sys/power/state on
8) media : AudioFlinger, MediaPlayerService, CameraService를 시작 (frameworks/base/media/
service media /system/bin/mediaserver
user media
group system audio camera graphics inet net_bt net_bt_admin
관련 코드를 보면 굉장히 간단하다. (framework/base/media/
int main(int argc, char** argv)
{
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p", sm.get());
AudioFlinger::instantiate();
MediaPlayerService::
CameraService::instantiate();
ProcessState::self()->
IPCThreadState::self()->
}
9) bootsound : boot sound (system/media/audio/ui/boot.
service bootsound /system/bin/playmp3
user media
group audio
oneshot
10) dbus : dbus daemon 시작 (BlueZ 즉 Bluetooth 관련 서비스) (external/dbus/bus/)
service dbus /system/bin/dbus-daemon --system --nofork
socket dbus stream 660 bluetooth bluetooth
user bluetooth
group bluetooth net_bt_admin
11) hcid : hcid의 stdout, stdin을 안드로이드 logging sytstem으로 redirect (external/bluez/hcid/)
service hcid /system/bin/hcid -s -n -f /etc/bluez/hcid.conf
socket bluetooth stream 660 bluetooth bluetooth
socket dbus_bluetooth stream 660 bluetooth bluetooth
# init.rc does not yet support applying capabilities, so run as root and
# let hcid drop uid to bluetooth with the right linux capabilities
group bluetooth net_bt_admin misc
disabled
12) hfag : Bluetooth handsfree audio gateway 시작 (BlueZ 만 사용) (external/bluez/utils/tools/)
user bluetooth
group bluetooth net_bt_admin
disabled
oneshot
13) hsag : Bluetooth headset audio gateway 시작 (BlueZ 만 사용) (external/bluez/utils/tools/)
user bluetooth
group bluetooth net_bt_admin
disabled
oneshot
14) install : install package daemon 시작 (frameworks/cmds/installd/)
service installd /system/bin/installd
socket installd stream 600 system system
15) flash_recovery : /system/recovery.img를 로드 (bootable/recovery/mtdutils/)
service flash_recovery /system/bin/flash_image recovery /system/recovery.img
oneshot
강조한 것처럼 바와 같이 servicemanager을 이용해서 zygote와 media를 시작하고 SD 카드와 USB의 mount 등을 처리하는 vold 데몬을 올린다. 이후 부팅 사운드를 재생하거나 다른 필요한 데몬들을 올리게 된다. 이후 다시 강조한 부분을 보면 zygote를 이용해서 system server 를 시작한다. 이후 media를 다시 시작한다(?)
안드로이드의 system server는 Native Service와 여러가지 기본 서비스(core system service 라고도 한다)들로 이루어진다.
/framework/base/cmds/system_
extern "C" status_t system_init()
{
LOGI("Entered system_init()");
sp<ProcessState> proc(ProcessState::self());
sp<IServiceManager> sm = defaultServiceManager();
LOGI("ServiceManager: %p\n", sm.get());
sp<GrimReaper> grim = new GrimReaper();
sm->asBinder()->linkToDeath(
char propBuf[PROPERTY_VALUE_MAX];
property_get("system_init.
if (strcmp(propBuf, "1") == 0) {
// Start the SurfaceFlinger
SurfaceFlinger::
// On the simulator, audioflinger et al don't get started the
// same way as on the device, and we need to start them here
if (!proc->supportsProcesses()) {
// Start the AudioFlinger
AudioFlinger::
// Start the media playback service
MediaPlayerService::
// Start the camera service
CameraService::
}
// And now start the Android runtime. We have to do this bit
// of nastiness because the Android runtime initialization requires
// some of the core system services to already be started.
// All other servers should just start the Android runtime at
// the beginning of their processes's main(), before calling
// the init function.
LOGI("System server: starting Android runtime.\n");
AndroidRuntime* runtime = AndroidRuntime::getRuntime();
LOGI("System server: starting Android services.\n");
runtime->callStatic("com/
// If running in our own process, just go into the thread
// pool. Otherwise, call the initialization finished
// func to let this process continue its initilization.
if (proc->supportsProcesses()) {
LOGI("System server: entering thread pool.\n");
ProcessState::self()->
IPCThreadState::self()->
LOGI("System server: exiting thread pool.\n");
}
return NO_ERROR;
}
코드를 보면 알겠지만 크게 다음 순서로 초기화 과정이 이루어진다.
1. Native Service 초기화
SurfaceFlinger
AudioFlinger
MediaPlayerService
CameraService
2. Android RunTime 시작
SystemServer
안드로이드가 동작하기 위한 여러가지 기본 서비스들(또는 JAVA 서비스)을 시작하는 곳이 SystemServer이다.
파일 위치는 다음과 같다.
/frameworks/base/services/
SystemServer 클래스는 init2() 함수를 호출하게되면 ServerThread를 동작시키고 여기에서 다양한 서비스들을 시작한다.
서비스 시작하는 순서대로 대충 정리하면 다음과 같다.(run 함수의 내용을 그냥 정리한 것이며 * 표시 없는 것은 주서비스이고 * 표시 있는 것은 부가 서비스이다)
Power Manager 시작
Activity Manager 생성
ActivityManager를 생성해서 context를 받으면 이후 서비스들에는 context를 전달한다.
(아직 이 구조는 잘 모르겠지만 서비스들에서 설정이나 특정 이벤트들을 브로드 캐스팅하기 위해서는 context를 이용해야 하는 것 같다. ActivityManger에서 이를 위한 초기화 과정이 이루어지고 이후 서비스들은 context를 가지고 서로간의 통신이나 Focus 이동이 생길 수 있도록 하고 있는 것 같다. 이것은 아직은 어디까지나 추측이다.)
Telephony Registry 시작
Package Manager 시작
System Process로 Activity Manager 설정
Context Manager 시작
System Context Providers 시작
Battery Service 시작
* Hardware Service 시작
Alarm Manager 시작
Sensor Service 시작
Window Manager 시작
Bluetooth Service 시작
BluetoothDeviceService
BluetoothA2dpService
*Status Bar Service 시작
ClipboardService
InputMethodManagerService
*NetStat Service 시작
*Connectivity Service 시작
*Notification Manager 시작
Mount Service 시작
*DeviceStorageMonitor Service 시작
*Location Manager 시작
*SearchManager Service 시작
*Clipboard Service 시작
*Fallback Checkin Service 시작
*WallpaperService 시작
*Audio Service 시작
*Headset Observer 시작
(?)AppWidgetService
*AdbSettingsObserver 시작
(?)HDMISettingsObserver 시작
'old > Basic' 카테고리의 다른 글
zygote & Dalvik VM (0) | 2010.07.06 |
---|---|
안드로이드 HAL - RIL(Radio Interface Layer) (0) | 2010.07.06 |
The Froyo Code Drop (0) | 2010.07.06 |
Parcelable Object 2 (0) | 2010.07.06 |
Parcelable Object 1 (0) | 2010.07.06 |