init进程是Android启动后,系统执行的第一个名称为init的可执行程序。

功能:

  • 设备管理
  • 解析启动脚本init.rc
  • 执行启动脚本中的基本功能
  • 执行启动脚本中的各种服务

代码路径:system/core/init

编译结果生成一个可执行文件:init

1.main{}

int main(int argc, char **argv)
{
    int device_fd = -1;
    int property_set_fd = -1;
    int signal_recv_fd = -1;
    int keychord_fd = -1;
    int fd_count;
    int s[2];
    int fd;
    struct sigaction act;
    char tmp[PROP_VALUE_MAX];
    struct pollfd ufds[4];
    char *tmpdev;
    char* debuggable;

act.sa_handler = sigchld_handler;
    act.sa_flags = SA_NOCLDSTOP;
    act.sa_mask = 0;
    act.sa_restorer = NULL;
    sigaction(SIGCHLD, &act, 0);

umask(0);

mkdir("/dev", 0755);                    //创建文件系统的基本目录
    mkdir("/proc", 0755);
    mkdir("/sys", 0755);

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);

open_devnull_stdio();             //打开3个文件:输入,输入,错误
    log_init();                       //初始化log
    
    INFO("reading config file\n");
    parse_config_file("/init.rc");        //处理初始化脚本,获取内核命令行参数

qemu_init();
    import_kernel_cmdline(0);             //初始化驱动设备,创建文件系统节点

get_hardware_name();
    snprintf(tmp, sizeof(tmp), "/init.%s.rc", hardware);
    parse_config_file(tmp);

action_for_each_trigger("early-init", action_add_queue_tail);
    drain_action_queue();

INFO("device init\n");
    device_fd = device_init();              //属性相关处理和启动logo

if (emmc_boot){
        action_for_each_trigger("emmc", action_add_queue_tail);
        drain_action_queue();
    }else{
        action_for_each_trigger("nand", action_add_queue_tail);
        drain_action_queue();
    }

property_init();
   
    // only listen for keychords if ro.debuggable is true
    keychord_fd = open_keychord();

if (console[0]) {
        snprintf(tmp, sizeof(tmp), "/dev/%s", console);
        console_name = strdup(tmp);
    }

fd = open(console_name, O_RDWR);
    if (fd >= 0)
        have_console = 1;
    close(fd);

if( load_565rle_image(INIT_IMAGE_FILE) ) {        //
    fd = open("/dev/tty0", O_WRONLY);
    if (fd >= 0) {
        const char *msg;
            msg = "\n"

"\n"
        "\n"
        "\n"
        "\n"
        "\n"
        "\n"  // console is 40 cols x 30 lines
        "\n"
        "\n"
        "\n"
        "\n"
        "\n"
        "\n"
        "\n"
        "             A N D R O I D ";
        write(fd, msg, strlen(msg));
        close(fd);
    }

}

if (qemu[0])
        import_kernel_cmdline(1);

if (!strcmp(bootmode,"factory"))
        property_set("ro.factorytest", "1");
    else if (!strcmp(bootmode,"factory2"))
        property_set("ro.factorytest", "2");
    else
        property_set("ro.factorytest", "0");

property_set("ro.serialno", serialno[0] ? serialno : "");
    property_set("ro.bootmode", bootmode[0] ? bootmode : "unknown");
    property_set("ro.baseband", baseband[0] ? baseband : "unknown");
    property_set("ro.carrier", carrier[0] ? carrier : "unknown");
    property_set("ro.bootloader", bootloader[0] ? bootloader : "unknown");

property_set("ro.hardware", hardware);
    snprintf(tmp, PROP_VALUE_MAX, "%d", revision);
    property_set("ro.revision", tmp);
    property_set("ro.emmc",emmc_boot ? "1" : "0");

action_for_each_trigger("init", action_add_queue_tail);
    drain_action_queue();
    
    {
    ERROR("pmd processing!\n");
    system("/system/bin/pmd");
    ERROR("pmd exit!\n");
    // }    
       
    property_set_fd = start_property_service();

if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) == 0) {
        signal_fd = s[0];
        signal_recv_fd = s[1];
        fcntl(s[0], F_SETFD, FD_CLOEXEC);
        fcntl(s[0], F_SETFL, O_NONBLOCK);
        fcntl(s[1], F_SETFD, FD_CLOEXEC);
        fcntl(s[1], F_SETFL, O_NONBLOCK);
    }

if ((device_fd < 0) ||
        (property_set_fd < 0) ||
        (signal_recv_fd < 0)) {
        ERROR("init startup failure\n");
        return 1;
    }

if (battchg_pause) {
        action_for_each_trigger("boot-pause", action_add_queue_tail);
        drain_action_queue();
    }

action_for_each_trigger("early-boot", action_add_queue_tail);
    action_for_each_trigger("boot", action_add_queue_tail);
    drain_action_queue();

queue_all_property_triggers();
    drain_action_queue();

property_triggers_enabled = 1;

ufds[0].fd = device_fd;                 //初始化struct pollfd ufds[4]
    ufds[0].events = POLLIN;
    ufds[1].fd = property_set_fd;
    ufds[1].events = POLLIN;
    ufds[2].fd = signal_recv_fd;
    ufds[2].events = POLLIN;
    fd_count = 3;

if (keychord_fd > 0) {
        ufds[3].fd = keychord_fd;
        ufds[3].events = POLLIN;
        fd_count++;
    } else {
        ufds[3].events = 0;
        ufds[3].revents = 0;
    }

