Tiny4412 Android 启动流程

来源:互联网 发布:网络自由度排名 编辑:程序博客网 时间:2024/06/11 13:28

Tiny4412 Android 启动流程

Android系统的启动主要包括三个阶段:

①BootLoader启动

②Linux Kernel启动

③Android系统启动

前面我们大致分析了前面两个步骤,即u-boot和内核的启动流程(内核启动流程待完善-_-!!),这次就来分析以下Linux内核启动之后是怎样挂载起Android这个“根文件系统”的。Android系统在Linux内核上运行了一系列的系统服务。

和Linux系统类似,Android系统中第一个被启动的进程也是init进程,它的PID为0。Android系统的init进程启动的过程中会解析init.rc文件,以此来构建出系统的初始运行形态。其他Android系统服务,比如装载Android的文件系统、创建系统目录、初始化属性系统、启动Android系统重要的守护进程,这些进程包括USB守护进程,adb守护进程,vold守护进程,rild守护进程、mediaserver和ServiceManager等,大多都是在这个脚本中被相继启动的。

init进程启动后会执行system/core/init/init.c 中的 main 函数,并且在main函数中调用init_parse_config_file函数来解析init.rc脚本。下面就分析以下这个main函数究竟做了那些事。

复制代码
//  system/core/init/init.cint main(int argc, char **argv){    ....    //对umask进行清零    umask(0);    //为rootfs建立必要的文件夹,并挂载适当的分区    mkdir("/dev", 0755);    mkdir("/proc", 0755);    mkdir("/sys", 0755);    mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");    mkdir("/dev/pts", 0755);    mkdir("/dev/socket", 0755);    mount("devpts", "/dev/pts", "devpts", 0, NULL);    mount("proc", "/proc", "proc", 0, NULL);    mount("sysfs", "/sys", "sysfs", 0, NULL);        /* indicate that booting is in progress to background fw loaders, etc */    close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000));    //调用dup函数把标准输入,输出,错误输出都重定位到/dev/__null__    open_devnull_stdio();    //初始化kernel log,创建/dev/kmsg设备节点    klog_init();    //属性初始化,读取default.prop    property_init();    //获取硬件信息/proc/cpuinfo    get_hardware_name(hardware, &revision);    //获取命linux内核传来命令行信息    process_kernel_cmdline();    union selinux_callback cb;    cb.func_log = log_callback;    selinux_set_callback(SELINUX_CB_LOG, cb);    cb.func_audit = audit_callback;    selinux_set_callback(SELINUX_CB_AUDIT, cb);    selinux_initialize();    /* These directories were necessarily created before initial policy load     * and therefore need their security context restored to the proper value.     * This must happen before /dev is populated by ueventd.     */    restorecon("/dev");    restorecon("/dev/socket");    restorecon("/dev/__properties__");    restorecon_recursive("/sys");    is_charger = !strcmp(bootmode, "charger");    INFO("property init\n");    property_load_boot_defaults();    INFO("reading config file\n");    ///解析init.rc脚本    init_parse_config_file("/init.rc");    //执行rc文件中触发器为 on early-init的语句    action_for_each_trigger("early-init", action_add_queue_tail);     /*         解析完init.rc配置文件后,会得到一系列的Action,action_for_each_trigger函数用来执行early-init阶段的Action。         init将动作执行的时间划分为4个阶段:early-init、init、early-boot、boot。由于有些动作必须要在其他动作完成后才能执行,        所以就有了先后之分。哪些动作属于哪个阶段由配置文件决定。     */      queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");    queue_builtin_action(keychord_init_action, "keychord_init");    queue_builtin_action(console_init_action, "console_init");     // 执行init阶段的动作    /* execute all the boot actions to get us started */    action_for_each_trigger("init", action_add_queue_tail);    /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random     * wasn't ready immediately after wait_for_coldboot_done     */    queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng");    queue_builtin_action(property_service_init_action, "property_service_init");    queue_builtin_action(signal_init_action, "signal_init");    /* Don't mount filesystems or start core system services if in charger mode. */    if (is_charger) {        action_for_each_trigger("charger", action_add_queue_tail);    } else {        action_for_each_trigger("late-init", action_add_queue_tail);    }    /* run all property triggers based on current state of the properties */    queue_builtin_action(queue_property_triggers_action, "queue_property_triggers");#if BOOTCHART    queue_builtin_action(bootchart_init_action, "bootchart_init");#endif    // 无限循环,用来处理各种消息      for(;;) {        int nr, i, timeout = -1;        execute_one_command();        // 重启那些已经死去的进程,启动所有init脚本中声明的service        restart_processes();        // 用来监听属性设置服务的事件        if (!property_set_fd_init && get_property_set_fd() > 0) {            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;#if BOOTCHART        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();                else if (ufds[i].fd == get_keychord_fd())                    handle_keychord();                else if (ufds[i].fd == get_signal_fd())                    handle_signal();            }        }    }    return 0;}
复制代码

