{"id":347,"date":"2018-03-14T09:45:18","date_gmt":"2018-03-14T01:45:18","guid":{"rendered":"http:\/\/www.max-shu.com\/blog\/?p=347"},"modified":"2018-03-14T09:45:18","modified_gmt":"2018-03-14T01:45:18","slug":"linux%e7%9a%84init-main-c","status":"publish","type":"post","link":"http:\/\/www.max-shu.com\/blog\/?p=347","title":{"rendered":"linux\u7684init\/Main.c"},"content":{"rendered":"<div>\u4ecehead-common.S\u8c03\u7528\u4e86start_kernel\u51fd\u6570\uff0c\u5c31\u5b9a\u4e49\u5728\u8fd9\u4e2a\u6587\u4ef6\u4e2d\uff0c\u8fd9\u91cc\u662f\u5185\u6838\u7684c\u51fd\u6570\u5165\u53e3\u70b9\u3002<\/div>\n<div><\/div>\n<div><span style=\"color: #ff00ff;\"><strong>\u8fd9\u91cc\u5bf9\u6574\u4e2a\u7cfb\u7edf\u5185\u5b58\u3001cache\u3001\u4fe1\u53f7\u3001\u8bbe\u5907\u7b49\u8fdb\u884c\u521d\u59cb\u5316\uff0c\u6700\u540e\u751f\u6210init\u8fdb\u7a0b\u540e\uff0c\u8c03\u7528cpu_idle()\u5b8c\u6210\u5185\u6838\u542f\u52a8\u3002<\/strong><\/span><\/div>\n<div><\/div>\n<div>asmlinkage void __init start_kernel(void)<br \/>\n{<br \/>\nchar * command_line;<br \/>\nextern struct kernel_param __start___param[], __stop___param[];<\/p>\n<p>smp_setup_processor_id();<\/p>\n<p>\/*<br \/>\n* Need to run as early as possible, to initialize the<br \/>\n* lockdep hash:<br \/>\n*\/<br \/>\nunwind_init();<br \/>\nlockdep_init();<br \/>\ndebug_objects_early_init();<br \/>\ncgroup_init_early();<\/p>\n<p>local_irq_disable();<br \/>\nearly_boot_irqs_off();<br \/>\nearly_init_irq_lock_class();<\/p>\n<p>\/*<br \/>\n* Interrupts are still disabled. Do necessary setups, then<br \/>\n* enable them<br \/>\n*\/<br \/>\nlock_kernel();<br \/>\ntick_init();<br \/>\nboot_cpu_init();<br \/>\npage_address_init();<br \/>\nprintk(KERN_NOTICE);<br \/>\nprintk(linux_banner);<br \/>\nsetup_arch(&amp;command_line);<br \/>\nmm_init_owner(&amp;init_mm, &amp;init_task);<br \/>\nsetup_command_line(command_line);<br \/>\nunwind_setup();<br \/>\nsetup_per_cpu_areas();<br \/>\nsetup_nr_cpu_ids();<br \/>\nsmp_prepare_boot_cpu();\u00a0\u00a0\u00a0\u00a0 \/* arch-specific boot-cpu hooks *\/<\/p>\n<p>\/*<br \/>\n* Set up the scheduler prior starting any interrupts (such as the<br \/>\n* timer interrupt). Full topology setup happens at smp_init()<br \/>\n* time &#8211; but meanwhile we still have a functioning scheduler.<br \/>\n*\/<br \/>\nsched_init();<br \/>\n\/*<br \/>\n* Disable preemption &#8211; early bootup scheduling is extremely<br \/>\n* fragile until we cpu_idle() for the first time.<br \/>\n*\/<br \/>\npreempt_disable();<br \/>\nbuild_all_zonelists();<br \/>\npage_alloc_init();<br \/>\nprintk(KERN_NOTICE &#8220;Kernel command line: %s\\n&#8221;, boot_command_line);<br \/>\nparse_early_param();<br \/>\nparse_args(&#8220;Booting kernel&#8221;, static_command_line, __start___param,<br \/>\n__stop___param &#8211; __start___param,<br \/>\n&amp;unknown_bootoption);<br \/>\nif (!irqs_disabled()) {<br \/>\nprintk(KERN_WARNING &#8220;start_kernel(): bug: interrupts were &#8221;<br \/>\n&#8220;enabled *very* early, fixing it\\n&#8221;);<br \/>\nlocal_irq_disable();<br \/>\n}<br \/>\nsort_main_extable();<br \/>\ntrap_init();<br \/>\nrcu_init();<br \/>\ninit_IRQ();<br \/>\npidhash_init();<br \/>\ninit_timers();<br \/>\nhrtimers_init();<br \/>\nsoftirq_init();<br \/>\ntimekeeping_init();<br \/>\ntime_init();<br \/>\nsched_clock_init();<br \/>\nprofile_init();<br \/>\nif (!irqs_disabled())<br \/>\nprintk(&#8220;start_kernel(): bug: interrupts were enabled early\\n&#8221;);<br \/>\nearly_boot_irqs_on();<br \/>\nlocal_irq_enable();<\/p>\n<p>\/*<br \/>\n* HACK ALERT! This is early. We&#8217;re enabling the console before<br \/>\n* we&#8217;ve done PCI setups etc, and console_init() must be aware of<br \/>\n* this. But we do want output early, in case something goes wrong.<br \/>\n*\/<br \/>\nconsole_init();<br \/>\nif (panic_later)<br \/>\npanic(panic_later, panic_param);<\/p>\n<p>lockdep_info();<\/p>\n<p>\/*<br \/>\n* Need to run this when irqs are enabled, because it wants<br \/>\n* to self-test [hard\/soft]-irqs on\/off lock inversion bugs<br \/>\n* too:<br \/>\n*\/<br \/>\nlocking_selftest();<\/p>\n<p>#ifdef CONFIG_BLK_DEV_INITRD<br \/>\nif (initrd_start &amp;&amp; !initrd_below_start_ok &amp;&amp;<br \/>\npage_to_pfn(virt_to_page((void *)initrd_start)) &lt; min_low_pfn) {<br \/>\nprintk(KERN_CRIT &#8220;initrd overwritten (0x%08lx &lt; 0x%08lx) &#8211; &#8221;<br \/>\n&#8220;disabling it.\\n&#8221;,<br \/>\npage_to_pfn(virt_to_page((void *)initrd_start)),<br \/>\nmin_low_pfn);<br \/>\ninitrd_start = 0;<br \/>\n}<br \/>\n#endif<br \/>\nvmalloc_init();<br \/>\nvfs_caches_init_early();<br \/>\ncpuset_init_early();<br \/>\npage_cgroup_init();<br \/>\nmem_init();<br \/>\nenable_debug_pagealloc();<br \/>\ncpu_hotplug_init();<br \/>\nkmem_cache_init();<br \/>\ndebug_objects_mem_init();<br \/>\nidr_init_cache();<br \/>\nsetup_per_cpu_pageset();<br \/>\nnuma_policy_init();<br \/>\nif (late_time_init)<br \/>\nlate_time_init();<br \/>\ncalibrate_delay();<br \/>\npidmap_init();<br \/>\npgtable_cache_init();<br \/>\nprio_tree_init();<br \/>\nanon_vma_init();<br \/>\n#ifdef CONFIG_X86<br \/>\nif (efi_enabled)<br \/>\nefi_enter_virtual_mode();<br \/>\n#endif<br \/>\nthread_info_cache_init();<br \/>\nfork_init(num_physpages);<br \/>\nproc_caches_init();<br \/>\nbuffer_init();<br \/>\nkey_init();<br \/>\nsecurity_init();<br \/>\nvfs_caches_init(num_physpages);<br \/>\nradix_tree_init();<br \/>\nsignals_init();<br \/>\n\/* rootfs populating might need page-writeback *\/<br \/>\npage_writeback_init();<br \/>\n#ifdef CONFIG_PROC_FS<br \/>\nproc_root_init();<br \/>\n#endif<br \/>\ncgroup_init();<br \/>\ncpuset_init();<br \/>\ntaskstats_init_early();<br \/>\ndelayacct_init();<\/p>\n<p>check_bugs();<\/p>\n<p>acpi_early_init(); \/* before LAPIC and SMP init *\/<\/p>\n<p>ftrace_init();<\/p>\n<p>\/* Do the rest non-__init&#8217;ed, we&#8217;re now alive *\/<br \/>\nrest_init(); \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/*\u8fdb\u5165\u5269\u4f59\u521d\u59cb\u5316\uff0c\u5c31\u662f\u521d\u59cb\u5316init\u8fdb\u7a0b*\/<br \/>\n}<\/p><\/div>\n<div><\/div>\n<div>static void noinline __init_refok rest_init(void) \u00a0 \/*\u5176\u4f59\u7684\u521d\u59cb\u5316*\/<br \/>\n__releases(kernel_lock)<br \/>\n{<br \/>\nint pid;<\/p>\n<p>kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND); \u00a0 \u00a0\/*\u542f\u52a8init\u8fdb\u7a0b\uff0c\u5165\u53e3\u4e3akernel_init()\u3002*\/<br \/>\nnuma_default_policy();<br \/>\npid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES); \u00a0\/*\u542f\u52a8kthread\u8fdb\u7a0b\uff0c\u5165\u53e3\u4e3akthreadd\uff0c\u5b9a\u4e49\u5728kthread.c\u3002\u5b83\u5c06\u4f1a\u5bf9\u6bcf\u4e2acpu\u5efa\u7acb\u5f88\u591a\u8bbe\u5907\u7684\u5185\u6838\u5b50\u8fdb\u7a0b*\/<br \/>\nkthreadd_task = find_task_by_pid_ns(pid, &amp;init_pid_ns);<br \/>\nunlock_kernel();<\/p>\n<p>\/*<br \/>\n* The boot idle thread must execute schedule()<br \/>\n* at least once to get things moving:<br \/>\n*\/<br \/>\ninit_idle_bootup_task(current);<br \/>\npreempt_enable_no_resched();<br \/>\nschedule();<br \/>\npreempt_disable();<\/p>\n<p>\/* Call into cpu_idle with preempt disabled *\/<br \/>\ncpu_idle(); \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \/*\u8c03\u7528cpu_idle\uff0c\u5373\u8c03\u7528pm_idle\uff0c\u6700\u7ec8\u8c03\u7528cpuidle_idle_call\u3002*\/<br \/>\n}<\/p><\/div>\n<div><\/div>\n<div>static int __init kernel_init(void * unused) \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0 \u00a0\/*init\u8fdb\u7a0b*\/<br \/>\n{<br \/>\nlock_kernel();<br \/>\n\/*<br \/>\n* init can run on any cpu.<br \/>\n*\/<br \/>\nset_cpus_allowed_ptr(current, CPU_MASK_ALL_PTR);<br \/>\n\/*<br \/>\n* Tell the world that we&#8217;re going to be the grim<br \/>\n* reaper of innocent orphaned children.<br \/>\n*<br \/>\n* We don&#8217;t want people to have to make incorrect<br \/>\n* assumptions about where in the task array this<br \/>\n* can be found.<br \/>\n*\/<br \/>\ninit_pid_ns.child_reaper = current;<\/p>\n<p>cad_pid = task_pid(current);<\/p>\n<p>smp_prepare_cpus(setup_max_cpus);<\/p>\n<p>do_pre_smp_initcalls();<br \/>\nstart_boot_trace();<\/p>\n<p>smp_init();<br \/>\nsched_init_smp();<\/p>\n<p>cpuset_init_smp();<\/p>\n<p>do_basic_setup();<\/p>\n<p>\/*<br \/>\n* check if there is an early userspace init.\u00a0 If yes, let it do all<br \/>\n* the work<br \/>\n*\/<\/p>\n<p>if (!ramdisk_execute_command)<br \/>\nramdisk_execute_command = &#8220;\/init&#8221;;<\/p>\n<p>if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {<br \/>\nramdisk_execute_command = NULL;<br \/>\nprepare_namespace();<br \/>\n}<\/p>\n<p>\/*<br \/>\n* Ok, we have completed the initial bootup, and<br \/>\n* we&#8217;re essentially up and running. Get rid of the<br \/>\n* initmem segments and start the user-mode stuff..<br \/>\n*\/<br \/>\nstop_boot_trace();<br \/>\ninit_post();<br \/>\nreturn 0;<br \/>\n}<\/p><\/div>\n<div><\/div>\n<div>static int noinline init_post(void)<br \/>\n{<br \/>\nfree_initmem();<br \/>\nunlock_kernel();<br \/>\nmark_rodata_ro();<br \/>\nsystem_state = SYSTEM_RUNNING;<br \/>\nnuma_default_policy();<\/p>\n<p>if (sys_open((const char __user *) &#8220;\/dev\/console&#8221;, O_RDWR, 0) &lt; 0)<br \/>\nprintk(KERN_WARNING &#8220;Warning: unable to open an initial console.\\n&#8221;);<\/p>\n<p>(void) sys_dup(0);<br \/>\n(void) sys_dup(0);<\/p>\n<p>current-&gt;signal-&gt;flags |= SIGNAL_UNKILLABLE;<\/p>\n<p>if (ramdisk_execute_command) {<br \/>\nrun_init_process(ramdisk_execute_command);<br \/>\nprintk(KERN_WARNING &#8220;Failed to execute %s\\n&#8221;,<br \/>\nramdisk_execute_command);<br \/>\n}<\/p>\n<p>\/*<br \/>\n* We try each of these until one succeeds.<br \/>\n*<br \/>\n* The Bourne shell can be used instead of init if we are<br \/>\n* trying to recover a really broken machine.<br \/>\n*\/<br \/>\nif (execute_command) {<br \/>\nrun_init_process(execute_command);<br \/>\nprintk(KERN_WARNING &#8220;Failed to execute %s.\u00a0 Attempting &#8221;<br \/>\n&#8220;defaults&#8230;\\n&#8221;, execute_command);<br \/>\n}<br \/>\nrun_init_process(&#8220;\/sbin\/init&#8221;);<br \/>\nrun_init_process(&#8220;\/etc\/init&#8221;);<br \/>\nrun_init_process(&#8220;\/bin\/init&#8221;);<br \/>\nrun_init_process(&#8220;\/bin\/sh&#8221;);<\/p>\n<p>panic(&#8220;No init found.\u00a0 Try passing init= option to kernel.&#8221;);<br \/>\n}<\/p><\/div>\n","protected":false},"excerpt":{"rendered":"<p>\u4ecehead-common.S\u8c03\u7528\u4e86start_kernel\u51fd\u6570\uff0c\u5c31\u5b9a\u4e49\u5728\u8fd9\u4e2a\u6587\u4ef6\u4e2d\uff0c\u8fd9\u91cc\u662f\u5185\u6838\u7684c\u51fd\u6570\u5165\u53e3\u70b9\u3002 &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[15],"tags":[9,234,243,244],"class_list":["post-347","post","type-post","status-publish","format-standard","hentry","category-linuxandroid","tag-linux","tag-main-c","tag-243","tag-244"],"views":1670,"_links":{"self":[{"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/347","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=347"}],"version-history":[{"count":1,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/347\/revisions"}],"predecessor-version":[{"id":348,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/347\/revisions\/348"}],"wp:attachment":[{"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=347"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=347"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.max-shu.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=347"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}