Android系统开机流程

1.系统开机流程图

系统流程图.PNG

2 Android开机各阶段

2.1 BootLoader阶段

Android 设备上电后,首先会从处理器到Rom 的启动引导代码开始执行,Rom 会找 Boot loader 的代码,并加载到内存中。这一步由“新品厂商”负责设计和实现的。

2.2 kernel 阶段

Linux 内核开始启动,初始化各种软硬件环境、加载驱动程序、挂载根文件系统、并执行 init 程序,由此开启 Android 的世界。
内核启动的执行的第一条的代码在head.S文件中,主要功能是实现压缩内核的解压和跳转到内核vmlinux内核的入口,kernel的C启动阶段可以理解为真正的启动阶段,从head.S看到,最终调用的是kernel/init/main.c的start_kernel()函数
1)start_kernel()函数中执行了大量的初始化操作:
2)setup_arch():主要做一些板级初始化,cpu初始化,tag参数解析,u-boot传递的cmdline解析,建立mmu工作页表,初始化内存布局,调用mmap_io建立GPIO、IRQ、MEMCTRL、UART,及其他外设的静态映射表,对时钟,定时器,uart进行初始化
3)sched_init():初始化每个处理器的可运行队列,设置系统初始化进程即0号进程
4)softirq_init():内核的软中断机制初始化函数
5)console_init():初始化系统的控制台结构
6)rest_init():调用kernel_thread()创建1号内核线程,调用schedule()函数切换当前进程,在调用该函数之前,Linux系统中只有两个进程,即0号进程init_task和1号进程kernel_init,其中kernel_init进程也是刚刚被创建的。调用该函数后,1号进程kernel_init将会运行

2.3 init 进程启动

init 进程时Linux 内核启动后创建的第一个用户空间进程 ,init在初始化过程中会启动很多守护进程。init进程的入口是system\core\init\init.cpp里的main函数:

int main(int argc, char** argv) {
.........
parser.ParseConfig("/init.rc");
parser.set_is_system_etc_init_loaded(
parser.ParseConfig("/system/etc/init"));
parser.set_is_vendor_etc_init_loaded(
parser.ParseConfig("/vendor/etc/init"));
parser.set_is_odm_etc_init_loaded(parser.ParseConfig("/odm/etc/init"));
.........
}

在init.cpp中,加载system\core\rootdir\init.rc 配置文件,init.rc配置文件会进行加载很多配置,创建文件夹及文件,然后初始化一些Android 驱动器。各个极端的顺序是:
on early-init --> on init --> on late-init --> on early-fs --> on post-fs --> on late-fs --> on post-fs-data(在这个时候才开始 mkdir data) --> on zygote-start --> on boot
在boot阶段会启动下面两个模块的服务

on boot
     ........
     class_start core 
     class_start hal
     .......

在android\system\core\init\builtin.c
而start_class core 具体 对应了 int do_class_start(int nargs, char **args) 方法

 int do_class_start(int nargs, char **args)
 {
    /* Starting a class does not start services
     * which are explicitly disabled.  They must
     * be started individually.
     */
    service_for_each_class(args[1], service_start_if_not_disabled);
    return 0;

 }

在android\system\core\init\init_parse.c中:

void service_for_each_class(const char *classname,
                        void (*func)(struct service *svc))
{
    struct listnode *node;
    struct service *svc;
    list_for_each(node, &service_list) {
        svc = node_to_item(node, struct service, slist);
        if (!strcmp(svc->classname, classname)) {
            func(svc);
        }
    }
}

其中 service_start_if_not_disabled 定义在builtin.c

static void service_start_if_not_disabled(struct service *svc)
{
    if (!(svc->flags & SVC_DISABLED)) {
        service_start(svc, NULL);
    } else {
        svc->flags |= SVC_DISABLED_START;
    }
}

然后就走到了到service_start()。通过class_start 来启动相关的 service 。

开机动画bootanim属于core服务,但他不是自启服务,需要由surfaceflinger服务将bootanim启动。
surfaceflinger属于core服务,自启动服务,在init进程的on boot阶段会启动surfaceflinger,surfaceflinger最后会启动StartPropertySetThread从而启动bootanim。
surfaceflinger服务的main函数入口在main_surfaceflinger,主要有:
1.启动Hidl服务,主要是DisplayService
2.启动线程池
3.初始化surfaceFlinger
4.将SurfaceFlinger和GpuService注册到ServiceManager
5.启动SurfaceFlinger线程
具体实现在frameworks/native/services/surfaceflinger/
surfaceflinger继承了Thread,执行run 方法后,本质上是调用c++ 中的pthread类,线程入口函数是ThreadLoop,ThreadLoop的含义是通过一个循环不断的调用该函数,当threadLoop返回 false的时候退出循环。
由于bootanim的threadLoop返回false,所以启动函数在开机过程中只会执行一次。

2.4 Zygote启动

在init 执行过程中,在on boot阶段,会 trigger zygote-start,on zygote-start 会根据当前的加密状态选择启动服务,在init.rc中,import zygote 的启动rc文件。
Zygote会执行一个app_process64可执行文件,这个文件调用的代码位于/frameworks/base/cmds/app_process/路径下,有一个文件app_main.cpp,入口是main 函数

你可能感兴趣的:(Android系统开机流程)