Init process

The init process is the first user process in the Android system. The process number is 1 and is given many important responsibilities, such as creating Zygote processes and properties services. The init process consists of multiple source files located in the system/core/init directory.

Init process startup process

The first steps of the Android startup process:

  1. Start the power supply and the system

    When the power is pressed, the boot chip code starts execution from a predefined place (solidified in ROM), loads the boot program BootLoader into RAM, and then executes.

  2. Boot program BootLoader

    Is the Android operating system before running a small program, the system OS up and running.

  3. Linux kernel startup

    When the kernel starts, the cache is set up, the protected storage is set, the schedule list is set, and the driver is loaded. After the kernel has finished setting up the system, first look for the init.rc file in the system files and start the init process.

  4. Start the init process

    It is used to initialize and start the properties service, and also to start the Zygote process.

Init entry function

Once the Linux kernel is loaded, the first thing to do is start the init process, first looking for the init.rc file in the system files

File location: the system/core/init/init. CPP.

The main() method of init. CPP

int main(int argc, char** argv) {
    if(! strcmp(basename(argv[0]),"ueventd")) {
        return ueventd_main(argc, argv);
    }
    if(! strcmp(basename(argv[0]),"watchdogd")) {
        return watchdogd_main(argc, argv);
    }
    umask(0);
    add_environment("PATH", _PATH_DEFPATH);
    bool is_first_stage = (argc == 1) || (strcmp(argv[1], "--second-stage")! = 0); //① Create and mount the file directory required for startupif (is_first_stage) {
        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));
        mount("sysfs"."/sys"."sysfs", 0, NULL);
    }
    open_devnull_stdio();
    klog_init();
    klog_set_level(KLOG_NOTICE_LEVEL);
    NOTICE("init %s started! \n", is_first_stage ? "first stage" : "second stage");
    if(! is_first_stage) { // Indicate that booting isin progress to background fw loaders, etc.
        close(open("/dev/.booting", O_WRONLY | O_CREAT | O_CLOEXEC, 0000)); //② property_init() : initializes the property property_init(); process_kernel_dt(); process_kernel_cmdline(); export_kernel_boot_props(); }... //③ start_property_service() : start_property_service(); const BuiltinFunctionMap function_map; Action::set_function_map(&function_map); Parser& parser = Parser::GetInstance(); parser.AddSectionParser("service",std::make_unique<ServiceParser>());
    parser.AddSectionParser("on", std::make_unique<ActionParser>());
    parser.AddSectionParser("import", std::make_unique<ImportParser>()); / / (4) the parse. ParseConfig ("/init.rc"Parser.parseconfig (parser.parser.rc) : parser.parser.parseconfig (parser.parser.rc)"/init.rc"); .while (true) {
        if(! waiting_for_exec) { am.ExecuteOneCommand(); //⑤ restart_processes() : restarts dead processes; } int timeout = -1;if (process_needs_restart) {
            timeout = (process_needs_restart - gettime()) * 1000;
            if (timeout < 0)
                timeout = 0;
        }
        if (am.HasMoreCommands()) {
            timeout = 0;
        }
        bootchart_sample(&timeout);
        epoll_event ev;
        int nr = TEMP_FAILURE_RETRY(epoll_wait(epoll_fd, &ev, 1, timeout));
        if (nr == -1) {
            ERROR("epoll_wait failed: %s\n", strerror(errno));
        } else if(nr == 1) { ((void (*)()) ev.data.ptr)(); }}return 0;
}
Copy the code

In the main() function, ②③ completes the initialization and startup of the property service, ④ parses the init.rc file, and ① mounts the system runtime directory (which disappears when the system stops).

4, parse init.rc file

File location: system/core/init/init_parse.cpp

Init. rc is a very important configuration script file written in the Android initialization language. The Android initialization language contains five types of statements: Action, Service, Command, Option, and Import

The Zygote startup script is defined in init. zygotexx. rc. The 64-bit processor is defined in init. zygote64. rc. Corresponding to the file directory system/core/rootdir/init. Zygote64. Rc

Before starting Zygote, the Service type statement is first parsed and the Service object is added to the Service list

> Zygote > Zygote > Zygote > Zygote

① Zygote classname is main. ② Zygote execution program path is /system/bin/app_process64, corresponding file is app_main.cppCopy the code

Service# init. Rc file will call Start () function (function in the file for the system/core/init/service. The CPP), if the service is running, is no longer Start, otherwise will eventually by execve (…). If the Service is Zygote, the mian() function of app_main.cpp, which is the main() function of Zygote, is used to start the subprocess. The AppRuntime#start() method is then called to start Zygote, which is now started.

5. Attribute services

Windows platform has a registry manager, the contents of the registry in the form of key-value pairs to record some use information of users, software. Even if the system or software is restarted, it can still perform initialization based on previous records in the registry. Android provides a similar mechanism called properties services.

Summary of init process

Having said that, the init process basically does three things: 1. Create some folders and mount device 2. Initialize and start the property service. 3. Parse the init.rc configuration file and start the Zygote process

References:

Android Startup Process (1)