Step 1: Start Linux
1. bootloader
2. Kernel
Step 2: Start Android: the entry is init. RC (System \ core \ rootdir)
1./system/bin/Service Manager: binder daemon;
2. runtime;
3. zygote: app-process/APP-Main;
4. Start VM;
5. Start Server
6. Start Android service: Register to Service Manager
7. Start Launcher
Step 3: start the application: Run Package Manager
L init Process
When the Android system is started, it will first start the Linux system, boot the Linux kernel and start the INIT process. The INIT process is a user-level process started by the kernel and the first process in the Android system. The code for this process is in platform \ System \ core \ init. C. The main function has the following code:
Open_devnull_stdio ();
Log_init ();
Info ("reading config file \ n ");
Init_parse_config_file ("/init. RC ");
/* Pull the kernel CommandLine and ramdisk properties file in */
Import_kernel_cmdline (0 );
Get_hardware_name (hardware, & revision );
Snprintf (TMP, sizeof (TMP), "/init. % S. RC", hardware );
Init_parse_config_file (TMP );
The initialization scripts init. RC and init. Hardware. RC will be loaded here. * The RC file defines the process services to be started and actions to be executed in the INIT process. For more information, see platform \ System \ core \ init \ reademe.txt. Init. RC is defined as follows:
Service servicemanager/system/bin/servicemanager
User System
Critical
Onrestart restart zygote
Onrestart restart Media
Service vold/system/bin/vold
Socket vold stream 0660 root Mount
Ioprio be 2
Service netd/system/bin/netd
Socket netd stream 0660 Root System
Socket dnsproxyd stream 0660 root inet
Service debugadh/system/bin/debugadh
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 audio sdcard_rw
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
Onrestart restart netd
Service DRM/system/bin/drmserver
User DRM
Group system root inet
For details about the parsing process, see platform \ System \ core \ init \ init_parser.c. Add the parsed service to service_list and add the action to action_list.
Next, execute the action and start the process service in the main function:
Execute_one_command ();
Restart_processes ()
Generally, some system folders need to be created during the INIT process and the USB daemon process, Android debug bridge daemon process, debug daemon process, servicemanager process, and zygote process must be started.
L servicemanager Process
The servicemanager process is the manager of all services. According to the description of servicemanager by init. RC, The servicemanager/system/bin/servicemanager process starts from platform \ frameworks \ base \ cmd \ servicemanager \ service_manager.cpp. The main function has the following code:
Int main (INT argc, char ** argv)
{
Struct binder_state * BS;
Void * svcmgr = binder_service_manager;
BS = binder_open (128*1024 );
If (binder_become_context_manager (BS )){
LogE ("cannot become context Manager (% s) \ n", strerror (errno ));
Return-1;
}
Svcmgr_handle = svcmgr;
Binder_loop (BS, svcmgr_handler );
Return 0;
}
Call binder_open () to open the binder device (/dev/binder) and call binder_become_context_manager () to set the current process to servicemanager. Servicemanager is a service.
Int binder_become_context_manager (struct binder_state * BS)
{
Return IOCTL (BS-> FD, binder_set_context_mgr, 0 );
}
Finally, binder_loop () enters the cyclic state, and sets the svcmgr_handler callback function to wait for requests such as adding, querying, and obtaining services.
L zygote Process
Zygote processes are used to generate other processes. The description of zygote by init. RC service zygot/system/bin/app_process indicates that the zygote process starts from platfrom \ frameworks \ base \ cmds \ app_process \ app_main.cpp. The main function has the following code:
If (0 = strcmp ("-- zygote", ARG )){
Bool startsystemserver = (I <argc )?
Strcmp (argv [I], "-- start-system-server") = 0: false;
Setargv0 (argv0, "zygote ");
Set_process_name ("zygote ");
Runtime. Start ("com. Android. Internal. OS. zygoteinit ",
Startsystemserver );
} Else {
Set_process_name (argv0 );
Runtime. mclassname = ARG;
// Remainder of argS get passed to startup class main ()
Runtime. margc = argc-I;
Runtime. margv = argv + I;
Logv ("app process is starting with PID = % d, class = % S. \ n ",
Getpid (), runtime. getclassname ());
Runtime. Start ();
}
Create an appruntime, that is, androidruntime, and create a Dalvik virtual machine. This Runtime is used to pass the com. Android. Internal. OS. zygoteinit parameter, so that the Dalvik virtual machine runs main () of zygoteinit. Java and starts to create the zygote process. In its main (), It is shown as follows:
Registerzygotesocket ();
EventLog. writeevent (log_boot_progress_preload_start,
Systemclock. uptimemillis ());
Preloadclasses ();
// Cacheregistermaps ();
Preloadresources ();
EventLog. writeevent (log_boot_progress_preload_end,
Systemclock. uptimemillis ());
// Finish profiling the zygote initialization.
Samplingprofilerintegration. writezygotesnapshot ();
// Do an initial GC to clean up after startup
GC ();
// If requested, start system server directly from zygote
If (argv. length! = 2 ){
Throw new runtimeexception (argv [0] + usage_string );
}
If (argv [1]. Equals ("true ")){
Startsystemserver ();
} Else if (! Argv [1]. Equals ("false ")){
Throw new runtimeexception (argv [0] + usage_string );
}
First, register the port through registerzygotesocket (), and then load the relevant classes in preloadclasses. More than 1000 classes are loaded here. For specific loading classes, see platform \ frameworks \ base \ preloaded-classes. This file is automatically generated by the writepreloadedclassfile class. The main function of this class is analyzed. The following filtering class code is provided:
// Preload classes that were loaded by at least 2 processes. Hopefully,
// The memory associated with these classes will be shared.
For (loadedclass: Root. loadedclasses. Values ()){
Set <string> names = loadedclass. processnames ();
If (! Policy. ispreloadable (loadedclass )){
Continue;
}
If (names. Size ()> = min_processes |
(Loadedclass. mediantimemicros ()> min_load_time_micros & names. Size ()> 1 )){
Topreload. Add (loadedclass );
}
}
Int initialsize = topreload. Size ();
System. Out. println (initialsize
+ "Classses were loaded by more than one app .");
// Preload eligable classes from applications (not long-running
// Services ).
For (Proc proc: Root. processes. Values ()){
If (Proc. fromzygote ()&&! Policy. isservice (Proc. Name )){
For (Operation operation: Proc. Operations ){
Loadedclass = operation. loadedclass;
If (shouldpreload (loadedclass )){
Topreload. Add (loadedclass );
}
}
}
}
Among them, min_load_time_micros is equal to 1250. When the class loading time is greater than 1.25 mS, it needs to be preloaded.
Policy. ispreloadable () is scheduled to be as follows:
/** Reports if the given class shoshould be preloaded .*/
Public static Boolean ispreloadable (loadedclass clazz ){
Return clazz. systemclass &&! Excluded_classes.contains (clazz. Name );
}
Excluded_classes is defined as follows:
/**
* Classes which we shouldn't load from the zygote.
*/
Private Static final set <string> excluded_classes
= New hashset <string> (arrays. aslist (
// Binders
"Android. App. alarmmanager ",
"Android. App. searchmanager ",
"Android. OS. fileobserver ",
"Com. Android. server. packagemanagerservice $ appdirobserver ",
// Threads
"Android. OS. asynctask ",
"Android. Pim. contactsasynchelper ",
"Java. Lang. processmanager"
));
These binders and threads are not pre-loaded.
In addition, some applications need to be loaded, which must meet the condition Proc. fromzygote () and are not resident memory services. Services are defined as follows:
/**
* Long running services. These are restricted in their contribution to
* Preloader because their launch time is less critical.
*/
// Todo: generate this automatically from Package Manager.
Private Static final set <string> services = new hashset <string> (arrays. aslist (
"System_server ",
"Com. Google. process. Content ",
"Android. process. Media ",
"Com. Android. Bluetooth ",
"Com. Android. Calendar ",
"Com. Android. inputmethod. Latin ",
"Com. Android. Phone ",
"Com. Google. Android. Apps. Maps. friendservice", // pre froyo
"Com. Google. Android. Apps. Maps: friendservice", // froyo
"Com. Google. Android. Apps. Maps. locationfriendservice ",
"Com. Google. Android. javasclock ",
"Com. Google. process. gapps ",
"Android. TTS"
));
Preloaded-classes is generated when the source code is downloaded. The writepreloadedclassfile class is not used. However, you can use this class to understand the default requirements of the pre-loaded class in the Android system, modify the preloaded-classes file to reduce the classes to be preloaded during initialization and increase the boot speed.
Finally, start the systemserver process through startsystemserver. See the following code:
/* Hardcoded command line to start the system server */
String ARGs [] = {
& Quot; -- setuid = 1000 & quot ",
& Quot; -- setgid = 1000 & quot ",
"-- Setgroups = 1001,1002, 1003,1004, 1005,1006, 1007,1008, 1009,1010, 1018,3001, 3002,3003 ",
"-- Capabilities = 1300000352,1300000352 ",
"-- Runtime-init ",
"-- Nice-name = system_server ",
"Com. Android. server. systemserver ",
};
Zygoteconnection. Arguments parsedargs = NULL;
Int PID;
Try {
Parsedargs = new zygoteconnection. Arguments (ARGs );
/*
* Enable debugging of the system process if * either * the command line flags
* Indicate it shoshould be debuggable or the Ro. debuggable system property
* Is set to "1"
*/
Int debugflags = parsedargs. debugflags;
If ("1". Equals (systemproperties. Get ("Ro. debuggable ")))
Debugflags | = zygote. debug_enable_debugger;
/* Request to fork the system server process */
PID = zygote. forksystemserver (
Parsedargs. uid, parsedargs. GID,
Parsedargs. gids, debugflags, null,
Parsedargs. permittedcapabilities,
Parsedargs. effectivecapabilities)
Zygote encapsulates Linux fork. Forksystemserver () calls forkandspecialize (), and finally calls dalvik_dalvik_system_zygote.c in platform \ Dalvik \ VM \ native \ dalvik_system_zygote_forkandspecialize () through the Virtual Machine (). The new fork process is completed by Dalvik.
Main () will call runselectloopmode () to enter the while loop, and the peers will create a new process.
L systemservice Process
Systemservice is used to create all services other than the services defined by init. RC. The following code is available at the end of main:
// The system server has to run all of the time, so it needs to be
// As efficient as possible with its memory usage.
Vmruntime. getruntime (). settargetheaputilization (0.8f );
System. loadlibrary ("android_servers ");
Init1 (ARGs );
Init1 () is implemented in the native space and is used to start the service in the native space. In fact, android_server_systemserver.cpp in com_android_server_systemserver_init1 ():
Static void android_server_systemserver_init1 (jnienv * ENV, jobject clazz)
{
System_init ();
}
The system_init () Service initializes various services at the native layer:
// Start the sensor Service
Sensorservice: instantiate ();
// On the simulator, audioflinger et al don't get started
// Same way as on the device, and we need to start them here
If (! Proc-> supportsprocesses ()){
// Start the audioflinger
Audioflinger: instantiate ();
// Start the media playback Service
Mediaplayerservice: instantiate ();
// Start the camera service
Cameraservice: instantiate ();
// Start the audio Policy Service
Audiopolicyservice: instantiate ();
}
Finally, use the following code:
Logi ("system server: Starting Android services. \ n ");
Runtime-> callstatic ("com/Android/Server/systemserver", "init2 ");
Return to systemserver. Java and call init2 ():
Public static final void init2 (){
Slog. I (TAG, "entered the Android system server! ");
Thread thr = new serverthread ();
Thr. setname ("android. server. serverthread ");
Thr. Start ();
}
Init2 starts a thread specifically used to start all services in the Java space. Run the following code to start some services:
Slog. I (TAG, "Content Manager ");
Contentservice. Main (context,
Factorytest = systemserver. factory_test_low_level );
Slog. I (TAG, "system content providers ");
Activitymanagerservice. installsystemproviders ();
Slog. I (TAG, "battery service ");
Battery = new batteryservice (context );
Servicemanager. addservice ("battery", battery );
Slog. I (TAG, "Lights service ");
Lights = new lightsservice (context );
Slog. I (TAG, "vibrator service ");
Servicemanager. addservice ("vibrator", new vibratorservice (context ));
// Only initialize the Power Service after we have started
// Lights service, content providers and the battery service.
Power. INIT (context, lights, activitymanagerservice. getdefault (), battery );
Slog. I (TAG, "alarm manager ");
Alarmmanagerservice alarm = new alarmmanagerservice (context );
Servicemanager. addservice (context. alarm_service, alarm );
Add these services to servicemanager for management and inter-process communication.
In the second half of the thread, activitymanagerservice waits for systemready, such as appwidget, wallpaper, and IMM, to call its own systemready ().
(Activitymanagerservice) servicemanager. getservice ("activity "))
. Setwindowmanager (WM );
// Skip Bluetooth if we have an emulator Kernel
// Todo: Use a more reliable check to see if this product shocould
// Support Bluetooth-See Bug 988521
If (systemproperties. Get ("Ro. kernel. qemu"). Equals ("1 ")){
Slog. I (TAG, "registering null Bluetooth service (emulator )");
Servicemanager. addservice (effecthadapter. effecth_service, null );
} Else if (factorytest = systemserver. factory_test_low_level ){
Slog. I (TAG, "registering null Bluetooth service (factory test )");
Servicemanager. addservice (effecthadapter. effecth_service, null );
} Else {
Slog. I (TAG, "Bluetooth service ");
Bluetooth = new incluthservice (context );
Servicemanager. addservice (fig. Fig, Bluetooth );
Bluetooth. initafterregistration ();
Export tha2dp = new export tha2dpservice (context, Bluetooth );
Servicemanager. addservice (fig. Fig _ service,
Bluetootha2dp );
Int contentthon = settings. Secure. getint (mcontentresolver,
Settings. Secure. Fig, 0 );
If (cmdthon> 0 ){
Bluetooth. Enable ();
}
}
The following code is executed at the end of systemready () of activitymanagerservice:
Mmainstack. resumetopactivitylocked (null );
Because the activity management stack is empty, launcher is started.
// Find the first activity that is not finishing.
Activityrecord next = toprunningactivitylocked (null );
// Remember how we'll process this pause/resume situation, and ensure
// That the state is reset however we wind up proceeding.
Final Boolean userleaving = muserleaving;
Muserleaving = false;
If (next = NULL ){
// There are no more activities! Let's just start up
// Launcher...
If (mmainstack ){
Return mservice. starthomeactivitylocked ();
}
}
Create an intent with category_home in starthomeactivitylocked (), and launch the corresponding activity, that is, launcher.
Intent intent = new intent (
Mtopaction,
Mtopdata! = NULL? Uri. parse (mtopdata): NULL );
Intent. setcomponent (mtopcomponent );
If (mfactorytest! = Systemserver. factory_test_low_level ){
Intent. addcategory (intent. category_home );
}
In this way, the android system starts up and enters the standby interface.