基於android2.3.5系統:開天闢地Android啟動機制[一]

來源:互聯網
上載者:User

**************************************************************************************************************************
作者:EasyWave                                                                                 時間:2012.07.21

類別:Android系統源碼分析                                                              聲明:轉載,請保留連結

注意:如有錯誤,歡迎指正。這些是我學習的日誌文章......

***************************************************************************************************************************

在android的系統中init程式是第一個啟動並執行程式,這是一個守護進程,而具體的代碼在android2.3.5的源碼中,位於system/core/init/init.c文檔中,這個是main函數的入口,也是android啟動機制的入口。代碼如下所示:

int main(int argc, char **argv){    int fd_count = 0;    struct pollfd ufds[4];    char *tmpdev;    char* debuggable;    char tmp[32];    int property_set_fd_init = 0;    int signal_fd_init = 0;    int keychord_fd_init = 0;    if (!strcmp(basename(argv[0]), "ueventd")) // 得到運行程式ueventd.rc的全路徑名下的ueventd        return ueventd_main(argc, argv);    // 如果可以找到ueventd.rc,則執行ueventd_main函數                                            // 解析uevent.rc以及/ueventd.%s.rc    /* clear the umask */    umask(0);        /* Get the basic filesystem setup we need put         * together in the initramdisk on / and then we'll         * let the rc file figure out the rest.         */    mkdir("/dev", 0755);  //建立可讀寫的/dev目錄    mkdir("/proc", 0755); //建立可讀寫的/proc目錄    mkdir("/sys", 0755);  //建立可讀寫的/sys目錄,下面也是建立和掛載一些檔案系統,是不是似曾相識啊,這個就是建立一個基本的檔案系統,是不是有點像busybox.    mount("tmpfs", "/dev", "tmpfs", 0, "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);        /* We must have some place other than / to create the         * device nodes for kmsg and null, otherwise we won't         * be able to remount / read-only later on.         * Now that tmpfs is mounted on /dev, we can actually         * talk to the outside world.         */    open_devnull_stdio();   // 建立和開啟"/dev/__null__" 虛擬設備(類似於 Linux 系統中的 /dev/null 裝置)並將                             // stdin/stdout/stderr 三個檔案重新導向到 "/dev/__null__"    log_init();  //建立和開啟"/dev/__kmsg__" 虛擬設備用於記錄 log        INFO("reading config file\n");    init_parse_config_file("/init.rc"); //初始化解析system/etc/init.rc檔案    /* pull the kernel commandline and ramdisk properties file in */    import_kernel_cmdline(0); //匯入proc/cmdline的command line參數等。    get_hardware_name(hardware, &revision); //透過/proc/cpuinfo得到硬體模組名稱    snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware); //並且將其拷貝到init.xxxx.rc中。    init_parse_config_file(tmp); //初始化解析init.xxxx.rc檔案    action_for_each_trigger("early-init", action_add_queue_tail); //下面的代碼需要去瞭解android的一些檔案系統初始化的一些原理,不多說了。     queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done");    queue_builtin_action(property_init_action, "property_init");    queue_builtin_action(keychord_init_action, "keychord_init");    queue_builtin_action(console_init_action, "console_init");    queue_builtin_action(set_init_properties_action, "set_init_properties");        /* execute all the boot actions to get us started */    action_for_each_trigger("init", action_add_queue_tail);    action_for_each_trigger("early-fs", action_add_queue_tail);    action_for_each_trigger("fs", action_add_queue_tail);    action_for_each_trigger("post-fs", action_add_queue_tail);    queue_builtin_action(property_service_init_action, "property_service_init");    queue_builtin_action(signal_init_action, "signal_init");    queue_builtin_action(check_startup_action, "check_startup");    /* execute all the boot actions to get us started */    action_for_each_trigger("early-boot", action_add_queue_tail);    action_for_each_trigger("boot", action_add_queue_tail);        /* run all property triggers based on current state of the properties */    queue_builtin_action(queue_property_triggers_action, "queue_propety_triggers");#if BOOTCHART    queue_builtin_action(bootchart_init_action, "bootchart_init");#endif    for(;;) {        int nr, i, timeout = -1;        execute_one_command(); //操作上面整理的 action_queue 中對應的 action        restart_processes(); //當前的服務進程狀態,如果有服務進程退出,重啟對應服務進程        //property_service 的事件控制代碼填充 poll event 結構體        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;}

1 . 關於 init.rc

啟動指令碼init.rc

在 Android中使用啟動指令碼init.rc,可以在系統的初始化過程中進行一些簡單的初始化操作。這個指令碼被直接安裝到目標系統的根檔案系統中,被 init可執行程式解析。 init.rc是在init啟動後被執行的啟動指令碼,其餘發主要包含了以下內容:

  • Commands:命令
  • Actions:動作
  • Triggers:觸發條件
  • Services:服務
  • Options:選項
  • Propertise:屬性

Commands是一些基本的操作,例如:

    mkdir /sdcard 0000 system system    mkdir /system    mkdir /data 0771 system system    mkdir /cache 0770 system cache    mkdir /config 0500 root root    mkdir /sqlite_stmt_journals 01777 root root    mount tmpfs tmpfs /sqlite_stmt_journals size=4m

這些命令在init可執行程式中被解析,然後調用相關的函數來實現。 Actions(動作)表示一系列的命令,通常在Triggers(觸發條件)中調用,動作和觸發條件例如:

    on init    export PATH /sbin:/system/sbin:/system/bin:/system/xbin

init表示一個觸發條件,這個觸發事件發生後,進行設定環境變數和建立目錄的操作稱為一個“動作” Services(服務)通常表示啟動一個可執行程式,Options(選項)是服務的附加內容,用於配合服務使用。

service vold /system/bin/vold    socket vold stream 0660 root mountservice bootsound /system/bin/playmp3    user media    group audio    oneshot

vold和bootsound分別是兩個服務的名稱,/system/bin /vold和/system /bin/playmp3分別是他們所對應的可執行程式。socket、user、group、oneshot就是配合服務使用的選項。 Properties(屬性)是系統中使用的一些值,可以進行設定和讀取。

    setprop ro.FOREGROUND_APP_MEM 1536    setprop ro.VISIBLE_APP_MEM 2048    start adbd

setprop 用於設定屬性,on property可以用於判斷屬性,這裡的屬性在整個Android系統運行中都是一致的。

綜上如果想要修改啟動過程只需要修改init.c或者init.rc裡的內容即可.


3. 總結:

(1)核心的init_post類似介面,會去檔案系統中啟動init類似的使用者進程

(2)android實現了這樣的init,這就是android架構啟動的地方,當然linux核心也可說是android系統的一部分

(3)init進程無限分裂,啟動架構,演變成android系統

(4)android的init進程的代碼在system/core/init/init.c中,從main函數開始.

還沒有分析完,詳細的程式碼分析請見:基於android2.3.5學習之:開天闢地Android啟動機制[二]

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.