您的位置:首页 > 移动开发 > Android开发

android启动过程详细讲解

2013-08-12 15:22 260 查看
安卓启动过程
1.当从关机状态开始正常启动时,第一步会执行bootloader,它是从地址0x00开始执行的一段程序,他负责初始化软件运行是所需的最小硬件环境,最后将内核加载进内存中
2.内核加载进内存后,将首先进入内核引导阶段,在引导阶段的最后将会调用start_kernel函数进入内核启动状态,start_kernel函数在最后将会启动用户空间的init程序
3.init:
1)init进程是一个由内核启动的用户级进程,是android系统的第一个进程,进程号为1,是所有进程的父进程
2)init的相关代码在System\system\core\init\init.c下
3)解析init.c的main函数重要部分

open_devnull_stdio();//重定向标准输出,输入和出错到null
klog_init();//设置init的日志输出设备为kmeg
property_init();//初始化属性系统所需空间
get_hardware_name(hardware,&revision);//获取硬件信息
process_kernel_cmdline();//处理内核命令行
#ifdef HAVE_SELINUX//安全相关的一些措施
INFO("loadingselinux policy\n");
selinux_load_policy();
#endif
is_charger= !strcmp(bootmode, "charger");//是否在充电模式下
INFO("propertyinit\n");
if(!is_charger)//不在充电模式下,调用函数设置默认属性
property_load_boot_defaults();
INFO("readingconfig file\n");
init_parse_config_file("/init.rc");//!!!很重要的一部分,解析init.rc文件

4)经过上面的初始化后和触发action后开始进入无限循环状态,执行command,处理事件
5)bootchart是一个性能统计工具,用于搜集系统和硬件信息,并写入磁盘,以便其他程序使用
6)init.c的main函数的具体功能可以分为4个部分:
初始化文件系统和日志系统,为之后的执行阶段做准备;
解析init.rc和init.<hardware>.rc初始化文件;
触发需要执行的Action和Service;
          Init用一个无限循环开始监听事件
4.init.rc文件
1)init.rc的文件格式是有android初始化语言定义,有六个基本概念(Section,Action,Service,Trigger,Command,Option),两个基本关键字(on,service)和多个指令关键字
2)init.rc就是由不同的Section组成的
5.init解析完init.rc后,生成了存放Service和Action的链表,接着执行action_for_each_trigger和queue_builtin_action函数触发Action,接着再使用execute_one_command函数执行action,execute_one_command函数做了两部分工作:取命令和执行命令的func函数。这里的func便是command结构体中的成员函数func,函数代码为:
cmd->func= kw_func(kw);
接下来定位kw_func:
#definekw_func(kw) (keyword_info[kw].func)
这是一个宏定义,需要找到key_word_info的定义。他在init_parser.c中,代码主要定义了所有的Command对应的执行函数,执行Command就是执行这些函数,接着在init.rc文件中,每个aciton对应的Command都能在key_word_info中找到对应,在找到的对应函数中会找到service_start函数,使用service_start函数启动Service(状态不为SVC_DISABLED的Service启动)。init是把service当作一个进程,用command启动,这样所有的service便是init的子进程了,这些由init启动的service为守护进程服务(如ueventd,servicemanager,vold,zygote...),两个最重要的守护进程是zygote和servicemanager,前者是android启动的第一个Dalvik虚拟机,他负责启动java世界的进程,后者是binder通信的基础(注:zygote并不是由init直接启动的,而是app_process将最重要的工作交给了AppRuntime类的start方法去完成,在start方法中调用ZygoteInit类的main方法启动zygote)。
6.init中除了解析init.rc中配置的action和service外,还处理了一些内置的action,这些工作由queue_builtin_action函数完成,进行属性服务的相关操作,定位init.c中的main函数到属性服务相关代码:
property_init();
...
INFO("propertyinit\n");
if(!is_charger)
property_load_boot_defaults();

//触发属性服务相关的action
queue_builtin_action(property_service_init_action,"property_service_init");

