Init进程启动.doc_第1页
Init进程启动.doc_第2页
Init进程启动.doc_第3页
Init进程启动.doc_第4页
Init进程启动.doc_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

Init进程启动asmlinkage void _init start_kernel(void).rest_init();static noinline void _init_refok rest_init(void)_releases(kernel_lock)int pid;rcu_scheduler_starting();/* * We need to spawn init first so that it obtains pid 1, however * the init task will end up wanting to create kthreads, which, if * we schedule it before we create kthreadd, will OOPS. */kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);numa_default_policy();pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);rcu_read_lock();kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);rcu_read_unlock();complete(&kthreadd_done);unlock_kernel();/* * The boot idle thread must execute schedule() * at least once to get things moving: */init_idle_bootup_task(current);preempt_enable_no_resched();schedule();preempt_disable();/* Call into cpu_idle with preempt disabled */cpu_idle();static int _init kernel_init(void * unused)/* * Wait until kthreadd is all set-up. */wait_for_completion(&kthreadd_done);lock_kernel();do_basic_setup(); .init_post();return 0;static noinline int init_post(void)_releases(kernel_lock)/* need to finish all async _init code before freeing the memory */async_synchronize_full();free_initmem();unlock_kernel();mark_rodata_ro();system_state = SYSTEM_RUNNING;numa_default_policy();current-signal-flags |= SIGNAL_UNKILLABLE;if (ramdisk_execute_command) run_init_process(ramdisk_execute_command);printk(KERN_WARNING Failed to execute %sn,ramdisk_execute_command);/* * We try each of these until one succeeds. * * The Bourne shell can be used instead of init if we are * trying to recover a really broken machine. */if (execute_command) run_init_process(execute_command);printk(KERN_WARNING Failed to execute %s. Attempting defaults.n, execute_command);run_init_process(/sbin/init);run_init_process(/etc/init);run_init_process(/bin/init);run_init_process(/bin/sh);panic(No init found. Try passing init= option to kernel. See Linux Documentation/init.txt for guidance.);static void run_init_process(char *init_filename)argv_init0 = init_filename;kernel_execve(init_filename, argv_init, envp_init);systemcoreinitinit.cint main(int argc, char *argv) int fd_count = 0; struct pollfd ufds4; char *tmpdev; char* debuggable; char tmp128; int property_set_fd_init = 0; int signal_fd_init = 0; int keychord_fd_init = 0; if (!strcmp(basename(argv0), ueventd) return ueventd_main(argc, argv);int ueventd_main(int argc, char *argv) struct pollfd ufd; int nr; char tmp32; open_devnull_stdio(); log_init(); INFO(starting ueventdn); get_hardware_name(hardware, &revision); ueventd_parse_config_file(/ueventd.rc); snprintf(tmp, sizeof(tmp), /ueventd.%s.rc, hardware); ueventd_parse_config_file(tmp); device_init(); ufd.events = POLLIN; ufd.fd = get_device_fd(); while(1) ufd.revents = 0; nr = poll(&ufd, 1, -1); if (nr = 0) continue; if (ufd.revents = POLLIN) handle_device_fd(); /* clear the umask */umask(0);/创建一些linux根文件系统中的目录,mount一些分区 mkdir(/dev, 0755); mkdir(/proc, 0755); mkdir(/sys, 0755); mount(tmpfs, /dev, tmpfs, 0, 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); /打开标准输入,标准输出,标准错误文件描述符 open_devnull_stdio();/ log 初始化 log_init(); /* initialize array. */ calibration0 = 0;INFO(reading config filen);/读取并且解析init.rc文件init_parse_config_file(/init.rc);int init_parse_config_file(const char *fn) char *data; data = read_file(fn, 0); if (!data) return -1; parse_config(fn, data); DUMP(); return 0;void *read_file(const char *fn, unsigned *_sz) char *data; int sz; int fd; data = 0; fd = open(fn, O_RDONLY); if(fd 0) return 0; sz = lseek(fd, 0, SEEK_END); if(sz 0) goto oops; if(lseek(fd, 0, SEEK_SET) != 0) goto oops; data = (char*) malloc(sz + 2); if(data = 0) goto oops; if(read(fd, data, sz) != sz) goto oops; close(fd); datasz = n; datasz+1 = 0; if(_sz) *_sz = sz; return data;oops: close(fd); if(data != 0) free(data); return 0;static void parse_config(const char *fn, char *s) struct parse_state state; char *argsINIT_PARSER_MAXARGS; int nargs; nargs = 0; state.filename = fn; state.line = 1; state.ptr = s; state.nexttoken = 0; state.parse_line = parse_line_no_op; for (;) switch (next_token(&state) case T_EOF: state.parse_line(&state, 0, 0); return; case T_NEWLINE: if (nargs) int kw = lookup_keyword(args0); if (kw_is(kw, SECTION) state.parse_line(&state, 0, 0); parse_new_section(&state, kw, nargs, args); else state.parse_line(&state, nargs, args); nargs = 0; break; case T_TEXT: if (nargs name, trigger) func(act); void action_add_queue_tail(struct action *act) list_add_tail(&action_queue, &act-qlist); /*把wait_for_coldboot_done_action, property_init_action, keychord_init_action, logo_init_action, console_init_action, set_init_propertyes_action加到action_queue 里*/queue_builtin_action(wait_for_coldboot_done_action, wait_for_coldboot_done);void queue_builtin_action(int (*func)(int nargs, char *args), char *name) struct action *act; struct command *cmd; act = calloc(1, sizeof(*act); act-name = name; list_init(&act-commands); cmd = calloc(1, sizeof(*cmd); cmd-func = func; cmd-args0 = name; list_add_tail(&act-commands, &cmd-clist); list_add_tail(&action_list, &act-alist); action_add_queue_tail(act); queue_builtin_action(property_init_action, property_init); queue_builtin_action(keychord_init_action, keychord_init); queue_builtin_action(console_init_action, console_init); queue_builtin_action(set_init_properties_action, set_init_properties); /触发在init脚本文件中名字为init,early-fs,fs,post-fs的action,并且执行其commandsaction_for_each_trigger(init, action_add_queue_tail); 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);/*把property_service_init_action, signal_init_action, check_startup_action加到action_queue 里*/ 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); /*触发在init脚本文件中名字为early-boot,boot的action,并且执行其commands */ action_for_each_trigger(early-boot, action_add_queue_tail);action_for_each_trigger(boot, action_add_queue_tail);/*把queue_property_triggers_action加到action_queue里*/ queue_builtin_action(queue_property_triggers_action, queue_propety_triggers);#if BOOTCHART queue_builtin_action(bootchart_init_action, bootchart_init);#endifaction触发顺序:early-initinitearly-fsfspost-fsearly-bootboot for(;) int nr, i, timeout = -1; /按序执行action_queue里的action execute_one_command();void execute_one_command(void) int ret; if (!cur_action | !cur_command | is_last_command(cur_action, cur_command) cur_action = action_remove_queue_head(); cur_command = NULL; if (!cur_action) return; INFO(processing action %p (%s)n, cur_action, cur_action-name); cur_command = get_first_command(cur_action); else cur_command = get_next_command(cur_action, cur_command); if (!cur_command) return; ret = cur_command-func(cur_command-nargs, cur_command-args); INFO(command %s r=%dn, cur_command-args0, ret); restart_processes();static void restart_processes() process_needs_restart = 0; service_for_each_flags(SVC_RESTARTING,restart_service_if_needed);void service_for_each_flags(unsigned matchflags, void (*func)(struct service *svc) struct listnode *node; struct service *svc; list_for_each(node, &service_list) svc = node_to_item(node, struct service, slist); if (svc-flags & matchflags) func(svc); static void restart_service_if_needed(struct service *svc) time_t next_start_time = svc-time_started + 5; if (next_start_time flags &= (SVC_RESTARTING); service_start(svc, NULL); return; if (next_start_time 0) ufdsfd_count.fd = get_property_set_fd(); ufdsfd_count.events = POLLIN; ufdsfd_count.revents = 0; fd_count+; property_set_fd_init = 1; if (!signal_fd_init & get_signal_fd() 0) ufdsfd_count.fd = get_signal_fd(); ufdsfd_count.events = POLLIN; ufdsfd_count.revents = 0; fd_count+; signal_fd_init = 1; if (!keychord_fd_init & get_keychord_fd() 0) ufdsfd_count.fd = get_keychord_fd(); ufdsfd_count.events = POLLIN; ufdsfd_count.revents = 0; fd_count+; keychord_fd_init = 1; if (process_needs_restart) timeout = (process_needs_restart - gettime() * 1000; if (timeout 0) if (timeout BOOTCHART_POLLING_MS) timeout = BOOTCHART_POLLING_MS; if (bootchart_step() 0 | -bootchart_count = 0) bootchart_finish(); bootchart_count = 0; #endif /调用poll等待监听事情的发生 nr = poll(ufds, fd_count, timeout); if (nr = 0) continue; for (i = 0; i magic = PROP_AREA_MAGIC; pa-version = PROP_AREA_VERSION; /* plug into the lib property services */ _system_property_area_ = pa; property_area_inited = 1; return 0;3) keychord_init_actionstatic int keychord_init_action(int nargs, char *args) keychord_init(); return 0;void keychord_init() int fd, ret; service_for_each(add_service_keycodes); /* nothing to do if no services require keychords */ if (!keychords) return; fd = open(/dev/keychord, O_RDWR); if (fd = 0) have_console = 1; close(fd); #define INIT_IMAGE_FILE/initlogo.rle if( load_565rle_image(INIT_IMAGE_FILE) ) fd = open(/dev/tty0, O_WRONLY); if (fd = 0) const char *msg; msg = n n n n n n n / console is 40 cols x 30 lines n n n n n n n A N D R O I D ; write(fd, msg, strlen(msg); close(fd); return 0;5) set_init_properties_actionstatic int set_init_properties_action(int nargs, char *args) char tmpPROP_VALUE_MAX; if (qemu0) import_kernel_cmdline(1); if (calibration0) PRINT(#: set ro.calibration 1.n); property_set(ro.calibration, 1); else PRINT(#: set ro.calibration 0.n); property_set(ro.calibration, 0); /* In fastsleep mode. */ if (!strcmp(bootmode,fastsleep) PRINT(#: fastsleep mode.n); PRINT(#: fastsleep mode.n); PRINT(#: fastsleep mode.n); property_set(ro.fastsleep, 1); fastsleep_enable = 1; if (!strcmp(bootmode,factory) property_set(ro.factorytest, 1); else if (!strcmp(bootmode,factory2) property_set(ro.factorytest, 2); else property_set(ro.factorytest, 0); property_set(ro.serialno, serialno0 ? serialno : ); property_set(ro.bootmode, bootmode0 ? bootmode : unknown); property_set(ro.baseband, baseband0 ? baseband : unknown); property_set(ro.carrier, carrier0 ? carrier : unknown); property_set(ro.bootloader, bootloader0 ? bootloader : unknown); property_set(ro.hardware, hardware); snprintf(tmp, PROP_VALUE_MAX, %d, revision); property_set(ro.revision, tmp); return 0;6) property_service_init_actionstatic int property_service_init_action(int nargs, char *args) start_property_service(); return 0;void start_property_service(void) int fd;#define PROP_PATH_RAMDISK_DEFAULT /p#define PROP_PATH_SYSTEM_BUILD /system/p#define PROP_PATH_SYSTEM_DEFAULT /system/p#define PROP_PATH_LOCAL_OVERRIDE /data/p load_properties_from_file(PROP_PATH_SYSTEM_BUILD); load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT); load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE); /* Read persistent properties after all default values have been loaded. */ load_persistent_properties(); fd = create

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论