当前位置:操作系统 > 安卓/Android >>

AndroidInitProcess分析心得(3)

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


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

//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:

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

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


会经由keyword_info mapping table中的

[cpp] view plaincopyprint?KEYWORD(write,       COMMAND, 2, do_write) 

KEYWORD(write,       COMMAND, 2, do_write)

呼叫到

[cpp]
\\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); 

\\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.

[cpp]
//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); 

//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的动作.


[cpp]
// 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"); 

// 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其间做哪些行为.

[cpp]
// 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; 

// 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

补充:移动开发 , Android ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,