標籤:android啟動最佳化 android init init android 啟動流程 android 啟動速度
#############################################
本文為極度寒冰原創,轉載請註明出處#############################################分析init進程,首先要分析init進程是如何啟動的, init的源碼位於(system/core/init),我們先來看看init進程的android.mk下面是從system/core/init模組拿出來的一段code:
LOCAL_MODULE:= initLOCAL_FORCE_STATIC_EXECUTABLE := trueLOCAL_MODULE_PATH := $(TARGET_ROOT_OUT)LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED)LOCAL_STATIC_LIBRARIES := libfs_mgr liblogwrap libcutils liblog libc libselinux libmincrypt libext4_utils_staticLOCAL_ADDITIONAL_DEPENDENCIES += $(LOCAL_PATH)/Android.mkinclude $(BUILD_EXECUTABLE)
我們發現,init的代碼其實是被編譯成了一個可執行檔程式:
include $(BUILD_EXECUTABLE)
程式的名字是叫:
LOCAL_MODULE:= init
那麼init的可執行應用程式是怎麼被啟動的呢?這下就是kernel與android ap端的聯絡了。
我們看一下kernel的code:在kernel的code:init/main.c的main函數中,我們看到了如下的代碼:
878if (!ramdisk_execute_command)879ramdisk_execute_command = "/init";880881if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {882ramdisk_execute_command = NULL;883prepare_namespace();884}我們發現,ramdisk_execute_command被初始化為了init
sys_access((const char __user *) ramdisk_execute_command, 0)
判斷系統中是否存在/init的命令,如果不存在的話,會將ramdisk_execute_command置為NUll並且會去繼續尋找,檢查是否有沒有掛載的檔案系統,initrd就是在這個函數中被掛載的。
而對於我們android來講,一般正常的情況下,我們會去執行
init_post();
而這個函數的實現如下:
795/* This is a non __init function. Force it to be noinline otherwise gcc796 * makes it inline to init() and it becomes part of init.text section797 */798static noinline int init_post(void)799{800/* need to finish all async __init code before freeing the memory */801async_synchronize_full();802free_initmem();803mark_rodata_ro();804system_state = SYSTEM_RUNNING;805numa_default_policy();806807808current->signal->flags |= SIGNAL_UNKILLABLE;809810if (ramdisk_execute_command) {811run_init_process(ramdisk_execute_command);812printk(KERN_WARNING "Failed to execute %s\n",813ramdisk_execute_command);814}815816/*817 * We try each of these until one succeeds.818 *819 * The Bourne shell can be used instead of init if we are820 * trying to recover a really broken machine.821 */822if (execute_command) {823run_init_process(execute_command);824printk(KERN_WARNING "Failed to execute %s. Attempting "825"defaults...\n", execute_command);826}827run_init_process("/sbin/init");828run_init_process("/etc/init");829run_init_process("/bin/init");830run_init_process("/bin/sh");831832panic("No init found. Try passing init= option to kernel. "833 "See Linux Documentation/init.txt for guidance.");834}可以看到,當ramdisk_execute_command不為NULL的時候,就會去run run_init_process.
<pre name="code" class="cpp" style="font-size: 13.63636302948px; line-height: 25.9943180084229px;">789static void run_init_process(const char *init_filename)790{791argv_init[0] = init_filename;792kernel_execve(init_filename, argv_init, envp_init);793}794
看到這裡,我們就看明白了。這裡就會去執行我們ap端編譯出來的的init的命令,也就是會進入到/system/core/init的目錄下
從此完成了kernel到init的連結
Android啟動流程分析(二) init進程的啟動