queue_builtin_action(queue_property_triggers_action,"queue_property_triggers");
7.init循环监听处理事件,init触发所有action后,就开始进入无限循环,定位代码:
for(;;){
intnr, i, timeout = -1;
execute_one_command();//启动action和service
restart_processes();//重启action和service
if(!property_set_fd_init && get_property_set_fd() > 0){//分别调用3个函数监听3个fd
ufds[fd_count].fd= get_property_set_fd();
ufds[fd_count].events= POLLIN;
ufds[fd_count].revents= 0;
fd_count++;
property_set_fd_init= 1;
}
if(!signal_fd_init && get_signal_fd() > 0) {
ufds[fd_count].fd= get_signal_fd();
ufds[fd_count].events= POLLIN;
ufds[fd_count].revents= 0;
fd_count++;
signal_fd_init= 1;
}

if(!keychord_fd_init && get_keychord_fd() > 0) {
ufds[fd_count].fd= get_keychord_fd();
ufds[fd_count].events= POLLIN;
ufds[fd_count].revents= 0;
fd_count++;
keychord_fd_init= 1;
}

if(process_needs_restart) {
timeout= (process_needs_restart - gettime()) * 1000;
if(timeout < 0)
timeout= 0;
}

if(!action_queue_empty() || cur_action)
timeout= 0;
#ifBOOTCHART
if(bootchart_count > 0) {
if(timeout < 0 || timeout > BOOTCHART_POLLING_MS)
timeout= BOOTCHART_POLLING_MS;
if(bootchart_step() < 0 || --bootchart_count == 0) {
bootchart_finish();
bootchart_count= 0;
}
}
#endif
nr= poll(ufds, fd_count, timeout);
if(nr <= 0)
continue;
for(i = 0; i < fd_count; i++) {
if(ufds[i].revents == POLLIN) {
if(ufds[i].fd == get_property_set_fd())
handle_property_set_fd();
elseif (ufds[i].fd == get_keychord_fd())
handle_keychord();
elseif (ufds[i].fd == get_signal_fd())
handle_signal();
}
}
}
8.init启动的守护进程中有两个很重要的进程,分别是zygote和servicemanager,zygote是android世界的第一个dalvik虚拟机,所有其他的dalvik虚拟机进程都是通过zygote
fork出来的。这有一点很重要,android应用程序是由java语言编写的,运行于各自独立的dalvik中,如果每个应用程序在启动之时都要单独运行和初始化一个虚拟机,会大大降低系统性能,因此android首先创建一个zygote虚拟机,然后通过他复制出其他的虚拟机进程,共享资源,大大提升程序启动和运行速度

9.接着zygote定义和注册了一个Socket,用于接受ActivityManagerService启动应用程序的请求,这个socket的fd由zygote启动时传入,利用Socket通讯,接收ActivityManangerService的请求,fork应用程序。注册完socket,便进行class资源和resourse资源的预加载

10.zygote通过fork系统调用创建system_server进程,系统在预加载了共享资源后,便开始启动system_server进程,android中所有系统服务都由该进程启动,它的异常退出将导致zygote异常退出,定位代码(ZygoteInit.java文件中):

privatestatic boolean startSystemServer()
throwsMethodAndArgsCaller, RuntimeException {
/*Hardcoded command line to start the system server */
Stringargs[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,3001,3002,3003,3006,3007",
"--capabilities=130104352,130104352",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer",
};

ZygoteConnection.ArgumentsparsedArgs = null;
intpid;
try{
parsedArgs= new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/*Request to fork the system server process */
pid= Zygote.forkSystemServer(
parsedArgs.uid,parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
}catch (IllegalArgumentException ex) {
thrownew RuntimeException(ex);
}
/*For child process */
if(pid == 0) {
handleSystemServerProcess(parsedArgs);
}
returntrue;
}
第一步是通过forkSystemServer创建system_server子进程
该方法内部将会调用Native方法nativeForkSystemServer完成启动system_server进程的任务,而且系统会检查system_server是否启动成功,如启动失败,则需重启
第二步是通过在子进程中调用handleSystemServerProcess方法
这样就fork出了system_server这个进程
11.在system_server进程的init1和init2阶段分别启动nativesystem
service和javasystemservice,SystemService在main函数中主要做的工作是申请更多的内存、加载android_servers库、执行init1。在init1阶段主要完成的工作:
启动核心系统服务SurfaceFlinger和SensorService,二者都是NativeSystem
Service
通过AndroidRuntime调用Java层Systemserver的init2方法
初始化Binder通信
在init2里面,init2启动了一个名为android.server.ServerThread的线程。然后系统服务启动后会注册到ServerManager中,用于Binder通信,而且ActivityManagerService进入systemReady状态
12.接着zygote执行最后一部工作:执行runSelectLoopMode方法。在startSystemServer成功后,便进入一个无限循环,在systemReady状态下通过前面第9步创建的socket与客户端ActivityManagerService进行通信,请求启动home,Zygote收到ActivitymanagerService的连接请求,执行runSelectLoopMode的runOnce处理请求。Zygote处理请求会通过frokAndSpecialize启动新的应用进程,并最终启动home,定位代码:
publicvoid systemReady(final Runnable goingCallback) {
    ……
    //readycallback
if(goingCallback != null)
goingCallback.run();
synchronized(this) {
//Start up initial activity.
//ActivityStack mMainStack;
mMainStack.resumeTopActivityLocked(null);
}
……
}

finalboolean resumeTopActivityLocked(ActivityRecord prev)
{
  //Find
the first activity that is not finishing.
  ActivityRecordnext
= topRunningActivityLocked(null);
  if(next
== null) {
    //There
are no more activities! Let's just start up the
    //Launcher...
    if(mMainStack)
{
      //ActivityManagerServicemService;
      returnmService.startHomeActivityLocked();
    }
  }
  ……
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android
相关文章推荐