在 restart_processes 函数中回去解析init.rc中的Service标号,启动Service

复制代码
//system/core/init/init.cstatic void restart_processes()        {    process_needs_restart = 0;    //调用service_for_each_flags    service_for_each_flags(SVC_RESTARTING,                           restart_service_if_needed);}
复制代码

在restart_processes调用了 service_for_each_flags

复制代码
// system/core/init/init_parser.cvoid service_for_each_flags(unsigned matchflags,                                    void (*func)(struct service *svc)){    struct listnode *node;    struct service *svc;    //遍历service_list链表里的每一个节点    list_for_each(node, &service_list) {        svc = node_to_item(node, struct service, slist);        if (svc->flags & matchflags) {            //调用传进来的func函数处理svc            func(svc);        }    }   }
复制代码

所以最终我们是调用了 restart_service_if_needed 来处理 SVC_RESTARTING链表里的每一个service节点。看一下这个restart_service_if_needed函数

复制代码
static void restart_service_if_needed(struct service *svc){    time_t next_start_time = svc->time_started + 5;     if (next_start_time <= gettime()) {                         svc->flags &= (~SVC_RESTARTING);        //启动service        service_start(svc, NULL);        return;    }        if ((next_start_time < process_needs_restart) ||        (process_needs_restart == 0)) {        process_needs_restart = next_start_time;    }    }
复制代码

接着分析一下这个service_start函数

复制代码
//   system/core/init/init.cvoid service_start(struct service *svc, const char *dynamic_args){    ....     NOTICE("starting '%s'\n", svc->name);    //创建一个子线程,启动service     pid = fork();     ....}
复制代码

init.rc语法

以行尾单位,以空格间隔的语法,以#开始代表注释行。rc文件主要包含Action、Service、Command、Options,其中对于Action和Service的名称都是唯一的,对于重复的命名视为无效。在android 5.0.2源码system/core/init/readme.txt中有init.rc语法的帮助文档。

①Action(动作)

Action: 通过trigger,即以 on开头的语句,决定何时执行相应的service。

on early-init; 在初始化早期阶段触发;

on init; 在初始化阶段触发;

on late-init; 在初始化晚期阶段触发;

on boot/charger: 当系统启动/充电时触发,还包含其他情况,此处不一一列举;

on property:<key>=<value>: 当属性值满足条件时触发;

 

②Commands(命令)

下面列举常用的命令

class_start <service_class_name>: 启动属于同一个class的所有服务;

start <service_name>: 启动指定的服务,若已启动则跳过;

stop <service_name>: 停止正在运行的服务;

setprop <name> <value>:设置属性值;

mkdir <path>:创建指定目录;

symlink <target> <sym_link>: 创建连接到<target>的<sym_link>符号链接;

write <path> <string>: 向文件path中写入字符串;

exec: fork并执行,会阻塞init进程直到程序完毕;

exprot <name> <name>:设定环境变量;

loglevel <level>:设置log级别;

 

③Service(服务)

服务Service,以 service开头,由init进程启动,一般运行于另外一个init的子进程,所以启动service前需要判断对应的可执行文件是否存在。init生成的子进程,定义在rc文件,其中每一个service,在启动时会通过fork方式生成子进程。

例如: service servicemanager /system/bin/servicemanager代表的是服务名为servicemanager,服务的路径,也就是服务执行操作时运行/system/bin/servicemanager。

 

④Options(选项)

Options是Services的可选项,与service配合使用

disabled: 不随class自动启动,只有根据service名才启动;

oneshot: service退出后不再重启;

user/group: 设置执行服务的用户/用户组,默认都是root;

class:设置所属的类名,当所属类启动/退出时,服务也启动/停止,默认为default;

onrestart:当服务重启时执行相应命令;

socket: 创建名为/dev/socket/<name>的socket

critical: 在规定时间内该service不断重启,则系统会重启并进入恢复模式

default: 意味着disabled=false,oneshot=false,critical=false。

所有的Service里面只有servicemanager ,zygote ,surfaceflinger这3个service有onrestart关键字来触发其他service启动过程。

系统启动流程

本地系统服务:在init.rc初始化一个server入口,然后通过这个server去启动其他service,比如mediaserver

Java系统服务启动:

 1):init启动service manager,这个进程主要负责系统服务的注册管理,包括“java系统服务”“本地系统服务”

 2):init启动Media server,这个进程负责启动C/C++的“本地系统服务”。

 3):init启动Zygote,这个进程启动System server进程,这个进程启动"Java系统服务"---[包括power manager    service,sensor service]

 4):另外init启动system/bin下面的各种守护进程

