Android启动流程

学习- Android启动流程

Bootloader(配置启动Linux)---> 加载 kernel (内核) --> 创建init进程

--> init进程启动 system/core/init/init.cpp 代码 -->

{
init.cpp ---> LoadBootScripts()---> parser.ParseConfig(bootscript)
}
aosp/system/core/init/parser.h

{
加载 system/core/rootdir/init.rc 配置 ---> trigger zygote-start

import /init.${ro.zygote}.rc
查看架构得出 执行文件是 init.zygote64_32.rc
adb shell getprop | findstr ro.zygote --> 得到 init.zygote64_32.rc

执行
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary

--zygote 创建 zygote进程
-start-system-server
--socket-name=zygote 创建zygote名字的socket

1.3、调用system/core/init/service.cpp # Service::start 函数创建zygote进程和/system/core/init/util.cpp # create_socket函数创建名为zygote 的socket

但它们进程的可执行文件都是app_process,对应的源码在/frameworks/base/cmds/app_process/app_main.cpp。

}
---> app_main.cpp执行文件-->

{
argv[0] --zygote
AppRuntime runtime(argv[0], computeArgBlockSize(argc, argv));
runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
}
--->
AppRuntime runtime

{

// 判断system-server 是否启动
static const String8 startSystemServer("start-system-server");

/*
 * 'startSystemServer == true' means runtime is obsolete and not run from
 * init.rc anymore, so we print out the boot start event here.
 */
for (size_t i = 0; i < options.size(); ++i) {
    if (options[i] == startSystemServer) {
       /* track our progress through the boot sequence */
       const int LOG_BOOT_PROGRESS_START = 3000;
       LOG_EVENT_LONG(LOG_BOOT_PROGRESS_START,  ns2ms(systemTime(SYSTEM_TIME_MONOTONIC)));
    }
}
// 创建目录
const char* rootDir = getenv("ANDROID_ROOT");
if (rootDir == NULL) {
    rootDir = "/system";
    if (!hasDir("/system")) {
        LOG_FATAL("No root directory specified, and /android does not exist.");
        return;
    }
    setenv("ANDROID_ROOT", rootDir, 1);
}

//const char* kernelHack = getenv("LD_ASSUME_KERNEL");
//ALOGD("Found LD_ASSUME_KERNEL='%s'\n", kernelHack);

/* start the virtual machine */
JniInvocation jni_invocation;
jni_invocation.Init(NULL);
JNIEnv* env;
if (startVm(&mJavaVM, &env, zygote) != 0) {
    return;
}
//创建虚拟机
onVmCreated(env);

/*
 * Register android functions.
 */
if (startReg(env) < 0) {
    ALOGE("Unable to register all android natives\n");
    return;
}

/*
 * We want to call main() with a String array with arguments in it.
 * At present we have two arguments, the class name and an option string.
 * Create an array to hold them.
 */
jclass stringClass;
jobjectArray strArray;
jstring classNameStr;

stringClass = env->FindClass("java/lang/String");
assert(stringClass != NULL);
strArray = env->NewObjectArray(options.size() + 1, stringClass, NULL);
assert(strArray != NULL);
// className = com.android.internal.os.ZygoteInit
classNameStr = env->NewStringUTF(className);
assert(classNameStr != NULL);
env->SetObjectArrayElement(strArray, 0, classNameStr);

for (size_t i = 0; i < options.size(); ++i) {
    jstring optionsStr = env->NewStringUTF(options.itemAt(i).string());
    assert(optionsStr != NULL);
    env->SetObjectArrayElement(strArray, i + 1, optionsStr);
}


// 开启虚拟机

/*
 * Start VM.  This thread becomes the main thread of the VM, and will
 * not return until the VM exits.
 */
char* slashClassName = toSlashClassName(className != NULL ? className : "");
jclass startClass = env->FindClass(slashClassName);
if (startClass == NULL) {
    ALOGE("JavaVM unable to locate class '%s'\n", slashClassName);
    /* keep going */
} else {
    jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
        "([Ljava/lang/String;)V");
    if (startMeth == NULL) {
        ALOGE("JavaVM unable to find main() in '%s'\n", className);
        /* keep going */
    } else {
    // 将zygote 的初始化传递到zygoteInit  运行到了com.android.internal.os.ZygoteInit 的main方法
        env->CallStaticVoidMethod(startClass, startMeth, strArray);

if 0

        if (env->ExceptionCheck())
            threadExitUncaughtException(env);

endif

    }
}
free(slashClassName);

}

---> ZygoteInit.java main方法

{

fork system-server 进程
Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.runtimeFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);

String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,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",
};

2: 配置system-server
forkSystemServer(abiList, socketName, zygoteServer);-->Zygote.forkSystemServer()(fork system-server 进程) -->handleSystemServerProcess()

--> RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader);-- findStaticMain(args.startClass, args.startArgs, classLoader);
调用 SystemServer main 方法 处理 system _server 进程

}

1: 上电 启动Bootloader

内核世界
BootLoader:引导加载程序 BootLoader启动Linux系统 是上电后在操作系统执行前的第一段代码.

作用:
1:初始化硬件设备
2:加载操作系统内核
3:加载内存空间映射图

Android 基于linux系统  在这个系统中内核加载和启动是由BootLoader完成的

BootLoader  加载 kernel  -- init进程
idle 是linux的第一个进程 init是Linux的第一个用户进程

idle进程 pid=0 init pid=1  
idle 是init_task退化而来 是Linux系统的第一个进程 是唯一一个没通过fork和kernel_thread产生的进程.
init_task 是Linux内核中所有进程的雏形


idle进程是通过汇编实现的是init和kthread的父进程   执行 start_kernel 加载操作系统内核   调用 rest_init进程和kthreadd进程 进入linux进程


start_kernel 调用rest_init函数 开始了linux的进程

BootLoader --->  start_kernel  --> rest_init  --> init进程 (开启了linux进程)

2:进入Linux世界

init 执行到了 system/core/init/init.cpp代码

    main--->  LoadBootScripts(am, sm);-->  parser.ParseConfig("/init.rc"); 启动zygote
    
init.rc  system/core/rootdir/init.rc    

        import /init.${ro.zygote}.rc
        adb shell getprop | findstr ro.zygote  --> 得到 init.zygote64_32.rc

        /system/core/rootdir/init.zygote64_32.rc
        
        ---> 
        service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
        
        
        service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
        
        文件位置
        /frameworks/base/cmds/app_process/app_main.cpp
        
        到service 指令时就会相应地调用system/core/init/service.cpp   启动服务调用到 service.cpp 
        
        system/core/init/service.cpp # Service::start   函数创建zygote进程和/system/core/init/util.cpp # create_socket函数创建名为zygote 的socket
        
        app_main.cpp  代码  创建 AndroidRuntime.cpp
        \frameworks\base\core\jni\AndroidRuntime.cpp
            
             runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
             runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
             
        //jni调用传入的className 即 com.android.internal.os.ZygoteInit的main函数
        env->CallStaticVoidMethod(startClass, startMeth, strArray);

/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java

ZygoteInit.java main--> ZygoteServer ZygoteServer 是Zygote进程的Socket通讯服务端的管理类
ZygoteHooks.startZygoteNoThreadCreation(); 启动 zygote

init 进程 启动流程  BootLoader  --> kernel---> 启动init进程
         
    BootLoader --->  start_kernel  --> rest_init  --> init进程 (开启了linux进程)    
         
         
init.cpp---> init.rc--->    /system/core/rootdir/init.zygote64_32.rc  通过Server.cpp 启动了Zygote进程   

    然后执行
    
    /frameworks/base/cmds/app_process/app_main.cpp
    
    main{
    AndroidRuntime.cpp
      runtime.start("com.android.internal.os.ZygoteInit", args, zygote);
      runtime.start("com.android.internal.os.RuntimeInit", args, zygote);
      
     jmethodID startMeth = env->GetStaticMethodID(startClass, "main",
        "([Ljava/lang/String;)V");
    if (startMeth == NULL) {
        ALOGE("JavaVM unable to find main() in '%s'\n", className);
        /* keep going */
    } else {
        env->CallStaticVoidMethod(startClass, startMeth, strArray);
    }
         
    // 启动到了  java ZygoteInit.java  的main 方法 来到了java世界    

java世界

ZygoteInit
fork system-server 进程
String socketName = "zygote";
String abiList = null;
boolean enableLazyPreload = false;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if ("--enable-lazy-preload".equals(argv[i])) {
enableLazyPreload = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}

    Runnable r = forkSystemServer(abiList, socketName, zygoteServer);        
         
                pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.runtimeFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
         

         String args[] = {
        "--setuid=1000",
        "--setgid=1000",
        "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,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",   //className
    };
    
    
    fork进程
    
          pid = Zygote.forkSystemServer(
                parsedArgs.uid, parsedArgs.gid,
                parsedArgs.gids,
                parsedArgs.runtimeFlags,
                null,
                parsedArgs.permittedCapabilities,
                parsedArgs.effectiveCapabilities);
    
        完成fok进程后操作
         handleSystemServerProcess(parsedArgs)
         
         ZygoteInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl)--->RuntimeInit.applicationInit(targetSdkVersion, argv, classLoader)
         -->findStaticMain(args.startClass, args.startArgs, classLoader)
         
         --通过反射 调用 SystemServer main方法
         
         
         最后回到  ZygoteInit
         
            Runnable r = forkSystemServer(abiList, socketName, zygoteServer);

            // {@code r == null} in the parent (zygote) process, and {@code r != null} in the
            // child (system_server) process.
            if (r != null) {
                r.run();
                return;
            }
         
          zygoteServer.runSelectLoop(abiList);
          --> if (i == 0) {
                ZygoteConnection newPeer = acceptCommandPeer(abiList);
                peers.add(newPeer);
                fds.add(newPeer.getFileDesciptor());
            }
            -->
        //创建Socket
private ZygoteConnection acceptCommandPeer(String abiList) {
    try {
        return createNewConnection(mServerSocket.accept(), abiList);
    } catch (IOException ex) {
        throw new RuntimeException(
                "IOException during accept()", ex);
    }
}
            

         
启动了SystemServer


        1:处理默认语言 城市
       if (!SystemProperties.get("persist.sys.language").isEmpty()) {
            final String languageTag = Locale.getDefault().toLanguageTag();

            SystemProperties.set("persist.sys.locale", languageTag);
            SystemProperties.set("persist.sys.language", "");
            SystemProperties.set("persist.sys.country", "");
            SystemProperties.set("persist.sys.localevar", "");
        }
        2:初始化MainLooper
        
                        android.os.Process.setThreadPriority(
            android.os.Process.THREAD_PRIORITY_FOREGROUND);
        android.os.Process.setCanSelfBackground(false);
        Looper.prepareMainLooper();
        Looper.getMainLooper().setSlowLogThresholdMs(
                SLOW_DISPATCH_THRESHOLD_MS, SLOW_DELIVERY_THRESHOLD_MS);

        3:创建系统的 Context
            createSystemContext()
            
              private void createSystemContext() {
              创建系统的 Context  初始化 ActivityThread  
                    ActivityThread activityThread = ActivityThread.systemMain();
                    mSystemContext = activityThread.getSystemContext();
                    mSystemContext.setTheme(DEFAULT_SYSTEM_THEME);
                    设置 主题
                    final Context systemUiContext = activityThread.getSystemUiContext();
                    systemUiContext.setTheme(DEFAULT_SYSTEM_THEME);
                }
                
        ActivityThread 
                 systemMain(){
                 
                         // The system process on low-memory devices do not get to use hardware
                            // accelerated drawing, since this can add too much overhead to the
                        // process.
                    if (!ActivityManager.isHighEndGfx()) {
                        ThreadedRenderer.disable(true);
                    } else {
                        ThreadedRenderer.enableForegroundTrimming();
                    }
                        // 创建 Instrumentation Application  
                        ActivityThread thread = new ActivityThread();
                        thread.attach(true, 0);
                 }
        4:创建 SystemServiceManager 系统服务管理类  管理系统服务(SystemService)的生命周期
        
        
        5:启动服务
        --->
        startBootstrapServices();
                Installer:安装器
                DeviceIdentifiersPolicyService: 设备标识符 的服务
                ActivityManagerService : 主要负责Android中四大组件的启动、通信、部分生命周期的管理等等
                PowerManagerService :上电服务管理
                StartRecoverySystemService 恢复设置服务\
                StartLightsService: 背光亮度服务
                DisplayManagerService: 显示器服务
                PackageManagerService: 包管理服务
        --->        
        startCoreServices();
                BatteryService: 电池服务
                WebViewUpdateService
                BinderCallsStatsService
        --->        
        startOtherServices();
        NetworkManagementService 网络服务
        TelephonyRegistry 电话
        AlarmManagerService 通知
        WindowManagerService Window管理服务
        
        --->            
        启动Luancher
           mActivityManagerService.systemReady(() -> {
            //在接收到这个引导阶段之后,服务可以广播Intents
             mSystemServiceManager.startBootPhase(
                SystemService.PHASE_ACTIVITY_MANAGER_READY);
                // SYSTEMUI   启动了
            startSystemUi(context, windowManagerF);
            //启动看门狗
                  Watchdog.getInstance().start();
            // 三方程序可以启动了
            mSystemServiceManager.startBootPhase(
                SystemService.PHASE_THIRD_PARTY_APPS_CAN_START);
            
           }
           
           ActivityManagerService   mActivityManagerService.systemReady(() -> {}
           
    
           systemReady(final Runnable goingCallback, TimingsTraceLog traceLog) {
             startHomeActivityLocked(currentUserId, "systemReady");
           }
            
            
            
            
        ...

bootloader 加载 init.cpp

init.cpp :/system/core/init/init.cpp 挂载 init.rc

init.rc /system/core/rootdir/init.rc ---> trigger zygote-start zygote 启动

BootLoader---> linux内核 加载各种驱动 --->加载init.rc(加载配置文件)

--->

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,378评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,356评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,702评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,259评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,263评论 5 371
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,036评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,349评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,979评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,469评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,938评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,059评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,703评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,257评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,262评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,485评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,501评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,792评论 2 345

推荐阅读更多精彩内容