SOM-ITSOLUTIONS |
Android |
Android boot-up process (4.0.4) |
SOMENATH MUKHOPADHYAY |
som-itsolutions #A2 1/13 South Purbachal Hospital Road Kolkata 700078 Mob: +91 9748185282 Email: som@som-itsolutions.com / som.mukhopadhyay@gmail.com Website: http://www.som-itsolutions.com/ |
The Android system starts by starting the init after the kernel started. It then parses a file at
The rc file is a script file defined by Android. It contains Action and Services. After few initialization activities like creating Log services, creating File System, initializing memory management, USB accessory configuration, charger management it goes on to initialize the services.
If we look at the service section of the .rc file we will find these these are the services the init process starts.
## Daemon processes to be run by init.
341##
342service ueventd /sbin/ueventd
343 class core
344 critical
345
346service console /system/bin/sh
347 class core
348 console
349 disabled
350 user shell
351 group log
352
353on property:ro.debuggable=1
354 start console
355
356# adbd is controlled via property triggers in init.<platform>.usb.rc
357service adbd /sbin/adbd
358 class core
359 disabled
360
361# adbd on at boot in emulator
362on property:ro.kernel.qemu=1
363 start adbd
364
365# This property trigger has added to imitiate the previous behavior of "adb root".
366# The adb gadget driver used to reset the USB bus when the adbd daemon exited,
367# and the host side adb relied on this behavior to force it to reconnect with the
368# new adbd instance after init relaunches it. So now we force the USB bus to reset
369# here when adbd sets the service.adb.root property to 1. We also restart adbd here
370# rather than waiting for init to notice its death and restarting it so the timing
371# of USB resetting and adb restarting more closely matches the previous behavior.
372on property:service.adb.root=1
373 write /sys/class/android_usb/android0/enable 0
374 restart adbd
375 write /sys/class/android_usb/android0/enable 1
376
377service servicemanager /system/bin/servicemanager
378 class core
379 user system
380 group system
381 critical
382 onrestart restart zygote
383 onrestart restart media
384 onrestart restart surfaceflinger
385 onrestart restart drm
386
387service vold /system/bin/vold
388 class core
389 socket vold stream 0660 root mount
390 ioprio be 2
391
392service netd /system/bin/netd
393 class main
394 socket netd stream 0660 root system
395 socket dnsproxyd stream 0660 root inet
396
397service debuggerd /system/bin/debuggerd
398 class main
399
400service ril-daemon /system/bin/rild
401 class main
402 socket rild stream 660 root radio
403 socket rild-debug stream 660 radio system
404 user root
405 group radio cache inet misc audio sdcard_rw log
406
407service surfaceflinger /system/bin/surfaceflinger
408 class main
409 user system
410 group graphics
411 onrestart restart zygote
412
413service zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server
414 class main
415 socket zygote stream 666
416 onrestart write /sys/android_power/request_state wake
417 onrestart write /sys/power/state on
418 onrestart restart media
419 onrestart restart netd
420
421service drm /system/bin/drmserver
422 class main
423 user drm
424 group system inet drmrpc
425
426service media /system/bin/mediaserver
427 class main
428 user media
429 group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc
430 ioprio rt 4
431
432service bootanim /system/bin/bootanimation
433 class main
434 user graphics
435 group graphics
436 disabled
437 oneshot
438
439service dbus /system/bin/dbus-daemon --system --nofork
440 class main
441 socket dbus stream 660 bluetooth bluetooth
442 user bluetooth
443 group bluetooth net_bt_admin
444
445service bluetoothd /system/bin/bluetoothd -n
446 class main
447 socket bluetooth stream 660 bluetooth bluetooth
448 socket dbus_bluetooth stream 660 bluetooth bluetooth
449 # init.rc does not yet support applying capabilities, so run as root and
450 # let bluetoothd drop uid to bluetooth with the right linux capabilities
451 group bluetooth net_bt_admin misc
452 disabled
453
454service installd /system/bin/installd
455 class main
456 socket installd stream 600 system system
457
458service flash_recovery /system/etc/install-recovery.sh
459 class main
460 oneshot
461
462service racoon /system/bin/racoon
463 class main
464 socket racoon stream 600 system system
465 # IKE uses UDP port 500. Racoon will setuid to vpn after binding the port.
466 group vpn net_admin inet
467 disabled
468 oneshot
469
470service mtpd /system/bin/mtpd
471 class main
472 socket mtpd stream 600 system system
473 user vpn
474 group vpn net_admin inet net_raw
475 disabled
476 oneshot
477
478service keystore /system/bin/keystore /data/misc/keystore
479 class main
480 user keystore
481 group keystore
482 socket keystore stream 666
483
484service dumpstate /system/bin/dumpstate -s
485 class main
486 socket dumpstate stream 0660 shell log
487 disabled
488 oneshot
Look at the first comment of this code which says ## Daemon processes to be run by init.
So as we find out from the above code the ServiceManager is started by the init process after starting console and adbd services. The zygote service actually initiates the System Server. The media service initiates the media-server.
So for our part of interests the service manager, system-server, media server come in active state during this init process.
Among many things the zygote spawns a new Dalvik instance.
Now let me delve into how the Android services come into picture.
Look into the file /frameworks/base/services/java/com/android/server/SystemServer.java
I have taken a snapshot from this file and shown it below:
/**
772 * This method is called from Zygote to initialize the system. This will cause the native
773 * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
774 * up into init2() to start the Android services.
775 */
776 native public static void init1(String[] args);
777
778 public static void main(String[] args) {
779 if (System.currentTimeMillis() < EARLIEST_SUPPORTED_TIME) {
780 // If a device's clock is before 1970 (before 0), a lot of
781 // APIs crash dealing with negative numbers, notably
782 // java.io.File#setLastModified, so instead we fake it and
783 // hope that time from cell towers or NTP fixes it
784 // shortly.
785 Slog.w(TAG, "System clock is before 1970; setting to 1970.");
786 SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
787 }
788
789 if (SamplingProfilerIntegration.isEnabled()) {
790 SamplingProfilerIntegration.start();
791 timer = new Timer();
792 timer.schedule(new TimerTask() {
793 @Override
794 public void run() {
795 SamplingProfilerIntegration.writeSnapshot("system_server", null);
796 }
797 }, SNAPSHOT_INTERVAL, SNAPSHOT_INTERVAL);
798 }
799
800 // Mmmmmm... more memory!
801 dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
802
803 // The system server has to run all of the time, so it needs to be
804 // as efficient as possible with its memory usage.
805 VMRuntime.getRuntime().setTargetHeapUtilization(0.8f);
806
807 System.loadLibrary("android_servers");
808 init1(args);
809 }
Look at line 807 and 808. It first loads a native library called system_servers. It basically gives an interface to the native functions. It then call the native function init1.
The function that implements this resides in /frameworks/base/cmds/system_server/library/system_init.cpp and it looks like the following.
extern "C" status_t system_init()
55{
56 LOGI("Entered system_init()");
57
58 sp<ProcessState> proc(ProcessState::self());
59
60 sp<IServiceManager> sm = defaultServiceManager();
61 LOGI("ServiceManager: %p\n", sm.get());
62
63 sp<GrimReaper> grim = new GrimReaper();
64 sm->asBinder()->linkToDeath(grim, grim.get(), 0);
65
66 char propBuf[PROPERTY_VALUE_MAX];
67 property_get("system_init.startsurfaceflinger", propBuf, "1");
68 if (strcmp(propBuf, "1") == 0) {
69 // Start the SurfaceFlinger
70 SurfaceFlinger::instantiate();
71 }
72
73 property_get("system_init.startsensorservice", propBuf, "1");
74 if (strcmp(propBuf, "1") == 0) {
75 // Start the sensor service
76 SensorService::instantiate();
77 }
78
79 // And now start the Android runtime. We have to do this bit
80 // of nastiness because the Android runtime initialization requires
81 // some of the core system services to already be started.
82 // All other servers should just start the Android runtime at
83 // the beginning of their processes's main(), before calling
84 // the init function.
85 LOGI("System server: starting Android runtime.\n");
86 AndroidRuntime* runtime = AndroidRuntime::getRuntime();
87
88 LOGI("System server: starting Android services.\n");
89 JNIEnv* env = runtime->getJNIEnv();
90 if (env == NULL) {
91 return UNKNOWN_ERROR;
92 }
93 jclass clazz = env->FindClass("com/android/server/SystemServer");
94 if (clazz == NULL) {
95 return UNKNOWN_ERROR;
96 }
97 jmethodID methodId = env->GetStaticMethodID(clazz, "init2", "()V");
98 if (methodId == NULL) {
99 return UNKNOWN_ERROR;
100 }
101 env->CallStaticVoidMethod(clazz, methodId);
102
103 LOGI("System server: entering thread pool.\n");
104 ProcessState::self()->startThreadPool();
105 IPCThreadState::self()->joinThreadPool();
106 LOGI("System server: exiting thread pool.\n");
107
108 return NO_ERROR;
109}
As you can see it first start the native services like surface flinger and sensor_service.
Then towards the end we call init2 via env->CallStaticVoidMethod(clazz, methodId);
This init2 method has been defined as
public static final void init2() {
812 Slog.i(TAG, "Entered the Android system server!");
813 Thread thr = new ServerThread();
814 thr.setName("android.server.ServerThread");
815 thr.start();
816 }
So it starts the ServerTheread which creates all other system_services. You may have a look at the run() of ServerThraed at /frameworks/base/services/java/com/android/server/SystemServer.java.
So the salient point of this discussions vis-a-vis Android services are as follows;