Android init 프로세스 시작 프로세스

init는 프로세스입니다. 이것은 linux 시스템에서 사용자 공간의 첫 번째 프로세스입니다. 프로세스 PID는 1이고, 부모 프로세스는 linux입니다. 시스템 내 핵의 0번 프로세스입니다.그래서 매우 중요한 직책을 부여받았고, linux 호스트가 초기화되면 그것을 실행하기 시작했다.
1. init의 핵심 코드를 분석하기 전에 init의 주요 업무를 초보적으로 파악할 수 있다.
  1. Android 시스템에는 많은 속성이 있습니다. init는property 를 제공합니다.서비스 (속성 서비스) 로 그것들을 관리합니다.
  2. 다양한 Action 처리를 포함한 구성 파일 처리 명령(주로 init.rc 파일)
  3. 성능 분석(bootchart 도구 사용).
  4. 무한 순환 실행 command.
2. 코드 경로:\system\core\init\init.c
다음은main 함수로 각 부분에 대한 주석을 포함합니다
int main(int argc, char **argv)
{
  int fd_count = 0;
  struct pollfd ufds[4];
  char *tmpdev;
  char* debuggable;
  char tmp[32];
  int property_set_fd_init = 0;
  int signal_fd_init = 0;
  int keychord_fd_init = 0;
  bool is_charger = false;

  if (!strcmp(basename(argv[0]), "ueventd"))
    return ueventd_main(argc, argv);

  if (!strcmp(basename(argv[0]), "watchdogd"))
    return watchdogd_main(argc, argv);

  /* clear the umask */
  umask(0);

  //          ,  /dev,/proc,/sys 。
  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/.booting           。
  close(open("/dev/.booting", O_WRONLY | O_CREAT, 0000));

  //      、  、        /dev/__null__。
  open_devnull_stdio();
  //  init          /dev/__kmsg__。
  klog_init();
  //            
  property_init();

  get_hardware_name(hardware, &revision);
  
  //        
  process_kernel_cmdline();

  union selinux_callback cb;
  cb.func_log = klog_write;
  selinux_set_callback(SELINUX_CB_LOG, cb);

  cb.func_audit = audit_callback;
  selinux_set_callback(SELINUX_CB_AUDIT, cb);

  selinux_initialize();
  /* These directories were necessarily created before initial policy load
   * and therefore need their security context restored to the proper value.
   * This must happen before /dev is populated by ueventd.
   */
  restorecon("/dev");
  restorecon("/dev/socket");
  restorecon("/dev/__properties__");
  restorecon_recursive("/sys");

  is_charger = !strcmp(bootmode, "charger");

  INFO("property init
"); if (!is_charger) property_load_boot_defaults(); INFO("reading config file
"); // /init.rc init_parse_config_file("/init.rc"); // init.rc , Action 。 // init :early-init,init,early-boot,boot action_for_each_trigger("early-init", action_add_queue_tail); queue_builtin_action(wait_for_coldboot_done_action, "wait_for_coldboot_done"); queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); queue_builtin_action(keychord_init_action, "keychord_init"); queue_builtin_action(console_init_action, "console_init"); /* execute all the boot actions to get us started */ action_for_each_trigger("init", action_add_queue_tail); /* skip mounting filesystems in charger mode */ if (!is_charger) { action_for_each_trigger("early-fs", action_add_queue_tail); action_for_each_trigger("fs", action_add_queue_tail); action_for_each_trigger("post-fs", action_add_queue_tail); action_for_each_trigger("post-fs-data", action_add_queue_tail); } /* Repeat mix_hwrng_into_linux_rng in case /dev/hw_random or /dev/random * wasn't ready immediately after wait_for_coldboot_done */ queue_builtin_action(mix_hwrng_into_linux_rng_action, "mix_hwrng_into_linux_rng"); queue_builtin_action(property_service_init_action, "property_service_init"); queue_builtin_action(signal_init_action, "signal_init"); queue_builtin_action(check_startup_action, "check_startup"); if (is_charger) { action_for_each_trigger("charger", action_add_queue_tail); } else { action_for_each_trigger("early-boot", action_add_queue_tail); action_for_each_trigger("boot", action_add_queue_tail); } /* run all property triggers based on current state of the properties */ queue_builtin_action(queue_property_triggers_action, "queue_property_triggers"); #if BOOTCHART queue_builtin_action(bootchart_init_action, "bootchart_init"); #endif // , init (init ) for(;;) { int nr, i, timeout = -1; execute_one_command(); restart_processes(); 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; } if (!signal_fd_init && get_signal_fd() > 0) { ufds[fd_count].fd = get_signal_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; signal_fd_init = 1; } if (!keychord_fd_init && get_keychord_fd() > 0) { ufds[fd_count].fd = get_keychord_fd(); ufds[fd_count].events = POLLIN; ufds[fd_count].revents = 0; fd_count++; keychord_fd_init = 1; } if (process_needs_restart) { timeout = (process_needs_restart - gettime()) * 1000; if (timeout < 0) timeout = 0; } if (!action_queue_empty() || cur_action) 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; for (i = 0; i < fd_count; i++) { if (ufds[i].revents == POLLIN) { if (ufds[i].fd == get_property_set_fd()) handle_property_set_fd(); else if (ufds[i].fd == get_keychord_fd()) handle_keychord(); else if (ufds[i].fd == get_signal_fd()) handle_signal(); } } } return 0; }

총괄: 본고는 안드로이드의 init 프로세스의 시작 과정을 분석했고 그 중에서 init가 하는 주요 업무는 init를 포함하는 것을 알 수 있다.rc의 해석,property 메커니즘의 실현,서비스 지탱의 실현.

좋은 웹페이지 즐겨찾기