专栏名称: foxleezh
android工程师
目录
相关文章推荐
香港中文大学深圳  ·  第二届神仙湖管理学论坛圆满落幕 ·  14 小时前  
秋叶PPT  ·  用AI给爸妈生成短剧海报,我被追着打! ·  19 小时前  
秋叶PPT  ·  想靠PPT副业年入30万的设计师,都偷偷收藏 ... ·  19 小时前  
51好读  ›  专栏  ›  foxleezh

(连载)Android 8.0 : 系统启动流程之init进程(一)

foxleezh  · 简书  ·  · 2018-03-02 08:26

正文

请到「今天看啥」查看全文


这个函数主要作用将各种信号量,如SIGABRT,SIGBUS等的行为设置为SA_RESTART,一旦监听到这些信号即执行重启系统

static void install_reboot_signal_handlers() {
    // Instead of panic'ing the kernel as is the default behavior when init crashes,
    // we prefer to reboot to bootloader on development builds, as this will prevent
    // boot looping bad configurations and allow both developers and test farms to easily
    // recover.
    struct sigaction action;
    memset(&action, 0, sizeof(action));
    sigfillset(&action.sa_mask);//将所有信号加入至信号集
    action.sa_handler = [](int) {
        // panic() reboots to bootloader
        panic(); //重启系统
    };
    action.sa_flags = SA_RESTART;
    sigaction(SIGABRT, &action, nullptr);
    sigaction(SIGBUS, &action, nullptr);
    sigaction(SIGFPE, &action, nullptr);
    sigaction(SIGILL, &action, nullptr);
    sigaction(SIGSEGV, &action, nullptr);
#if defined(SIGSTKFLT)
    sigaction(SIGSTKFLT, &action, nullptr);
#endif
    sigaction(SIGSYS, &action, nullptr);
    sigaction(SIGTRAP, &action, nullptr);
}

1.4 add_environment

定义在platform/system/core/init/init.cpp

这个函数主要作用是将一个键值对放到一个Char数组中,如果数组中有key就替换,没有就插入,跟Java中的Map差不多

/* add_environment - add "key=value" to the current environment */
int add_environment(const char *key, const char *val)
{
    size_t n;
    size_t key_len = strlen(key);

    /* The last environment entry is reserved to terminate the list */
    for (n = 0; n < (arraysize(ENV) - 1); n++) {

        /* Delete any existing entry for this key */
        if (ENV[n] != NULL) {
        /*
         * C++中strcspn用于返回字符所在下标,相当于String的indexof
         */
            size_t entry_key_len = strcspn(ENV[n], "=");
            if ((entry_key_len == key_len) && (strncmp(ENV[n], key, entry_key_len) == 0)) { //如果key相同,删除对应数据
                free((char*)ENV[n]);
                ENV[n] = NULL;
            }
        }

        /* Add entry if a free slot is available */
        if (ENV[n] == NULL) { //如果没有对应key,则插入数据
            char* entry;
            asprintf(&entry, "%s=%s", key, val);
            ENV[n] = entry;
            return 0;
        }
    }

    LOG(ERROR) << "No env. room to store: '" << key << "':'" << val << "'";

    return -1;
}

二、 挂载文件系统并创建目录


    bool is_first_stage = (getenv("INIT_SECOND_STAGE") == nullptr);//查看是否有环境变量INIT_SECOND_STAGE

    /*
     * 1.init的main方法会执行两次,由is_first_stage控制,first_stage就是第一阶段要做的事
     */
    if (is_first_stage) {//只执行一次,因为在方法体中有设置INIT_SECOND_STAGE
        boot_clock::time_point start_time = boot_clock::now();

        // 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.
        mount("tmpfs", "/dev", "tmpfs", MS_NOSUID, "mode=0755");
        mkdir("/dev/pts", 0755);
        mkdir("/dev/socket", 0755);
        mount("devpts", "/dev/pts", "devpts", 0, NULL);
        #define MAKE_STR(x) __STRING(x)
        mount("proc", "/proc", "proc", 0, "hidepid=2,gid=" MAKE_STR(AID_READPROC));
        // Don't expose the raw commandline to unprivileged processes.
        chmod("/proc/cmdline", 0440);
        gid_t groups[] = { AID_READPROC };
        setgroups(arraysize(groups), groups);
        mount("sysfs", "/sys", "sysfs", 0, NULL);
        mount("selinuxfs", "/sys/fs/selinux", "selinuxfs", 0, NULL);
        mknod("/dev/kmsg", S_IFCHR | 0600, makedev(1, 11));
        mknod("/dev/random", S_IFCHR | 0666, makedev(1, 8));
        mknod("/dev/urandom", S_IFCHR | 0666, makedev(1, 9));

        ...

    }

   ...


}


2.1 mount

mount是用来挂载文件系统的,mount属于Linux系统调用

int mount(const char *source, const char *target, const char *filesystemtype,
unsigned long mountflags, const void *data);

参数:

source:将要挂上的文件系统,通常是一个设备名。

target:文件系统所要挂载的目标目录。

filesystemtype:文件系统的类型,可以是"ext2","msdos","proc","ntfs","iso9660"。。。

mountflags:指定文件系统的读写访问标志,可能值有以下

参数 含义
MS_BIND 执行bind挂载,使文件或者子目录树在文件系统内的另一个点上可视。
MS_DIRSYNC 同步目录的更新。
MS_MANDLOCK 允许在文件上执行强制锁。
MS_MOVE 移动子目录树。
MS_NOATIME 不要更新文件上的访问时间。
MS_NODEV 不允许访问设备文件。
MS_NODIRATIME 不允许更新目录上的访问时间。
MS_NOEXEC 不允许在挂上的文件系统上执行程序。
MS_NOSUID 执行程序时,不遵照set-user-ID和set-group-ID位。
MS_RDONLY 指定文件系统为只读。
MS_REMOUNT 重新加载文件系统。这允许你改变现存文件系统的mountflag和数据,而无需使用先卸载,再挂上文件系统的方式。
MS_SYNCHRONOUS 同步文件的更新。
MNT_FORCE 强制卸载,即使文件系统处于忙状态。
MNT_EXPIRE 将挂载点标记为过时。

data:文件系统特有的参数







请到「今天看啥」查看全文