zoukankan      html  css  js  c++  java
  • 函数元素AndroidInitProcess分析心得(3)

    时间紧张,先记一笔,后续优化与完善。

        路一跑下来, 我们可以现发终究看到我们想看的command元素了, 本来在个一每act元素中还有一串由act元素所带的comand立建的cmdlinked list, 个一每comand元素会有一个func的functionpointer. 这个function pointer就是由kw_func macro所指定的.

    //system\core\init\init_parser.c
    #define kw_func(kw) (keyword_info[kw].func)

        由这个macro可以道知, 其所指定的function就看kw_func macro所带的参数kw经过keyword_infomapping table去指定的.

            回到执行程流的execute_one_command函数继承分析, 由下面的一些细节可以对于cur_command所带的function跟keyword_info mapping table中所记载的function有关.Example:

    //system\core\rootdir\init.rc
    write /proc/sys/kernel/panic_on_oops 1

        会经过keyword_info mapping table中的

    KEYWORD(write,       COMMAND, 2, do_write)

        呼叫到

    \\system\core\init\builtins.c
    int do_write(int nargs, char **args)
    {
        const char *path = args[1];
        const char *value = args[2];
        char prop_val[PROP_VALUE_MAX];
        int ret;
    
        ret = expand_props(prop_val, value, sizeof(prop_val));
        if (ret) {
            ERROR("cannot expand '%s' while writing to '%s'\n", value, path);
            return -EINVAL;
        }
        return write_file(path, prop_val);
    }

        创立filesystem path node

            Init process是android的一个启动的process,在initprocess一启动就会开始建构一些file system.

    //system\core\init\init.c
    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);

        首先先建构出三个目录, dev, proc, sys, 期三个目录所放的档案个不同.

        

    /dev

    在Linux下, 任何的边周置装都是以档案的状态存在这目录下. 要制控边周置装只要针对这目录下的档案径路作档案读写了行就.

    /proc

    本身是一个virtual file system, 里头放置的档案数据会都存在内存当中, 也就是说只有置装在执行时, 这目录下才会有档案现出..

    /sys

    本身是一个virtual file system, 跟/proc放置的档案不一样, 放的都是跟核心有关的数据或是核心侦测到的硬件置装信息..

        以后会现发就在这三个重要的目录下挂载其他目录,和建构子目录.

        监控系统属性化变跟事件

            Init process所监控的对象有property, signal, keychord. Init process一启动时便会针对这三个对像作initialize的作动.

    // system\core\init\init.c
    queue_builtin_action(keychord_init_action, "keychord_init");
    queue_builtin_action(property_service_init_action, "property_service_init");
    queue_builtin_action(signal_init_action, "signal_init");
        每日一道理
    流逝的日子像一片片凋零的枯叶与花瓣,渐去渐远的是青春的纯情与浪漫。不记得曾有多少雨飘在胸前风响在耳畔,只道知沧桑早已漫进了我的心爬上了我的脸。当一个人与追求同行,便坎坷是伴,磨难也是伴。

        queue_builtin_action函数只是将第一个函数包装成一个command, 然后在用利command构成一个act的数据元素, 以后在将这个act新增到action_list中, 以后再经过action_add_queue_tail将此新的act数据元素送进actionqueue中. 其command所带的函数会在面前所论讨的execute_one_command函数呼叫到.

            由于三个对像初始化的型为异小同大, 这里就举property来说明initial其间做哪些为行.

    // system\core\init\init.c
    static int property_service_init_action(int nargs, char **args)
    {
        /* read any property files on system or data and
         * fire up the property service.  This must happen
         * after the ro.foo properties are set above so
         * that /data/local.prop cannot interfere with them.
         */
        start_property_service();
        return 0;
    }
    
    //system\core\init\property_service.c
    void start_property_service(void)
    {
        int fd;
    
        load_properties_from_file(PROP_PATH_SYSTEM_BUILD);
        load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT);
        load_override_properties();
        /* Read persistent properties after all default values have been loaded. */
        load_persistent_properties();
    
        fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0);
        if(fd < 0) return;
        fcntl(fd, F_SETFD, FD_CLOEXEC);
        fcntl(fd, F_SETFL, O_NONBLOCK);
    
        listen(fd, 8);
        property_set_fd = fd;
    }

        一开始就会下载property配置文件, 这些档案放存的径路义定在_system_properties.h

    // bionic\libc\include\sys\_system_properties.h
    #define PROP_PATH_RAMDISK_DEFAULT  "/default.prop"
    #define PROP_PATH_SYSTEM_BUILD     "/system/build.prop"
    #define PROP_PATH_SYSTEM_DEFAULT   "/system/default.prop"
    #define PROP_PATH_LOCAL_OVERRIDE   "/data/local.prop"

        有所的android系统所吃的配置文件一开机就会从这些档案去取读. 至于propertyconfig file如何去编辑, 这不在这里的范围. 所以就不在这分析.下载完有所的property的设定值以后就开启socket去等待化变. 并把filedescriptor传给global 变数property_set_fd.

            一旦初始化以后, 就开始进入监控程流.

    //system\core\init\init.c
    int main(int argc, char **argv)
    {
        //...
        for(;;) {
           // 执行action list 中的act的command.
           // 检查是不是有service要需重新启动
           (1)
           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;
            }
    
            //....
           (2)
           nr = poll(ufds, fd_count, timeout);
            if (nr <= 0)
                continue;
           (3)
           for (i = 0; i < fd_count; i++) {
                if (ufds[i].revents == POLLIN) {
                   if (ufds[i].fd == get_property_set_fd())
                        handle_property_set_fd();
                   //....
                }
           }
    
        }
        return 0;
    }

        (1) 册注pollfd 结构, 其中get_property_set_fd 函数所得取的值就是之前在initial时代所开启socket的 filedescriptor.

        (2) 开始进入polling监控化变. 一有化变才会继承第三步, 否则跳过接着下一次polling监控.

        (3) 一有化变就开始比对所册注的filedescriptor, 之前有提到现在android(4.2)监控的对象有三个. 最后进入handlefunction.

    文章结束给大家分享下程序员的一些笑话语录: 女人篇
      有的女人就是Windows虽然很优秀,但是安全隐患太大。
      有的女人就是MFC她条件很好,然而不是谁都能玩的起。
      有的女人就是C#长的很漂亮,但是家务活不行。
      有的女人就是C++,她会默默的为你做很多的事情。
      有的女人就是汇编虽然很麻烦,但是有的时候还得求它。
      有的女人就是SQL,她会为你的发展带来莫大的帮助。

  • 相关阅读:
    2018.9月总结
    L143 Seasonal 'Plague' Hits College Freshman
    2018.9.28 长难句2-非简单句
    Report: Disappearing Wetlands Put Planet Life at Risk
    PyQt(Python+Qt)学习随笔:QTableWidget的currentItem、rowCount、columnCount等部件状态属性访问方法
    PyQt(Python+Qt)学习随笔:QTableWidget的构造方法
    PyQt学习随笔:QTableWidgetItem项的setSizeHint()方法的作用
    PyQt(Python+Qt)学习随笔:QTableWidget中表格各列平均分配宽度的两种方法
    PyQt学习随笔:QTableWidget项sizeHint的作用以及与QHeadView的sectionResizeMode、ResizeToContents的关系
    PyQt(Python+Qt)学习随笔:QTableWidget表格部件中行高和列宽的计算方式
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/3067710.html
Copyright © 2011-2022 走看看