首先看一下init.rc里面是如何启动这些系统服务的

复制代码
## Daemon processes to be run by init.##service ueventd /sbin/ueventd    class core    critical    seclabel u:r:ueventd:s0service logd /system/bin/logd    class core    socket logd stream 0666 logd logd    socket logdr seqpacket 0666 logd logd    socket logdw dgram 0222 logd logd    seclabel u:r:logd:s0service healthd /sbin/healthd    class core    critical    seclabel u:r:healthd:s0service console /system/bin/sh    class core    console    disabled    user shell    group shell log    seclabel u:r:shell:s0on property:ro.debuggable=1    start console# adbd is controlled via property triggers in init.<platform>.usb.rcservice adbd /sbin/adbd --root_seclabel=u:r:su:s0    class core    socket adbd stream 660 system system    disabled    seclabel u:r:adbd:s0# adbd on at boot in emulatoron property:ro.kernel.qemu=1    start adbdservice lmkd /system/bin/lmkd    class core    critical    socket lmkd seqpacket 0660 system systemservice servicemanager /system/bin/servicemanager    class core    user system    group system    critical    onrestart restart healthd    onrestart restart zygote    onrestart restart media    onrestart restart surfaceflinger    onrestart restart drmservice vold /system/bin/vold    class core    socket vold stream 0660 root mount    ioprio be 2service netd /system/bin/netd    class main    socket netd stream 0660 root system    socket dnsproxyd stream 0660 root inet    socket mdns stream 0660 root system    socket fwmarkd stream 0660 root inetservice debuggerd /system/bin/debuggerd    class main# for ZTE 3Gservice ril-daemon /system/bin/rild -l /system/lib/libzte-ril.so -- -d /dev/ttyUSB1 -u /dev/ttyUSB3    class main    socket rild stream 660 root radio    socket rild-debug stream 660 radio system    user root    group radio cache inet misc audio sdcard_r sdcard_rw log net_admin net_rawon property:ril.reset.rild=1    stop ril-daemon    start ril-daemon    setprop ril.reset.rild 0service pppd_gprs /system/etc/ppp/init.gprs-pppd    user root    group radio cache inet misc log net_admin net_raw    disabled    oneshotservice surfaceflinger /system/bin/surfaceflinger    class core    user system    group graphics drmrpc    #重启时会触发zygote重启    onrestart restart zygoteservice drm /system/bin/drmserver    class main    user drm    group drm system inet drmrpcservice media /system/bin/mediaserver    class main    user media    group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm    ioprio rt 4# One shot invocation to deal with encrypted volume.service defaultcrypto /system/bin/vdc --wait cryptfs mountdefaultencrypted    disabled    oneshot    # vold will set vold.decrypt to trigger_restart_framework (default    # encryption) or trigger_restart_min_framework (other encryption)# One shot invocation to encrypt unencrypted volumesservice encrypt /system/bin/vdc --wait cryptfs enablecrypto inplace default    disabled    oneshot    # vold will set vold.decrypt to trigger_restart_framework (default    # encryption)service bootanim /system/bin/bootanimation    class core    user graphics    group graphics audio    disabled    oneshotservice installd /system/bin/installd    class main    socket installd stream 600 system systemservice flash_recovery /system/bin/install-recovery.sh    class main    seclabel u:r:install_recovery:s0    oneshotservice racoon /system/bin/racoon    class main    socket racoon stream 600 system system    # IKE uses UDP port 500. Racoon will setuid to vpn after binding the port.    group vpn net_admin inet    disabled    oneshotservice mtpd /system/bin/mtpd    class main    socket mtpd stream 600 system system    user vpn    group vpn net_admin inet net_raw    disabled    oneshotservice keystore /system/bin/keystore /data/misc/keystore    class main    user keystore    group keystore drmrpcservice dumpstate /system/bin/dumpstate -s    class main    socket dumpstate stream 0660 shell log    disabled    oneshotservice mdnsd /system/bin/mdnsd    class main    user mdnsr    group inet net_raw    socket mdnsd stream 0660 mdnsr inet    disabled    oneshotservice pre-recovery /system/bin/uncrypt    class main    disabled    oneshot
复制代码

