📄 main.c
字号:
for_each_present_cpu(i) { if (num_online_cpus() >= max_cpus) break; if (!cpu_online(i)) cpu_up(i); } /* Any cleanup work */ printk("Brought up %ld CPUs\n", (long)num_online_cpus()); smp_cpus_done(max_cpus);#if 0 /* Get other processors into their bootup holding patterns. */ smp_threads_ready=1; smp_commence();#endif}#endif/* * We need to finalize in a non-__init function or else race conditions * between the root thread and the init thread may cause start_kernel to * be reaped by free_initmem before the root thread has proceeded to * cpu_idle. * * gcc-3.4 accidentally inlines this function, so use noinline. */static void noinline rest_init(void){ kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND); numa_default_policy(); unlock_kernel(); cpu_idle();} /* Check for early params. */static int __init do_early_param(char *param, char *val){ struct obs_kernel_param *p; extern struct obs_kernel_param __setup_start, __setup_end; for (p = &__setup_start; p < &__setup_end; p++) { if (p->early && strcmp(param, p->str) == 0) { if (p->setup_func(val) != 0) printk(KERN_WARNING "Malformed early option '%s'\n", param); } } /* We accept everything at this stage. */ return 0;}/* Arch code calls this early on, or if not, just before other parsing. */void __init parse_early_param(void){ static __initdata int done = 0; static __initdata char tmp_cmdline[COMMAND_LINE_SIZE]; if (done) return; /* All fall through to do_early_param. */ strlcpy(tmp_cmdline, saved_command_line, COMMAND_LINE_SIZE); parse_args("early options", tmp_cmdline, NULL, 0, do_early_param); done = 1;}/* * Activate the first processor. */asmlinkage void __init start_kernel(void){ char * command_line; extern struct kernel_param __start___param[], __stop___param[];/* * Interrupts are still disabled. Do necessary setups, then * enable them */ lock_kernel(); page_address_init(); printk(linux_banner); setup_arch(&command_line); setup_per_cpu_areas(); /* * Mark the boot cpu "online" so that it can call console drivers in * printk() and can access its per-cpu storage. */ smp_prepare_boot_cpu(); /* * Set up the scheduler prior starting any interrupts (such as the * timer interrupt). Full topology setup happens at smp_init() * time - but meanwhile we still have a functioning scheduler. */ sched_init(); build_all_zonelists(); page_alloc_init(); printk("Kernel command line: %s\n", saved_command_line); parse_early_param(); parse_args("Booting kernel", command_line, __start___param, __stop___param - __start___param, &unknown_bootoption); sort_main_extable(); trap_init(); rcu_init(); init_IRQ(); pidhash_init(); init_timers(); softirq_init(); time_init(); /* * HACK ALERT! This is early. We're enabling the console before * we've done PCI setups etc, and console_init() must be aware of * this. But we do want output early, in case something goes wrong. */ console_init(); if (panic_later) panic(panic_later, panic_param); profile_init(); local_irq_enable();#ifdef CONFIG_BLK_DEV_INITRD if (initrd_start && !initrd_below_start_ok && initrd_start < min_low_pfn << PAGE_SHIFT) { printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - " "disabling it.\n",initrd_start,min_low_pfn << PAGE_SHIFT); initrd_start = 0; }#endif vfs_caches_init_early(); mem_init(); kmem_cache_init(); numa_policy_init(); if (late_time_init) late_time_init(); calibrate_delay(); pidmap_init(); pgtable_cache_init(); prio_tree_init(); anon_vma_init();#ifdef CONFIG_X86 if (efi_enabled) efi_enter_virtual_mode();#endif fork_init(num_physpages); proc_caches_init(); buffer_init(); unnamed_dev_init(); security_scaffolding_startup(); vfs_caches_init(num_physpages); radix_tree_init(); signals_init(); /* rootfs populating might need page-writeback */ page_writeback_init();#ifdef CONFIG_PROC_FS proc_root_init();#endif check_bugs(); /* * We count on the initial thread going ok * Like idlers init is an unlocked kernel thread, which will * make syscalls (and thus be locked). */ init_idle(current, smp_processor_id()); /* Do the rest non-__init'ed, we're now alive */ rest_init();}static int __initdata initcall_debug;static int __init initcall_debug_setup(char *str){ initcall_debug = 1; return 1;}__setup("initcall_debug", initcall_debug_setup);struct task_struct *child_reaper = &init_task;extern initcall_t __initcall_start, __initcall_end;static void __init do_initcalls(void){ initcall_t *call; int count = preempt_count(); for (call = &__initcall_start; call < &__initcall_end; call++) { char *msg; if (initcall_debug) { printk(KERN_DEBUG "Calling initcall 0x%p", *call); print_symbol(": %s()", (unsigned long) *call); printk("\n"); } (*call)(); msg = NULL; if (preempt_count() != count) { msg = "preemption imbalance"; preempt_count() = count; } if (irqs_disabled()) { msg = "disabled interrupts"; local_irq_enable(); } if (msg) { printk("error in initcall at 0x%p: " "returned with %s\n", *call, msg); } } /* Make sure there is no pending stuff from the initcall sequence */ flush_scheduled_work();}/* * Ok, the machine is now initialized. None of the devices * have been touched yet, but the CPU subsystem is up and * running, and memory and process management works. * * Now we can finally start doing some real work.. */static void __init do_basic_setup(void){ driver_init();#ifdef CONFIG_SYSCTL sysctl_init();#endif /* Networking initialization needs a process context */ sock_init(); init_workqueues(); do_initcalls();}static void do_pre_smp_initcalls(void){ extern int spawn_ksoftirqd(void);#ifdef CONFIG_SMP extern int migration_init(void); migration_init();#endif spawn_ksoftirqd();}static void run_init_process(char *init_filename){ argv_init[0] = init_filename; execve(init_filename, argv_init, envp_init);}static inline void fixup_cpu_present_map(void){#ifdef CONFIG_SMP int i; /* * If arch is not hotplug ready and did not populate * cpu_present_map, just make cpu_present_map same as cpu_possible_map * for other cpu bringup code to function as normal. e.g smp_init() etc. */ if (cpus_empty(cpu_present_map)) { for_each_cpu(i) { cpu_set(i, cpu_present_map); } }#endif}static int init(void * unused){ lock_kernel(); /* * Tell the world that we're going to be the grim * reaper of innocent orphaned children. * * We don't want people to have to make incorrect * assumptions about where in the task array this * can be found. */ child_reaper = current; /* Sets up cpus_possible() */ smp_prepare_cpus(max_cpus); do_pre_smp_initcalls(); fixup_cpu_present_map(); smp_init(); sched_init_smp(); /* * Do this before initcalls, because some drivers want to access * firmware files. */ populate_rootfs(); do_basic_setup(); /* * check if there is an early userspace init. If yes, let it do all * the work */ if (sys_access((const char __user *) "/init", 0) == 0) execute_command = "/init"; else prepare_namespace(); /* * Ok, we have completed the initial bootup, and * we're essentially up and running. Get rid of the * initmem segments and start the user-mode stuff.. */ free_initmem(); unlock_kernel(); system_state = SYSTEM_RUNNING; numa_default_policy(); if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) printk("Warning: unable to open an initial console.\n"); (void) sys_dup(0); (void) sys_dup(0); /* * 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); 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.");}static int early_param_test(char *rest){ printk("early_parm_test: %s\n", rest ?: "(null)"); return rest ? 0 : -EINVAL;}early_param("testsetup", early_param_test);static int early_setup_test(char *rest){ printk("early_setup_test: %s\n", rest ?: "(null)"); return 0;}__setup("testsetup_long", early_setup_test);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -