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/

Blog: www.som-itsolutions.blogspot.com


The Android system starts by starting the init after the kernel started. It then parses a file at

/system/core/rootdir/init.rc

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;