init进程通过init.rc脚本启动servicemanager

复制代码
service servicemanager /system/bin/servicemanager    class core    user system    group system    critical    #重启时会触发下列进程重启    onrestart restart healthd    onrestart restart zygote    onrestart restart media    onrestart restart surfaceflinger    onrestart restart drm
复制代码

个servicemanager是Android系统Binder进程间通信的重要的守护进程

这个先放一下,之后学习Binder系统的时候再深入分析。

init进程又启动了zygote进程

init.rc脚本在开是引入了zygote的启动脚本

import /init.${ro.zygote}.rc
复制代码
#system/core/rootdir/init.zygote32.rcservice zygote /system/bin/app_process -Xzygote /system/bin --zygote --start-system-server    class main    socket zygote stream 660 root system    onrestart write /sys/android_power/request_state wake    onrestart write /sys/power/state on    onrestart restart media    onrestart restart netd
复制代码

zygote进程是java环境的入口

复制代码
// frameworks/base/cmds/app_process/app_main.cppint main(int argc, char* const argv[]){    ....    if (!niceName.isEmpty()) {        runtime.setArgv0(niceName.string());        set_process_name(niceName.string());    }    if (zygote) {        //启动zygote进程        runtime.start("com.android.internal.os.ZygoteInit", args);    } else if (className) {        runtime.start("com.android.internal.os.RuntimeInit", args);    } else {        fprintf(stderr, "Error: no class name or --zygote supplied.\n");        app_usage();        LOG_ALWAYS_FATAL("app_process: no class name or --zygote supplied.");        return 10;    }}
复制代码

看一下系统是怎样进入java环境的

复制代码
// frameworks/base/core/jni/AndroidRuntime.cpp void AndroidRuntime::start(const char* className, const Vector<String8>& options){    ALOGD("\n>>>>>> AndroidRuntime START %s <<<<<<\n",    ....    //启动systemserver    static const String8 startSystemServer("start-system-server");    ....    //启动java进程    char* slashClassName = toSlashClassName(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 {            env->CallStaticVoidMethod(startClass, startMeth, strArray);        ....}
复制代码

接着就是启动systemserver了,它是由zygote启动的

复制代码
// frameworks/base/core/java/com/android/internal/os/ZygoteInit.java public static void main(String argv[]) {    ....    registerZygoteSocket(socketName);//注册socket    ....    if (startSystemServer) {                //启动SystemServer                startSystemServer(abiList, socketName);            }    ....}
复制代码

systemserver启动了一票的Java层服务

复制代码
//frameworks/base/services/java/com/android/server/SystemServer.java public static void main(String[] args) {        //new一个SystemServer对象并调用其run函数        new SystemServer().run();    }private void run() {    ....    // Here we go!    Slog.i(TAG, "Entered the Android system server!");    EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());    ....    // Initialize native services.    //加载本地库并初始化    System.loadLibrary("android_servers");    nativeInit();    ....    // Start services.    //启动一票的Java层系统服务        try {            startBootstrapServices();            startCoreServices();            startOtherServices();         } catch (Throwable ex) {            Slog.e("System", "******************************************");            Slog.e("System", "************ Failure starting system services", ex);            throw ex;        }
复制代码

下面看一下这些系统服务的启动过程,注释很详细

复制代码
 private void startBootstrapServices() {        // Wait for installd to finish starting up so that it has a chance to        // create critical directories such as /data/user with the appropriate        // permissions.  We need this to complete before we initialize other services.        mInstaller = mSystemServiceManager.startService(Installer.class);        // Activity manager runs the show.        mActivityManagerService = mSystemServiceManager.startService(                ActivityManagerService.Lifecycle.class).getService();        mActivityManagerService.setSystemServiceManager(mSystemServiceManager);        // Power manager needs to be started early because other services need it.        // Native daemons may be watching for it to be registered so it must be ready        // to handle incoming binder calls immediately (including being able to verify        // the permissions for those calls).        mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);        // Now that the power manager has been started, let the activity manager        // initialize power management features.        mActivityManagerService.initPowerManagement();        // Display manager is needed to provide display metrics before package manager        // starts up.        mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);        // We need the default display before we can initialize the package manager.        mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);        // Only run "core" apps if we're encrypting the device.        String cryptState = SystemProperties.get("vold.decrypt");        if (ENCRYPTING_STATE.equals(cryptState)) {            Slog.w(TAG, "Detected encryption in progress - only parsing core apps");            mOnlyCore = true;        } else if (ENCRYPTED_STATE.equals(cryptState)) {            Slog.w(TAG, "Device encrypted - only parsing core apps");            mOnlyCore = true;        }        // Start the package manager.        Slog.i(TAG, "Package Manager");        mPackageManagerService = PackageManagerService.main(mSystemContext, mInstaller,                mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);        mFirstBoot = mPackageManagerService.isFirstBoot();        mPackageManager = mSystemContext.getPackageManager();        Slog.i(TAG, "User Service");        ServiceManager.addService(Context.USER_SERVICE, UserManagerService.getInstance());        // Initialize attribute cache used to cache resources from packages.        AttributeCache.init(mSystemContext);        // Set up the Application instance for the system process and get started.        mActivityManagerService.setSystemProcess();    }
复制代码
复制代码
private void startCoreServices() {        // Manages LEDs and display backlight.        mSystemServiceManager.startService(LightsService.class);        // Tracks the battery level.  Requires LightService.        mSystemServiceManager.startService(BatteryService.class);        // Tracks application usage stats.        mSystemServiceManager.startService(UsageStatsService.class);        mActivityManagerService.setUsageStatsManager(                LocalServices.getService(UsageStatsManagerInternal.class));        // Tracks whether the updatable WebView is in a ready state and watches for update installs.        mSystemServiceManager.startService(WebViewUpdateService.class);    }
复制代码
复制代码
private void startOtherServices() {    ....    Slog.i(TAG, "Reading configuration...");    SystemConfig.getInstance();    Slog.i(TAG, "Scheduling Policy");    ServiceManager.addService("scheduling_policy", new SchedulingPolicyService());    Slog.i(TAG, "Telephony Registry");    telephonyRegistry = new TelephonyRegistry(context);    ServiceManager.addService("telephony.registry", telephonyRegistry);    Slog.i(TAG, "Entropy Mixer");    ServiceManager.addService("entropy", new EntropyMixer(context));    Slog.i(TAG, "Account Manager");    accountManager = new AccountManagerService(context);    ServiceManager.addService(Context.ACCOUNT_SERVICE, accountManager);    //下面还有很多,具体用到哪些东西的时候再回过头来分析    ....
复制代码

再往下就是开机进入锁屏界面了,这部分内容还不熟悉,之后再分析。。。。。-_-!!!

 

 

多谢下面两位前辈的无私分享

参考文章:

http://gityuan.com/

http://blog.csdn.net/hovan/article/details/9896751


转载地址:http://www.cnblogs.com/CoderTian/p/6053084.html