#if BOOTCHART
    bootchart_count = bootchart_init();
    if (bootchart_count < 0) {
        ERROR("bootcharting init failure\n");
    } else if (bootchart_count > 0) {
        NOTICE("bootcharting started (period=%d ms)\n", bootchart_count*BOOTCHART_POLLING_MS);
    } else {
        NOTICE("bootcharting ignored\n");
    }
#endif

for(;;) {                                         //进入循环,处理ufds[4]的事件
        int nr, i, timeout = -1;

for (i = 0; i < fd_count; i++)
            ufds[i].revents = 0;

drain_action_queue();
        restart_processes();

if (process_needs_restart) {
            timeout = (process_needs_restart - gettime()) * 1000;
            if (timeout < 0)
                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;

if (ufds[2].revents == POLLIN) {
           
            read(signal_recv_fd, tmp, sizeof(tmp));
            while (!wait_for_one_process(0))
                ;
            continue;
        }

if (ufds[0].revents == POLLIN)
            handle_device_fd(device_fd);

if (ufds[1].revents == POLLIN)
            handle_property_set_fd(property_set_fd);
        if (ufds[3].revents == POLLIN)
            handle_keychord(keychord_fd);
    }

return 0;
}

Android——init可执行程序的更多相关文章

  1. Android init.rc文件格式解析

    /***************************************************************************** * Android init.rc文件格式 ...

  2. init进程 && 解析Android启动脚本init.rc && 修改它使不启动android && init.rc中启动一个sh文件

    Android启动后,系统执行的第一个进程是一个名称为init 的可执行程序.提供了以下的功能:设备管理.解析启动脚本.执行基本的功能.启动各种服务.代码的路径:system/core/init,编译 ...

  3. Android Init语言

    Android Init语言是一种特别简单的语言,专门用来写Android的Init进程使用的配置文件的. 相当于Linux系统中的rc文件(这句话对于Linux者多半是句废话). Android I ...

  4. android init进程分析 ueventd

    转自:http://blog.csdn.net/freshui/article/details/2132299 (懒人最近想起我还有csdn好久没打理了,这个Android init躺在我的草稿箱中快 ...

  5. Android init.rc解析【转】

    转自:http://www.linuxidc.com/Linux/2014-10/108438.htm 本文主要来自$Android_SOURCE/system/init/readme.txt的翻译. ...

  6. Android init.rc文件浅析

    Android init.rc文件浅析 分类: Android2012-04-13 18:00 13149人阅读 评论(2) 收藏 举报 androidservicepathactionsocketc ...

  7. android init进程分析 init脚本解析和处理

    (懒人近期想起我还有csdn好久没打理了.这个android init躺在我的草稿箱中快5年了.略微改改发出来吧) RC文件格式 rc文件是linux中常见的启动载入阶段运行的文件.rc是run co ...

  8. Android init介绍(下)

    上一篇请参考<Android init介绍(上)> 5. AIL 在init启动过程中,系统服务等均是通过解析rc文件来启动,而rc文件则是由Android初始化语言(Android In ...

  9. Android init介绍(上)

    1. 介绍 init进程是Linux系统第一个用户进程,是Android系统应用程序的根进程,即1号进程(PID为1):Android中的init文件位于/init,代码位于system/core/i ...

随机推荐

  1. 公司用中会用到的iOS开源库和第三方组件(不断更新...)

    分享一些目前我个人接触到的一些第三方组件和开源的库, 感谢开源, 减少了我们的开发成本, 节约了我们大量的时间, 让我们有更多的时间和精力专注做我们自己的产品.总有没有接触过的 , 总有你会用到的 , ...

  2. reflow和repaint

    Web页面运行在各种各样的浏览器当中,浏览器载入.渲染页面的速度直接影响着用户体验 简单地说,页面渲染就是浏览器将html代码根据CSS定义的规则显示在浏览器窗口中的这个过程.先来大致了解一下浏览器都 ...

  3. C++中为什么构造函数初始化列表

    已经有个构造函数负责初始化,为什么还需要构造函数初始化表呢? 在以下三种情况下需要使用初始化成员列表:一,需要初始化的数据成员是对象的情况:二,需要初始化const修饰的类成员:三,需要初始化引用成员 ...

  4. Google Gson的使用方法

    用法1:从网络获取到json字符串之后,假如该字符串为data, Gson gson = new Gson(); HomeBean json = gson.fromJson(data, HomeBea ...

  5. PCI源码学习笔记

    这个是PCI的关键结构体. static const struct file_operations proc_bus_pci_operations = { .owner = THIS_MODULE, ...

  6. jquery给html元素添加内容

    append() - 在被选元素的结尾插入内容 prepend() - 在被选元素的开头插入内容 after() - 在被选元素之后插入内容 before() - 在被选元素之前插入内容 实例 $(& ...

  7. HTML day01基础总结

    1.网页的基本元素 文字.图像与超链接. 2.每一个网页元素通常由开始标记.结束标记,以及在这两个标记中的内容所组成. 3.一般结构 <html> <head> <met ...

  8. linux视频学习7(ssh, linux启动过程分析,加解压缩,java网络编程)

    回顾数据库mysql的备份和恢复: show databases; user spdb1; show tables; 在mysql/bin目录下 执行备份: ./mysqldump -u root - ...

  9. HDU1492/The number of divisors(约数) about Humble Numbers

    题目连接 The number of divisors(约数) about Humble Numbers Time Limit: 2000/1000 MS (Java/Others) Memory L ...

  10. pat L1-006. 连续因子

    L1-006. 连续因子 时间限制 400 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 一个正整数N的因子中可能存在若干连续的数字.例如630 ...