⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 Linux的初始化源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -