0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

Android Zygote启动流程

哆啦安全 来源:程序员Android 2023-07-10 14:27 次阅读

Android系统包含netd、servicemanager、surfaceflinger、zygote、media、installd、bootanimation等基本服务,具体作用请看下图。

ae4569de-1d25-11ee-962d-dac502259ad0.jpg

Android 系统基本服务

二、虚拟机创建和第一个Java 程序引导

为了让APK在不同的虚拟机都可以运行,Google采取了适配器模式,在让虚拟机运行之前先执行dexopt,即将dex文件优化成odex文件,可以让虚拟机更加优化的执行。

在ART虚拟机中,dexopt将dex文件优化成二进制格式的问题,从而可以让ART虚拟机执行。dexopt会调用dex2oat进行优化,dex2oat的任务是将原来的dex文件进行预翻译,从而可以加快app运行的时间,但是由于某些app比较复杂,所以优化的时间就比较长。
优化是以dex文件中的Method方法为单位,dex2oat在优化时候,会根据需求优化一定量的Method,即不是所有的Method都回翻译成oat模式。

ae636254-1d25-11ee-962d-dac502259ad0.jpg

虚拟机创建和第一个Java 程序引导

三、Dalvik 虚拟机基本配置

在Android系统中,Dalvik虚拟机 和ART、应用程序进程,以及运行系统的关键服务SystemServer进程都是由Zygote进程创建孵化的。

1.Dalvik 虚拟机基本配置

ae7a69c2-1d25-11ee-962d-dac502259ad0.jpg

Dalvik 虚拟机基本配置

四、Zygote 启动流程

1.Zygote 启动代码

Zygote服务时通过init.rc进程启动的,Zygote的classname为main.
init.rc文件配置代码如下:

... ... 
on nonencrypted
    class_start main
    class_start late_start

on property:sys.init_log_level=*
    loglevel ${sys.init_log_level}

... ...

详细可以参考init.rc启动分析。
Android init 启动流程

2.Zygote main 函数

app_main.cpp是Zygote进程的main函数,frameworksasecmdsapp_processapp_main.cpp

Zygote是由init.rc脚本启动,在init脚本中,我们可以看到会导入import /init.${ro.zygote}.rc脚本

# Copyright (C) 2012 The Android Open Source Project
#
# IMPORTANT: Do not create world writable files or directories.
# This is a common source of Android security bugs.
#

import /init.environ.rc
import /init.usb.rc
import /init.${ro.hardware}.rc
import /vendor/etc/init/hw/init.${ro.hardware}.rc
import /init.usb.configfs.rc
... ...
import /init.${ro.zygote}.rc

... ...

在system/core/rootdir目录下,会根据ro.zygote属性值不同,启动不同的脚本,主要包含以下四个zygote脚本。

1.init.zygote32.rc 支持32为系统

2.init.zygote32_64.rc

3.init.zygote64.rc

4.init.zygote64_32.rc

ae9918b8-1d25-11ee-962d-dac502259ad0.jpg

init.zygte.rc脚本

aeb63e3e-1d25-11ee-962d-dac502259ad0.jpg

Zygote 启动流程

五、Zygote 启动分析

aeda2010-1d25-11ee-962d-dac502259ad0.jpg

Zygote 启动分析

六、Zygote 创建system_server主要方法

af0f1dba-1d25-11ee-962d-dac502259ad0.jpg

Zygote 创建system_server主要方法

七、Zygote 创建System_server 分析

af25fce2-1d25-11ee-962d-dac502259ad0.jpg

Zygote 创建System_server

八、Zygote 创建应用

af37ce72-1d25-11ee-962d-dac502259ad0.jpg

Zygote 创建应用

九、Zygote 创建应用流程

af625b56-1d25-11ee-962d-dac502259ad0.jpg

Zygote 创建应用流程

十、Zygote 预加载资源

af7fd0dc-1d25-11ee-962d-dac502259ad0.jpg

Zygote 预加载资源

afa5b4f0-1d25-11ee-962d-dac502259ad0.jpg

preloadClasses()

afbb346a-1d25-11ee-962d-dac502259ad0.jpg

preloadResources()

十一、Zygote 预加载的目的

afd7eb14-1d25-11ee-962d-dac502259ad0.jpg

Zygote 预加载的目的

十二、优化Zygote 启动方法:线程池

1.Zygote 启动优化

1:加载类和资源是可重入操作,所以在并行模式下,不存在互斥的场景

2:Android提供了Executors和ExecutorService多线程类,因此可以使用多线程来加载类和资源。

3:硬件平台最好是多核,否则加速也不明显;

aff8972e-1d25-11ee-962d-dac502259ad0.jpg

线程池 优化Zygote 启动

2.Zygote 启动优化实质

使我们的进程最大限度的抢占CPU

十三、fork SystemServer

经过一系列初始化后,在ZygoteInit类中forkSystemServer,为启动SystemServer做准备。ZygoteInit.java代码路径如下:alpsframeworksasecorejavacomandroidinternalosygoteInit.java

    /**
     * Prepare the arguments and forks for the system server process.
     *
     * Returns an {@code Runnable} that provides an entrypoint into system_server code in the
     * child process, and {@code null} in the parent.
     */
    private static Runnable forkSystemServer(String abiList, String socketName,
            ZygoteServer zygoteServer) {
        long capabilities = posixCapabilitiesAsBits(
            OsConstants.CAP_IPC_LOCK,
            OsConstants.CAP_KILL,
            OsConstants.CAP_NET_ADMIN,
            OsConstants.CAP_NET_BIND_SERVICE,
            OsConstants.CAP_NET_BROADCAST,
            OsConstants.CAP_NET_RAW,
            OsConstants.CAP_SYS_MODULE,
            OsConstants.CAP_SYS_NICE,
            OsConstants.CAP_SYS_PTRACE,
            OsConstants.CAP_SYS_TIME,
            OsConstants.CAP_SYS_TTY_CONFIG,
            OsConstants.CAP_WAKE_ALARM,
            OsConstants.CAP_BLOCK_SUSPEND
        );
        /* Containers run without some capabilities, so drop any caps that are not available. */
        StructCapUserHeader header = new StructCapUserHeader(
                OsConstants._LINUX_CAPABILITY_VERSION_3, 0);
        StructCapUserData[] data;
        try {
            data = Os.capget(header);
        } catch (ErrnoException ex) {
            throw new RuntimeException("Failed to capget()", ex);
        }
        capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);

        /* Hardcoded command line to start the system server */
        String args[] = {
            "--setuid=1000",
            "--setgid=1000",
            /// M: [Wi-Fi Hotspot Manager] system_server add dhcp (1014) group to access
            /// "/data/misc/dhcp/dnsmasq.leases"
            "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1014,1018,1021,1023," +
                        "1024,1032,1065,3001,3002,3003,3006,3007,3009,3010",
            "--capabilities=" + capabilities + "," + capabilities,
            "--nice-name=system_server",
            "--runtime-args",
            "--target-sdk-version=" + VMRuntime.SDK_VERSION_CUR_DEVELOPMENT,
            "com.android.server.SystemServer",
        };
        ZygoteConnection.Arguments parsedArgs = null;

        int pid;

        try {
            parsedArgs = new ZygoteConnection.Arguments(args);
            ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
            ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);

            boolean profileSystemServer = SystemProperties.getBoolean(
                    "dalvik.vm.profilesystemserver", false);
            if (profileSystemServer) {
                parsedArgs.runtimeFlags |= Zygote.PROFILE_SYSTEM_SERVER;
            }

            /* Request to fork the system server process */
            pid = Zygote.forkSystemServer(
                    parsedArgs.uid, parsedArgs.gid,
                    parsedArgs.gids,
                    parsedArgs.runtimeFlags,
                    null,
                    parsedArgs.permittedCapabilities,
                    parsedArgs.effectiveCapabilities);
        } catch (IllegalArgumentException ex) {
            throw new RuntimeException(ex);
        }

        /* For child process */
        if (pid == 0) {
            if (hasSecondZygote(abiList)) {
                waitForSecondaryZygote(socketName);
            }

            zygoteServer.closeServerSocket();
            return handleSystemServerProcess(parsedArgs);
        }

        return null;
    }

审核编辑:汤梓红

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • Android
    +关注

    关注

    12

    文章

    3851

    浏览量

    125651
  • JAVA
    +关注

    关注

    19

    文章

    2904

    浏览量

    103001
  • 应用程序
    +关注

    关注

    37

    文章

    3136

    浏览量

    56412
  • 虚拟机
    +关注

    关注

    1

    文章

    855

    浏览量

    27382
  • ART
    ART
    +关注

    关注

    0

    文章

    25

    浏览量

    10427

原文标题:十三、fork SystemServer

文章出处:【微信号:哆啦安全,微信公众号:哆啦安全】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    关于ok6410 android 自己编译的源码不启动问题

    关于ok6410 android 自己编译的源码不启动问题最近发现很多用户在自己编译android系统,启动android过程中出现如下
    发表于 01-14 14:39

    关于ok6410 android 自己编译的源码不启动问题

    关于ok6410 android 自己编译的源码不启动问题最近发现很多朋友在自己编译android系统,启动android过程中出现如下
    发表于 01-16 10:42

    [资料分享]+Android框架揭秘

    :通过启动程序了解android框架的概要,移植android以及如何开发适合各种机器的应用程序,分析android框架所需的基础知识,jni(java native interfac
    发表于 09-26 09:47

    安卓底层开发学习经验第十五期

    ``这一期我们来学习一下Android的一些基本的服务与Zygote启动首先我们来看一下在init脚本中配置的一些服务我们的服务包括netd服务,它主要做的是网络管理,第二个是比较
    发表于 10-13 15:44

    芯灵思开发板安卓底层开发资料十五

    ,兼容性最差下面我们来看一下我们Zygote的一个启动流程首先,我们会调用AndroidRuntime的方法去创建一个虚拟机和我们JNI的环境变量,在这个环境变量中会设置一些相关的函数
    发表于 10-13 16:30

    Android程序的执行流程分析

    《大话企业级Android应用开发实战》这是一本能够让你学出幸福感并在还没有学完时就能够胜任Android应用软件工程师工作的书。本书所有的内容都是基于企业内部的Android实际开发需要和问题而著。本节为
    发表于 07-11 08:02

    疯壳Android嵌入式Linux平板开发教程4-1Linux引导过程

    /su_fHnaDyD1o.jspLinux引导过程Linux内核与Android系统linux内核有什么区别?什么是引导装载程序?什么是Zygote?什么是init.rc?什么是系统服务?第一节Android
    发表于 02-19 14:36

    关于Android系统启动的理解

    虽然第2章Android系统启动看得比较晕,但还是想把一些总结性的内容做个笔记,加深自己对Android系统启动的理解。1. init进程启动
    发表于 07-28 07:05

    Android系统启动流程总结

    Android系统是如何启动的?Android系统的启动过程是怎样的?
    发表于 10-22 07:14

    【嵌入式开发教程1】手把手教你做平板电脑-Linux 引导过程

    会为不同的应用分配不同的内存。但如果 Android 系统为每一个应用启动不同的 Dalvik 虚拟机实例,就会消耗大量的内存以及时间。因此,为了克服这个问题,Android 系统创造了”Zy
    发表于 05-31 15:21

    【嵌入式开发教程1】疯壳·平板电脑-Linux 引导过程

    会为不同的应用分配不同的内存。但如果 Android 系统为每一个应用启动不同的 Dalvik 虚拟机实例,就会消耗大量的内存以及时间。因此,为了克服这个问题,Android 系统创造了”Zy
    发表于 07-18 17:06

    【开发教程1】手把手教你做平板电脑-Linux 引导过程

    会为不同的应用分配不同的内存。但如果 Android 系统为每一个应用启动不同的 Dalvik 虚拟机实例,就会消耗大量的内存以及时间。因此,为了克服这个问题,Android 系统创造了”Zy
    发表于 08-04 18:55

    基于Android系统自启动程序设计

    Android是在移动设备上执行应用程序的环境,自启动应用程序会给用户带来便利。通过对Android的系统架构与启动流程分析,结合具体编程,
    发表于 12-12 19:20 5次下载

    AURIX™ TC3xx启动流程详解

    本文首先介绍整个启动流程的概况,接着分别介绍了firmware启动流程,boot mode的配置,以及用户程序启动
    的头像 发表于 06-06 10:31 2343次阅读
    AURIX™ TC3xx<b class='flag-5'>启动</b><b class='flag-5'>流程</b>详解

    Android安全机制介绍及实践

    Android系统运行于Linux内核之上,init进程是用户空间启动的第一个进程,职责主要为fork出系统关键进(Daemons)、servicemanager、zygote等;提供属性服务管理系统属性等。
    的头像 发表于 11-14 09:35 275次阅读
    <b class='flag-5'>Android</b>安全机制介绍及实践