xref: /linux-6.15/init/main.c (revision 31a67102)
11da177e4SLinus Torvalds /*
21da177e4SLinus Torvalds  *  linux/init/main.c
31da177e4SLinus Torvalds  *
41da177e4SLinus Torvalds  *  Copyright (C) 1991, 1992  Linus Torvalds
51da177e4SLinus Torvalds  *
61da177e4SLinus Torvalds  *  GK 2/5/95  -  Changed to support mounting root fs via NFS
71da177e4SLinus Torvalds  *  Added initrd & change_root: Werner Almesberger & Hans Lermen, Feb '96
81da177e4SLinus Torvalds  *  Moan early if gcc is old, avoiding bogus kernels - Paul Gortmaker, May '96
91da177e4SLinus Torvalds  *  Simplified starting of init:  Michael A. Griffith <[email protected]>
101da177e4SLinus Torvalds  */
111da177e4SLinus Torvalds 
121da177e4SLinus Torvalds #include <linux/types.h>
131da177e4SLinus Torvalds #include <linux/module.h>
141da177e4SLinus Torvalds #include <linux/proc_fs.h>
151da177e4SLinus Torvalds #include <linux/kernel.h>
161da177e4SLinus Torvalds #include <linux/syscalls.h>
179b5609fdSIngo Molnar #include <linux/stackprotector.h>
181da177e4SLinus Torvalds #include <linux/string.h>
191da177e4SLinus Torvalds #include <linux/ctype.h>
201da177e4SLinus Torvalds #include <linux/delay.h>
211da177e4SLinus Torvalds #include <linux/ioport.h>
221da177e4SLinus Torvalds #include <linux/init.h>
231da177e4SLinus Torvalds #include <linux/initrd.h>
241da177e4SLinus Torvalds #include <linux/bootmem.h>
254a7a16dcSLen Brown #include <linux/acpi.h>
261da177e4SLinus Torvalds #include <linux/tty.h>
271da177e4SLinus Torvalds #include <linux/percpu.h>
281da177e4SLinus Torvalds #include <linux/kmod.h>
29db64fe02SNick Piggin #include <linux/vmalloc.h>
301da177e4SLinus Torvalds #include <linux/kernel_stat.h>
31d7cd5611SRusty Russell #include <linux/start_kernel.h>
321da177e4SLinus Torvalds #include <linux/security.h>
333d442233SJens Axboe #include <linux/smp.h>
341da177e4SLinus Torvalds #include <linux/profile.h>
351da177e4SLinus Torvalds #include <linux/rcupdate.h>
361da177e4SLinus Torvalds #include <linux/moduleparam.h>
371da177e4SLinus Torvalds #include <linux/kallsyms.h>
381da177e4SLinus Torvalds #include <linux/writeback.h>
391da177e4SLinus Torvalds #include <linux/cpu.h>
401da177e4SLinus Torvalds #include <linux/cpuset.h>
41ddbcc7e8SPaul Menage #include <linux/cgroup.h>
421da177e4SLinus Torvalds #include <linux/efi.h>
43906568c9SThomas Gleixner #include <linux/tick.h>
446168a702SAndrew Morton #include <linux/interrupt.h>
45c757249aSShailabh Nagar #include <linux/taskstats_kern.h>
46ca74e92bSShailabh Nagar #include <linux/delayacct.h>
471da177e4SLinus Torvalds #include <linux/unistd.h>
481da177e4SLinus Torvalds #include <linux/rmap.h>
491da177e4SLinus Torvalds #include <linux/mempolicy.h>
501da177e4SLinus Torvalds #include <linux/key.h>
51b6cd0b77SAdrian Bunk #include <linux/buffer_head.h>
5294b6da5aSKAMEZAWA Hiroyuki #include <linux/page_cgroup.h>
539a11b49aSIngo Molnar #include <linux/debug_locks.h>
543ac7fe5aSThomas Gleixner #include <linux/debugobjects.h>
55fbb9ce95SIngo Molnar #include <linux/lockdep.h>
563c7b4e6bSCatalin Marinas #include <linux/kmemleak.h>
5784d73786SSukadev Bhattiprolu #include <linux/pid_namespace.h>
581f21782eSAdrian Bunk #include <linux/device.h>
5973c27992SEric W. Biederman #include <linux/kthread.h>
60e6fe6649SAdrian Bunk #include <linux/sched.h>
61a1c9eea9SAdrian Bunk #include <linux/signal.h>
62199f0ca5SAkinobu Mita #include <linux/idr.h>
630b4b3827SJason Wessel #include <linux/kgdb.h>
6468bf21aaSSteven Rostedt #include <linux/ftrace.h>
6522a9d645SArjan van de Ven #include <linux/async.h>
66dfec072eSVegard Nossum #include <linux/kmemcheck.h>
676ae6996aSFeng Tang #include <linux/sfi.h>
682b2af54aSKay Sievers #include <linux/shmem_fs.h>
695a0e3ad6STejun Heo #include <linux/slab.h>
7024a24bb6SPeter Zijlstra #include <linux/perf_event.h>
711da177e4SLinus Torvalds 
721da177e4SLinus Torvalds #include <asm/io.h>
731da177e4SLinus Torvalds #include <asm/bugs.h>
741da177e4SLinus Torvalds #include <asm/setup.h>
75a940199fSAndi Kleen #include <asm/sections.h>
7637b73c82SArjan van de Ven #include <asm/cacheflush.h>
771da177e4SLinus Torvalds 
781da177e4SLinus Torvalds #ifdef CONFIG_X86_LOCAL_APIC
791da177e4SLinus Torvalds #include <asm/smp.h>
801da177e4SLinus Torvalds #endif
811da177e4SLinus Torvalds 
82aae5f662SSam Ravnborg static int kernel_init(void *);
831da177e4SLinus Torvalds 
841da177e4SLinus Torvalds extern void init_IRQ(void);
851da177e4SLinus Torvalds extern void fork_init(unsigned long);
861da177e4SLinus Torvalds extern void mca_init(void);
871da177e4SLinus Torvalds extern void sbus_init(void);
881da177e4SLinus Torvalds extern void prio_tree_init(void);
891da177e4SLinus Torvalds extern void radix_tree_init(void);
9037b73c82SArjan van de Ven #ifndef CONFIG_DEBUG_RODATA
9137b73c82SArjan van de Ven static inline void mark_rodata_ro(void) { }
9237b73c82SArjan van de Ven #endif
931da177e4SLinus Torvalds 
941da177e4SLinus Torvalds #ifdef CONFIG_TC
951da177e4SLinus Torvalds extern void tc_init(void);
961da177e4SLinus Torvalds #endif
971da177e4SLinus Torvalds 
982ce802f6STejun Heo /*
992ce802f6STejun Heo  * Debug helper: via this flag we know that we are in 'early bootup code'
1002ce802f6STejun Heo  * where only the boot processor is running with IRQ disabled.  This means
1012ce802f6STejun Heo  * two things - IRQ must not be enabled before the flag is cleared and some
1022ce802f6STejun Heo  * operations which are not allowed with IRQ disabled are allowed while the
1032ce802f6STejun Heo  * flag is set.
1042ce802f6STejun Heo  */
1052ce802f6STejun Heo bool early_boot_irqs_disabled __read_mostly;
1062ce802f6STejun Heo 
107a6826048SPaul E. McKenney enum system_states system_state __read_mostly;
1081da177e4SLinus Torvalds EXPORT_SYMBOL(system_state);
1091da177e4SLinus Torvalds 
1101da177e4SLinus Torvalds /*
1111da177e4SLinus Torvalds  * Boot command-line arguments
1121da177e4SLinus Torvalds  */
1131da177e4SLinus Torvalds #define MAX_INIT_ARGS CONFIG_INIT_ENV_ARG_LIMIT
1141da177e4SLinus Torvalds #define MAX_INIT_ENVS CONFIG_INIT_ENV_ARG_LIMIT
1151da177e4SLinus Torvalds 
1161da177e4SLinus Torvalds extern void time_init(void);
1171da177e4SLinus Torvalds /* Default late time init is NULL. archs can override this later. */
118d2e3192bSJan Beulich void (*__initdata late_time_init)(void);
1191da177e4SLinus Torvalds extern void softirq_init(void);
1201da177e4SLinus Torvalds 
12130d7e0d4SAlon Bar-Lev /* Untouched command line saved by arch-specific code. */
12230d7e0d4SAlon Bar-Lev char __initdata boot_command_line[COMMAND_LINE_SIZE];
12330d7e0d4SAlon Bar-Lev /* Untouched saved command line (eg. for /proc) */
12430d7e0d4SAlon Bar-Lev char *saved_command_line;
12530d7e0d4SAlon Bar-Lev /* Command line for parameter parsing */
12630d7e0d4SAlon Bar-Lev static char *static_command_line;
1271da177e4SLinus Torvalds 
1281da177e4SLinus Torvalds static char *execute_command;
129ffdfc409SOlof Johansson static char *ramdisk_execute_command;
1301da177e4SLinus Torvalds 
1318b3b2955SJan Beulich /*
1328b3b2955SJan Beulich  * If set, this is an indication to the drivers that reset the underlying
1338b3b2955SJan Beulich  * device before going ahead with the initialization otherwise driver might
1348b3b2955SJan Beulich  * rely on the BIOS and skip the reset operation.
1358b3b2955SJan Beulich  *
1368b3b2955SJan Beulich  * This is useful if kernel is booting in an unreliable environment.
1378b3b2955SJan Beulich  * For ex. kdump situaiton where previous kernel has crashed, BIOS has been
1388b3b2955SJan Beulich  * skipped and devices will be in unknown state.
1398b3b2955SJan Beulich  */
1408b3b2955SJan Beulich unsigned int reset_devices;
1418b3b2955SJan Beulich EXPORT_SYMBOL(reset_devices);
1421da177e4SLinus Torvalds 
1437e96287dSVivek Goyal static int __init set_reset_devices(char *str)
1447e96287dSVivek Goyal {
1457e96287dSVivek Goyal 	reset_devices = 1;
1467e96287dSVivek Goyal 	return 1;
1477e96287dSVivek Goyal }
1487e96287dSVivek Goyal 
1497e96287dSVivek Goyal __setup("reset_devices", set_reset_devices);
1507e96287dSVivek Goyal 
151d7627467SDavid Howells static const char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
152d7627467SDavid Howells const char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
1531da177e4SLinus Torvalds static const char *panic_later, *panic_param;
1541da177e4SLinus Torvalds 
155914dcaa8SRusty Russell extern const struct obs_kernel_param __setup_start[], __setup_end[];
1561da177e4SLinus Torvalds 
1571da177e4SLinus Torvalds static int __init obsolete_checksetup(char *line)
1581da177e4SLinus Torvalds {
159914dcaa8SRusty Russell 	const struct obs_kernel_param *p;
16033df0d19SRusty Russell 	int had_early_param = 0;
1611da177e4SLinus Torvalds 
1621da177e4SLinus Torvalds 	p = __setup_start;
1631da177e4SLinus Torvalds 	do {
1641da177e4SLinus Torvalds 		int n = strlen(p->str);
165b1e4d20cSMichal Schmidt 		if (parameqn(line, p->str, n)) {
1661da177e4SLinus Torvalds 			if (p->early) {
16733df0d19SRusty Russell 				/* Already done in parse_early_param?
16833df0d19SRusty Russell 				 * (Needs exact match on param part).
16933df0d19SRusty Russell 				 * Keep iterating, as we can have early
17033df0d19SRusty Russell 				 * params and __setups of same names 8( */
1711da177e4SLinus Torvalds 				if (line[n] == '\0' || line[n] == '=')
17233df0d19SRusty Russell 					had_early_param = 1;
1731da177e4SLinus Torvalds 			} else if (!p->setup_func) {
1741da177e4SLinus Torvalds 				printk(KERN_WARNING "Parameter %s is obsolete,"
1751da177e4SLinus Torvalds 				       " ignored\n", p->str);
1761da177e4SLinus Torvalds 				return 1;
1771da177e4SLinus Torvalds 			} else if (p->setup_func(line + n))
1781da177e4SLinus Torvalds 				return 1;
1791da177e4SLinus Torvalds 		}
1801da177e4SLinus Torvalds 		p++;
1811da177e4SLinus Torvalds 	} while (p < __setup_end);
18233df0d19SRusty Russell 
18333df0d19SRusty Russell 	return had_early_param;
1841da177e4SLinus Torvalds }
1851da177e4SLinus Torvalds 
1861da177e4SLinus Torvalds /*
1871da177e4SLinus Torvalds  * This should be approx 2 Bo*oMips to start (note initial shift), and will
1881da177e4SLinus Torvalds  * still work even if initially too large, it will just take slightly longer
1891da177e4SLinus Torvalds  */
1901da177e4SLinus Torvalds unsigned long loops_per_jiffy = (1<<12);
1911da177e4SLinus Torvalds 
1921da177e4SLinus Torvalds EXPORT_SYMBOL(loops_per_jiffy);
1931da177e4SLinus Torvalds 
1941da177e4SLinus Torvalds static int __init debug_kernel(char *str)
1951da177e4SLinus Torvalds {
1961da177e4SLinus Torvalds 	console_loglevel = 10;
197f6f21c81SYinghai Lu 	return 0;
1981da177e4SLinus Torvalds }
1991da177e4SLinus Torvalds 
2001da177e4SLinus Torvalds static int __init quiet_kernel(char *str)
2011da177e4SLinus Torvalds {
2021da177e4SLinus Torvalds 	console_loglevel = 4;
203f6f21c81SYinghai Lu 	return 0;
2041da177e4SLinus Torvalds }
2051da177e4SLinus Torvalds 
206f6f21c81SYinghai Lu early_param("debug", debug_kernel);
207f6f21c81SYinghai Lu early_param("quiet", quiet_kernel);
2081da177e4SLinus Torvalds 
2091da177e4SLinus Torvalds static int __init loglevel(char *str)
2101da177e4SLinus Torvalds {
211808bf29bSAlexander Sverdlin 	int newlevel;
212808bf29bSAlexander Sverdlin 
213808bf29bSAlexander Sverdlin 	/*
214808bf29bSAlexander Sverdlin 	 * Only update loglevel value when a correct setting was passed,
215808bf29bSAlexander Sverdlin 	 * to prevent blind crashes (when loglevel being set to 0) that
216808bf29bSAlexander Sverdlin 	 * are quite hard to debug
217808bf29bSAlexander Sverdlin 	 */
218808bf29bSAlexander Sverdlin 	if (get_option(&str, &newlevel)) {
219808bf29bSAlexander Sverdlin 		console_loglevel = newlevel;
220d9d4fcfeSAlex Riesen 		return 0;
2211da177e4SLinus Torvalds 	}
2221da177e4SLinus Torvalds 
223808bf29bSAlexander Sverdlin 	return -EINVAL;
224808bf29bSAlexander Sverdlin }
225808bf29bSAlexander Sverdlin 
226f6f21c81SYinghai Lu early_param("loglevel", loglevel);
2271da177e4SLinus Torvalds 
2281da177e4SLinus Torvalds /* Change NUL term back to "=", to make "param" the whole string. */
229a99cd112SChris Metcalf static int __init repair_env_string(char *param, char *val)
230a99cd112SChris Metcalf {
2311da177e4SLinus Torvalds 	if (val) {
2321da177e4SLinus Torvalds 		/* param=val or param="val"? */
2331da177e4SLinus Torvalds 		if (val == param+strlen(param)+1)
2341da177e4SLinus Torvalds 			val[-1] = '=';
2351da177e4SLinus Torvalds 		else if (val == param+strlen(param)+2) {
2361da177e4SLinus Torvalds 			val[-2] = '=';
2371da177e4SLinus Torvalds 			memmove(val-1, val, strlen(val)+1);
2381da177e4SLinus Torvalds 			val--;
2391da177e4SLinus Torvalds 		} else
2401da177e4SLinus Torvalds 			BUG();
2411da177e4SLinus Torvalds 	}
242a99cd112SChris Metcalf 	return 0;
243a99cd112SChris Metcalf }
244a99cd112SChris Metcalf 
245a99cd112SChris Metcalf /*
246a99cd112SChris Metcalf  * Unknown boot options get handed to init, unless they look like
247a99cd112SChris Metcalf  * unused parameters (modprobe will find them in /proc/cmdline).
248a99cd112SChris Metcalf  */
249a99cd112SChris Metcalf static int __init unknown_bootoption(char *param, char *val)
250a99cd112SChris Metcalf {
251a99cd112SChris Metcalf 	repair_env_string(param, val);
2521da177e4SLinus Torvalds 
2531da177e4SLinus Torvalds 	/* Handle obsolete-style parameters */
2541da177e4SLinus Torvalds 	if (obsolete_checksetup(param))
2551da177e4SLinus Torvalds 		return 0;
2561da177e4SLinus Torvalds 
257f066a4f6SRusty Russell 	/* Unused module parameter. */
258f066a4f6SRusty Russell 	if (strchr(param, '.') && (!val || strchr(param, '.') < val))
2591da177e4SLinus Torvalds 		return 0;
2601da177e4SLinus Torvalds 
2611da177e4SLinus Torvalds 	if (panic_later)
2621da177e4SLinus Torvalds 		return 0;
2631da177e4SLinus Torvalds 
2641da177e4SLinus Torvalds 	if (val) {
2651da177e4SLinus Torvalds 		/* Environment option */
2661da177e4SLinus Torvalds 		unsigned int i;
2671da177e4SLinus Torvalds 		for (i = 0; envp_init[i]; i++) {
2681da177e4SLinus Torvalds 			if (i == MAX_INIT_ENVS) {
2691da177e4SLinus Torvalds 				panic_later = "Too many boot env vars at `%s'";
2701da177e4SLinus Torvalds 				panic_param = param;
2711da177e4SLinus Torvalds 			}
2721da177e4SLinus Torvalds 			if (!strncmp(param, envp_init[i], val - param))
2731da177e4SLinus Torvalds 				break;
2741da177e4SLinus Torvalds 		}
2751da177e4SLinus Torvalds 		envp_init[i] = param;
2761da177e4SLinus Torvalds 	} else {
2771da177e4SLinus Torvalds 		/* Command line option */
2781da177e4SLinus Torvalds 		unsigned int i;
2791da177e4SLinus Torvalds 		for (i = 0; argv_init[i]; i++) {
2801da177e4SLinus Torvalds 			if (i == MAX_INIT_ARGS) {
2811da177e4SLinus Torvalds 				panic_later = "Too many boot init vars at `%s'";
2821da177e4SLinus Torvalds 				panic_param = param;
2831da177e4SLinus Torvalds 			}
2841da177e4SLinus Torvalds 		}
2851da177e4SLinus Torvalds 		argv_init[i] = param;
2861da177e4SLinus Torvalds 	}
2871da177e4SLinus Torvalds 	return 0;
2881da177e4SLinus Torvalds }
2891da177e4SLinus Torvalds 
2901da177e4SLinus Torvalds static int __init init_setup(char *str)
2911da177e4SLinus Torvalds {
2921da177e4SLinus Torvalds 	unsigned int i;
2931da177e4SLinus Torvalds 
2941da177e4SLinus Torvalds 	execute_command = str;
2951da177e4SLinus Torvalds 	/*
2961da177e4SLinus Torvalds 	 * In case LILO is going to boot us with default command line,
2971da177e4SLinus Torvalds 	 * it prepends "auto" before the whole cmdline which makes
2981da177e4SLinus Torvalds 	 * the shell think it should execute a script with such name.
2991da177e4SLinus Torvalds 	 * So we ignore all arguments entered _before_ init=... [MJ]
3001da177e4SLinus Torvalds 	 */
3011da177e4SLinus Torvalds 	for (i = 1; i < MAX_INIT_ARGS; i++)
3021da177e4SLinus Torvalds 		argv_init[i] = NULL;
3031da177e4SLinus Torvalds 	return 1;
3041da177e4SLinus Torvalds }
3051da177e4SLinus Torvalds __setup("init=", init_setup);
3061da177e4SLinus Torvalds 
307ffdfc409SOlof Johansson static int __init rdinit_setup(char *str)
308ffdfc409SOlof Johansson {
309ffdfc409SOlof Johansson 	unsigned int i;
310ffdfc409SOlof Johansson 
311ffdfc409SOlof Johansson 	ramdisk_execute_command = str;
312ffdfc409SOlof Johansson 	/* See "auto" comment in init_setup */
313ffdfc409SOlof Johansson 	for (i = 1; i < MAX_INIT_ARGS; i++)
314ffdfc409SOlof Johansson 		argv_init[i] = NULL;
315ffdfc409SOlof Johansson 	return 1;
316ffdfc409SOlof Johansson }
317ffdfc409SOlof Johansson __setup("rdinit=", rdinit_setup);
318ffdfc409SOlof Johansson 
3191da177e4SLinus Torvalds #ifndef CONFIG_SMP
32034db18a0SAmerigo Wang static const unsigned int setup_max_cpus = NR_CPUS;
3211da177e4SLinus Torvalds #ifdef CONFIG_X86_LOCAL_APIC
3221da177e4SLinus Torvalds static void __init smp_init(void)
3231da177e4SLinus Torvalds {
3241da177e4SLinus Torvalds 	APIC_init_uniprocessor();
3251da177e4SLinus Torvalds }
3261da177e4SLinus Torvalds #else
3271da177e4SLinus Torvalds #define smp_init()	do { } while (0)
3281da177e4SLinus Torvalds #endif
3291da177e4SLinus Torvalds 
330e0982e90SMike Travis static inline void setup_nr_cpu_ids(void) { }
3311da177e4SLinus Torvalds static inline void smp_prepare_cpus(unsigned int maxcpus) { }
3321da177e4SLinus Torvalds #endif
3331da177e4SLinus Torvalds 
3341da177e4SLinus Torvalds /*
33530d7e0d4SAlon Bar-Lev  * We need to store the untouched command line for future reference.
33630d7e0d4SAlon Bar-Lev  * We also need to store the touched command line since the parameter
33730d7e0d4SAlon Bar-Lev  * parsing is performed in place, and we should allow a component to
33830d7e0d4SAlon Bar-Lev  * store reference of name/value for future reference.
33930d7e0d4SAlon Bar-Lev  */
34030d7e0d4SAlon Bar-Lev static void __init setup_command_line(char *command_line)
34130d7e0d4SAlon Bar-Lev {
34230d7e0d4SAlon Bar-Lev 	saved_command_line = alloc_bootmem(strlen (boot_command_line)+1);
34330d7e0d4SAlon Bar-Lev 	static_command_line = alloc_bootmem(strlen (command_line)+1);
34430d7e0d4SAlon Bar-Lev 	strcpy (saved_command_line, boot_command_line);
34530d7e0d4SAlon Bar-Lev 	strcpy (static_command_line, command_line);
34630d7e0d4SAlon Bar-Lev }
34730d7e0d4SAlon Bar-Lev 
34830d7e0d4SAlon Bar-Lev /*
3491da177e4SLinus Torvalds  * We need to finalize in a non-__init function or else race conditions
3501da177e4SLinus Torvalds  * between the root thread and the init thread may cause start_kernel to
3511da177e4SLinus Torvalds  * be reaped by free_initmem before the root thread has proceeded to
3521da177e4SLinus Torvalds  * cpu_idle.
3531da177e4SLinus Torvalds  *
3541da177e4SLinus Torvalds  * gcc-3.4 accidentally inlines this function, so use noinline.
3551da177e4SLinus Torvalds  */
3561da177e4SLinus Torvalds 
357b433c3d4SPeter Zijlstra static __initdata DECLARE_COMPLETION(kthreadd_done);
358b433c3d4SPeter Zijlstra 
359f99ebf0aSRakib Mullick static noinline void __init_refok rest_init(void)
3601da177e4SLinus Torvalds {
36173c27992SEric W. Biederman 	int pid;
36273c27992SEric W. Biederman 
3637db905e6SPaul E. McKenney 	rcu_scheduler_starting();
364b433c3d4SPeter Zijlstra 	/*
36597158569SPeter Zijlstra 	 * We need to spawn init first so that it obtains pid 1, however
366b433c3d4SPeter Zijlstra 	 * the init task will end up wanting to create kthreads, which, if
367b433c3d4SPeter Zijlstra 	 * we schedule it before we create kthreadd, will OOPS.
368b433c3d4SPeter Zijlstra 	 */
369aae5f662SSam Ravnborg 	kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
3701da177e4SLinus Torvalds 	numa_default_policy();
37173c27992SEric W. Biederman 	pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
372d11c563dSPaul E. McKenney 	rcu_read_lock();
3735cd20455SPavel Emelyanov 	kthreadd_task = find_task_by_pid_ns(pid, &init_pid_ns);
374d11c563dSPaul E. McKenney 	rcu_read_unlock();
375b433c3d4SPeter Zijlstra 	complete(&kthreadd_done);
376f340c0d1SIngo Molnar 
377f340c0d1SIngo Molnar 	/*
378f340c0d1SIngo Molnar 	 * The boot idle thread must execute schedule()
3791df21055SIngo Molnar 	 * at least once to get things moving:
380f340c0d1SIngo Molnar 	 */
3811df21055SIngo Molnar 	init_idle_bootup_task(current);
382bd2f5536SThomas Gleixner 	schedule_preempt_disabled();
3835bfb5d69SNick Piggin 	/* Call into cpu_idle with preempt disabled */
3841da177e4SLinus Torvalds 	cpu_idle();
3851da177e4SLinus Torvalds }
3861da177e4SLinus Torvalds 
3871da177e4SLinus Torvalds /* Check for early params. */
3881da177e4SLinus Torvalds static int __init do_early_param(char *param, char *val)
3891da177e4SLinus Torvalds {
390914dcaa8SRusty Russell 	const struct obs_kernel_param *p;
3911da177e4SLinus Torvalds 
3921da177e4SLinus Torvalds 	for (p = __setup_start; p < __setup_end; p++) {
393b1e4d20cSMichal Schmidt 		if ((p->early && parameq(param, p->str)) ||
39418a8bd94SYinghai Lu 		    (strcmp(param, "console") == 0 &&
39518a8bd94SYinghai Lu 		     strcmp(p->str, "earlycon") == 0)
39618a8bd94SYinghai Lu 		) {
3971da177e4SLinus Torvalds 			if (p->setup_func(val) != 0)
3981da177e4SLinus Torvalds 				printk(KERN_WARNING
3991da177e4SLinus Torvalds 				       "Malformed early option '%s'\n", param);
4001da177e4SLinus Torvalds 		}
4011da177e4SLinus Torvalds 	}
4021da177e4SLinus Torvalds 	/* We accept everything at this stage. */
4031da177e4SLinus Torvalds 	return 0;
4041da177e4SLinus Torvalds }
4051da177e4SLinus Torvalds 
40613977091SMagnus Damm void __init parse_early_options(char *cmdline)
40713977091SMagnus Damm {
408026cee00SPawel Moll 	parse_args("early options", cmdline, NULL, 0, 0, 0, do_early_param);
40913977091SMagnus Damm }
41013977091SMagnus Damm 
4111da177e4SLinus Torvalds /* Arch code calls this early on, or if not, just before other parsing. */
4121da177e4SLinus Torvalds void __init parse_early_param(void)
4131da177e4SLinus Torvalds {
4141da177e4SLinus Torvalds 	static __initdata int done = 0;
4151da177e4SLinus Torvalds 	static __initdata char tmp_cmdline[COMMAND_LINE_SIZE];
4161da177e4SLinus Torvalds 
4171da177e4SLinus Torvalds 	if (done)
4181da177e4SLinus Torvalds 		return;
4191da177e4SLinus Torvalds 
4201da177e4SLinus Torvalds 	/* All fall through to do_early_param. */
42130d7e0d4SAlon Bar-Lev 	strlcpy(tmp_cmdline, boot_command_line, COMMAND_LINE_SIZE);
42213977091SMagnus Damm 	parse_early_options(tmp_cmdline);
4231da177e4SLinus Torvalds 	done = 1;
4241da177e4SLinus Torvalds }
4251da177e4SLinus Torvalds 
4261da177e4SLinus Torvalds /*
4271da177e4SLinus Torvalds  *	Activate the first processor.
4281da177e4SLinus Torvalds  */
4291da177e4SLinus Torvalds 
43044fd2299SStas Sergeev static void __init boot_cpu_init(void)
43144fd2299SStas Sergeev {
43244fd2299SStas Sergeev 	int cpu = smp_processor_id();
43344fd2299SStas Sergeev 	/* Mark the boot cpu "present", "online" etc for SMP and UP case */
434915441b6SRusty Russell 	set_cpu_online(cpu, true);
435933b0618SPeter Zijlstra 	set_cpu_active(cpu, true);
436915441b6SRusty Russell 	set_cpu_present(cpu, true);
437915441b6SRusty Russell 	set_cpu_possible(cpu, true);
43844fd2299SStas Sergeev }
43944fd2299SStas Sergeev 
440839ad62eSBenjamin Herrenschmidt void __init __weak smp_setup_processor_id(void)
441033ab7f8SAndrew Morton {
442033ab7f8SAndrew Morton }
443033ab7f8SAndrew Morton 
4448c9843e5SBenjamin Herrenschmidt void __init __weak thread_info_cache_init(void)
4458c9843e5SBenjamin Herrenschmidt {
4468c9843e5SBenjamin Herrenschmidt }
4478c9843e5SBenjamin Herrenschmidt 
448444f478fSPekka Enberg /*
449444f478fSPekka Enberg  * Set up kernel memory allocators
450444f478fSPekka Enberg  */
451444f478fSPekka Enberg static void __init mm_init(void)
452444f478fSPekka Enberg {
453ca371c0dSKAMEZAWA Hiroyuki 	/*
4547fa87ce7SJim Cromie 	 * page_cgroup requires contiguous pages,
4557fa87ce7SJim Cromie 	 * bigger than MAX_ORDER unless SPARSEMEM.
456ca371c0dSKAMEZAWA Hiroyuki 	 */
457ca371c0dSKAMEZAWA Hiroyuki 	page_cgroup_init_flatmem();
458444f478fSPekka Enberg 	mem_init();
459444f478fSPekka Enberg 	kmem_cache_init();
460099a19d9STejun Heo 	percpu_init_late();
461c868d550SBenjamin Herrenschmidt 	pgtable_cache_init();
462444f478fSPekka Enberg 	vmalloc_init();
463444f478fSPekka Enberg }
464444f478fSPekka Enberg 
4651da177e4SLinus Torvalds asmlinkage void __init start_kernel(void)
4661da177e4SLinus Torvalds {
4671da177e4SLinus Torvalds 	char * command_line;
468914dcaa8SRusty Russell 	extern const struct kernel_param __start___param[], __stop___param[];
469033ab7f8SAndrew Morton 
4701da177e4SLinus Torvalds 	/*
471fbb9ce95SIngo Molnar 	 * Need to run as early as possible, to initialize the
472fbb9ce95SIngo Molnar 	 * lockdep hash:
473fbb9ce95SIngo Molnar 	 */
474fbb9ce95SIngo Molnar 	lockdep_init();
47573839c5bSMing Lei 	smp_setup_processor_id();
4763ac7fe5aSThomas Gleixner 	debug_objects_early_init();
47742059429SIngo Molnar 
47842059429SIngo Molnar 	/*
47942059429SIngo Molnar 	 * Set up the the initial canary ASAP:
48042059429SIngo Molnar 	 */
48142059429SIngo Molnar 	boot_init_stack_canary();
48242059429SIngo Molnar 
483ddbcc7e8SPaul Menage 	cgroup_init_early();
484fbb9ce95SIngo Molnar 
485fbb9ce95SIngo Molnar 	local_irq_disable();
4862ce802f6STejun Heo 	early_boot_irqs_disabled = true;
487fbb9ce95SIngo Molnar 
488fbb9ce95SIngo Molnar /*
4891da177e4SLinus Torvalds  * Interrupts are still disabled. Do necessary setups, then
4901da177e4SLinus Torvalds  * enable them
4911da177e4SLinus Torvalds  */
492906568c9SThomas Gleixner 	tick_init();
49344fd2299SStas Sergeev 	boot_cpu_init();
4941da177e4SLinus Torvalds 	page_address_init();
495657cafa6SAlex Riesen 	printk(KERN_NOTICE "%s", linux_banner);
4961da177e4SLinus Torvalds 	setup_arch(&command_line);
497cf475ad2SBalbir Singh 	mm_init_owner(&init_mm, &init_task);
4986345d24dSLinus Torvalds 	mm_init_cpumask(&init_mm);
49930d7e0d4SAlon Bar-Lev 	setup_command_line(command_line);
500e0982e90SMike Travis 	setup_nr_cpu_ids();
501d6647bdfSTejun Heo 	setup_per_cpu_areas();
50244fd2299SStas Sergeev 	smp_prepare_boot_cpu();	/* arch-specific boot-cpu hooks */
5031da177e4SLinus Torvalds 
5041f522509SHaicheng Li 	build_all_zonelists(NULL);
50583b519e8SPekka Enberg 	page_alloc_init();
50683b519e8SPekka Enberg 
50783b519e8SPekka Enberg 	printk(KERN_NOTICE "Kernel command line: %s\n", boot_command_line);
50883b519e8SPekka Enberg 	parse_early_param();
50983b519e8SPekka Enberg 	parse_args("Booting kernel", static_command_line, __start___param,
51083b519e8SPekka Enberg 		   __stop___param - __start___param,
511026cee00SPawel Moll 		   0, 0, &unknown_bootoption);
51297ce2c88SJeremy Fitzhardinge 
51397ce2c88SJeremy Fitzhardinge 	jump_label_init();
51497ce2c88SJeremy Fitzhardinge 
51583b519e8SPekka Enberg 	/*
51683b519e8SPekka Enberg 	 * These use large bootmem allocations and must precede
51783b519e8SPekka Enberg 	 * kmem_cache_init()
51883b519e8SPekka Enberg 	 */
519162a7e75SMike Travis 	setup_log_buf(0);
52083b519e8SPekka Enberg 	pidhash_init();
52183b519e8SPekka Enberg 	vfs_caches_init_early();
52283b519e8SPekka Enberg 	sort_main_extable();
52383b519e8SPekka Enberg 	trap_init();
524444f478fSPekka Enberg 	mm_init();
525de03c72cSKOSAKI Motohiro 
5261da177e4SLinus Torvalds 	/*
5271da177e4SLinus Torvalds 	 * Set up the scheduler prior starting any interrupts (such as the
5281da177e4SLinus Torvalds 	 * timer interrupt). Full topology setup happens at smp_init()
5291da177e4SLinus Torvalds 	 * time - but meanwhile we still have a functioning scheduler.
5301da177e4SLinus Torvalds 	 */
5311da177e4SLinus Torvalds 	sched_init();
5321da177e4SLinus Torvalds 	/*
5331da177e4SLinus Torvalds 	 * Disable preemption - early bootup scheduling is extremely
5341da177e4SLinus Torvalds 	 * fragile until we cpu_idle() for the first time.
5351da177e4SLinus Torvalds 	 */
5361da177e4SLinus Torvalds 	preempt_disable();
537c4a68306SArd van Breemen 	if (!irqs_disabled()) {
538c4a68306SArd van Breemen 		printk(KERN_WARNING "start_kernel(): bug: interrupts were "
539c4a68306SArd van Breemen 				"enabled *very* early, fixing it\n");
540c4a68306SArd van Breemen 		local_irq_disable();
541c4a68306SArd van Breemen 	}
5429f58a205SPeter Zijlstra 	idr_init_cache();
54324a24bb6SPeter Zijlstra 	perf_event_init();
5441da177e4SLinus Torvalds 	rcu_init();
545773e3eb7SYinghai Lu 	radix_tree_init();
5460b8f1efaSYinghai Lu 	/* init some links before init_ISA_irqs() */
5470b8f1efaSYinghai Lu 	early_irq_init();
5481da177e4SLinus Torvalds 	init_IRQ();
5493c7b4e6bSCatalin Marinas 	prio_tree_init();
5501da177e4SLinus Torvalds 	init_timers();
551c0a31329SThomas Gleixner 	hrtimers_init();
5521da177e4SLinus Torvalds 	softirq_init();
553ad596171Sjohn stultz 	timekeeping_init();
55488fecaa2Sjohn stultz 	time_init();
55593e02814SHeiko Carstens 	profile_init();
556d8ad7d11STakao Indoh 	call_function_init();
55793e02814SHeiko Carstens 	if (!irqs_disabled())
55824d431d0SRon Lee 		printk(KERN_CRIT "start_kernel(): bug: interrupts were "
55924d431d0SRon Lee 				 "enabled early\n");
5602ce802f6STejun Heo 	early_boot_irqs_disabled = false;
56193e02814SHeiko Carstens 	local_irq_enable();
562dcce284aSBenjamin Herrenschmidt 
5637e85ee0cSPekka Enberg 	kmem_cache_init_late();
5641da177e4SLinus Torvalds 
5651da177e4SLinus Torvalds 	/*
5661da177e4SLinus Torvalds 	 * HACK ALERT! This is early. We're enabling the console before
5671da177e4SLinus Torvalds 	 * we've done PCI setups etc, and console_init() must be aware of
5681da177e4SLinus Torvalds 	 * this. But we do want output early, in case something goes wrong.
5691da177e4SLinus Torvalds 	 */
5701da177e4SLinus Torvalds 	console_init();
5711da177e4SLinus Torvalds 	if (panic_later)
5721da177e4SLinus Torvalds 		panic(panic_later, panic_param);
573fbb9ce95SIngo Molnar 
574fbb9ce95SIngo Molnar 	lockdep_info();
575fbb9ce95SIngo Molnar 
5769a11b49aSIngo Molnar 	/*
5779a11b49aSIngo Molnar 	 * Need to run this when irqs are enabled, because it wants
5789a11b49aSIngo Molnar 	 * to self-test [hard/soft]-irqs on/off lock inversion bugs
5799a11b49aSIngo Molnar 	 * too:
5809a11b49aSIngo Molnar 	 */
5819a11b49aSIngo Molnar 	locking_selftest();
5829a11b49aSIngo Molnar 
5831da177e4SLinus Torvalds #ifdef CONFIG_BLK_DEV_INITRD
5841da177e4SLinus Torvalds 	if (initrd_start && !initrd_below_start_ok &&
585bd673c7cSGeert Uytterhoeven 	    page_to_pfn(virt_to_page((void *)initrd_start)) < min_low_pfn) {
5861da177e4SLinus Torvalds 		printk(KERN_CRIT "initrd overwritten (0x%08lx < 0x%08lx) - "
587fb6624ebSGeert Uytterhoeven 		    "disabling it.\n",
588bd673c7cSGeert Uytterhoeven 		    page_to_pfn(virt_to_page((void *)initrd_start)),
589bd673c7cSGeert Uytterhoeven 		    min_low_pfn);
5901da177e4SLinus Torvalds 		initrd_start = 0;
5911da177e4SLinus Torvalds 	}
5921da177e4SLinus Torvalds #endif
59394b6da5aSKAMEZAWA Hiroyuki 	page_cgroup_init();
5943ac7fe5aSThomas Gleixner 	debug_objects_mem_init();
5959b090f2dSCatalin Marinas 	kmemleak_init();
596e7c8d5c9SChristoph Lameter 	setup_per_cpu_pageset();
5971da177e4SLinus Torvalds 	numa_policy_init();
5981da177e4SLinus Torvalds 	if (late_time_init)
5991da177e4SLinus Torvalds 		late_time_init();
600fa84e9eeSThomas Gleixner 	sched_clock_init();
6011da177e4SLinus Torvalds 	calibrate_delay();
6021da177e4SLinus Torvalds 	pidmap_init();
6031da177e4SLinus Torvalds 	anon_vma_init();
6041da177e4SLinus Torvalds #ifdef CONFIG_X86
6051da177e4SLinus Torvalds 	if (efi_enabled)
6061da177e4SLinus Torvalds 		efi_enter_virtual_mode();
6071da177e4SLinus Torvalds #endif
6088c9843e5SBenjamin Herrenschmidt 	thread_info_cache_init();
609d84f4f99SDavid Howells 	cred_init();
6104481374cSJan Beulich 	fork_init(totalram_pages);
6111da177e4SLinus Torvalds 	proc_caches_init();
6121da177e4SLinus Torvalds 	buffer_init();
6131da177e4SLinus Torvalds 	key_init();
6141da177e4SLinus Torvalds 	security_init();
6150b4b3827SJason Wessel 	dbg_late_init();
6164481374cSJan Beulich 	vfs_caches_init(totalram_pages);
6171da177e4SLinus Torvalds 	signals_init();
6181da177e4SLinus Torvalds 	/* rootfs populating might need page-writeback */
6191da177e4SLinus Torvalds 	page_writeback_init();
6201da177e4SLinus Torvalds #ifdef CONFIG_PROC_FS
6211da177e4SLinus Torvalds 	proc_root_init();
6221da177e4SLinus Torvalds #endif
623ddbcc7e8SPaul Menage 	cgroup_init();
6241da177e4SLinus Torvalds 	cpuset_init();
625c757249aSShailabh Nagar 	taskstats_init_early();
626ca74e92bSShailabh Nagar 	delayacct_init();
6271da177e4SLinus Torvalds 
6281da177e4SLinus Torvalds 	check_bugs();
6291da177e4SLinus Torvalds 
6301da177e4SLinus Torvalds 	acpi_early_init(); /* before LAPIC and SMP init */
6316ae6996aSFeng Tang 	sfi_init_late();
6321da177e4SLinus Torvalds 
63368bf21aaSSteven Rostedt 	ftrace_init();
63468bf21aaSSteven Rostedt 
6351da177e4SLinus Torvalds 	/* Do the rest non-__init'ed, we're now alive */
6361da177e4SLinus Torvalds 	rest_init();
6371da177e4SLinus Torvalds }
6381da177e4SLinus Torvalds 
639b99b87f7SPeter Oberparleiter /* Call all constructor functions linked into the kernel. */
640b99b87f7SPeter Oberparleiter static void __init do_ctors(void)
641b99b87f7SPeter Oberparleiter {
642b99b87f7SPeter Oberparleiter #ifdef CONFIG_CONSTRUCTORS
643196a15b4SH Hartley Sweeten 	ctor_fn_t *fn = (ctor_fn_t *) __ctors_start;
644b99b87f7SPeter Oberparleiter 
645196a15b4SH Hartley Sweeten 	for (; fn < (ctor_fn_t *) __ctors_end; fn++)
646196a15b4SH Hartley Sweeten 		(*fn)();
647b99b87f7SPeter Oberparleiter #endif
648b99b87f7SPeter Oberparleiter }
649b99b87f7SPeter Oberparleiter 
6502329abfaSRusty Russell bool initcall_debug;
651d0ea3d7dSRusty Russell core_param(initcall_debug, initcall_debug, bool, 0644);
6521da177e4SLinus Torvalds 
6534a683bf9SIngo Molnar static char msgbuf[64];
6544a683bf9SIngo Molnar 
655e4461271SKevin Winchester static int __init_or_module do_one_initcall_debug(initcall_t fn)
6561da177e4SLinus Torvalds {
65774239072SFrederic Weisbecker 	ktime_t calltime, delta, rettime;
65830dbb20eSAmérico Wang 	unsigned long long duration;
65930dbb20eSAmérico Wang 	int ret;
6601da177e4SLinus Torvalds 
66122c5c03bSKevin Winchester 	printk(KERN_DEBUG "calling  %pF @ %i\n", fn, task_pid_nr(current));
66274239072SFrederic Weisbecker 	calltime = ktime_get();
66330dbb20eSAmérico Wang 	ret = fn();
66474239072SFrederic Weisbecker 	rettime = ktime_get();
66574239072SFrederic Weisbecker 	delta = ktime_sub(rettime, calltime);
66630dbb20eSAmérico Wang 	duration = (unsigned long long) ktime_to_ns(delta) >> 10;
66722c5c03bSKevin Winchester 	printk(KERN_DEBUG "initcall %pF returned %d after %lld usecs\n", fn,
66830dbb20eSAmérico Wang 		ret, duration);
66922c5c03bSKevin Winchester 
67022c5c03bSKevin Winchester 	return ret;
6718f0c45cdSIngo Molnar }
6728f0c45cdSIngo Molnar 
673e4461271SKevin Winchester int __init_or_module do_one_initcall(initcall_t fn)
67422c5c03bSKevin Winchester {
67522c5c03bSKevin Winchester 	int count = preempt_count();
67622c5c03bSKevin Winchester 	int ret;
67722c5c03bSKevin Winchester 
67822c5c03bSKevin Winchester 	if (initcall_debug)
67922c5c03bSKevin Winchester 		ret = do_one_initcall_debug(fn);
68022c5c03bSKevin Winchester 	else
68122c5c03bSKevin Winchester 		ret = fn();
68222c5c03bSKevin Winchester 
683e662e1cfSCyrill Gorcunov 	msgbuf[0] = 0;
684e662e1cfSCyrill Gorcunov 
68530dbb20eSAmérico Wang 	if (ret && ret != -ENODEV && initcall_debug)
68630dbb20eSAmérico Wang 		sprintf(msgbuf, "error code %d ", ret);
687e662e1cfSCyrill Gorcunov 
6881da177e4SLinus Torvalds 	if (preempt_count() != count) {
689a76bfd0dSCyrill Gorcunov 		strlcat(msgbuf, "preemption imbalance ", sizeof(msgbuf));
6901da177e4SLinus Torvalds 		preempt_count() = count;
6911da177e4SLinus Torvalds 	}
6921da177e4SLinus Torvalds 	if (irqs_disabled()) {
693a76bfd0dSCyrill Gorcunov 		strlcat(msgbuf, "disabled interrupts ", sizeof(msgbuf));
6941da177e4SLinus Torvalds 		local_irq_enable();
6951da177e4SLinus Torvalds 	}
696e662e1cfSCyrill Gorcunov 	if (msgbuf[0]) {
69796d746c6SLinus Torvalds 		printk("initcall %pF returned with %s\n", fn, msgbuf);
6981da177e4SLinus Torvalds 	}
69959f9415fSArjan van de Ven 
70030dbb20eSAmérico Wang 	return ret;
7011da177e4SLinus Torvalds }
7021da177e4SLinus Torvalds 
703e0df154fSLinus Torvalds 
704026cee00SPawel Moll extern initcall_t __initcall_start[];
705026cee00SPawel Moll extern initcall_t __initcall0_start[];
706026cee00SPawel Moll extern initcall_t __initcall1_start[];
707026cee00SPawel Moll extern initcall_t __initcall2_start[];
708026cee00SPawel Moll extern initcall_t __initcall3_start[];
709026cee00SPawel Moll extern initcall_t __initcall4_start[];
710026cee00SPawel Moll extern initcall_t __initcall5_start[];
711026cee00SPawel Moll extern initcall_t __initcall6_start[];
712026cee00SPawel Moll extern initcall_t __initcall7_start[];
713026cee00SPawel Moll extern initcall_t __initcall_end[];
714026cee00SPawel Moll 
715026cee00SPawel Moll static initcall_t *initcall_levels[] __initdata = {
716026cee00SPawel Moll 	__initcall0_start,
717026cee00SPawel Moll 	__initcall1_start,
718026cee00SPawel Moll 	__initcall2_start,
719026cee00SPawel Moll 	__initcall3_start,
720026cee00SPawel Moll 	__initcall4_start,
721026cee00SPawel Moll 	__initcall5_start,
722026cee00SPawel Moll 	__initcall6_start,
723026cee00SPawel Moll 	__initcall7_start,
724026cee00SPawel Moll 	__initcall_end,
725026cee00SPawel Moll };
726026cee00SPawel Moll 
727026cee00SPawel Moll static char *initcall_level_names[] __initdata = {
728026cee00SPawel Moll 	"early parameters",
729026cee00SPawel Moll 	"core parameters",
730026cee00SPawel Moll 	"postcore parameters",
731026cee00SPawel Moll 	"arch parameters",
732026cee00SPawel Moll 	"subsys parameters",
733026cee00SPawel Moll 	"fs parameters",
734026cee00SPawel Moll 	"device parameters",
735026cee00SPawel Moll 	"late parameters",
736026cee00SPawel Moll };
737026cee00SPawel Moll 
738026cee00SPawel Moll static void __init do_initcall_level(int level)
739026cee00SPawel Moll {
740026cee00SPawel Moll 	extern const struct kernel_param __start___param[], __stop___param[];
741026cee00SPawel Moll 	initcall_t *fn;
742026cee00SPawel Moll 
743026cee00SPawel Moll 	strcpy(static_command_line, saved_command_line);
744026cee00SPawel Moll 	parse_args(initcall_level_names[level],
745026cee00SPawel Moll 		   static_command_line, __start___param,
746026cee00SPawel Moll 		   __stop___param - __start___param,
747026cee00SPawel Moll 		   level, level,
748a99cd112SChris Metcalf 		   repair_env_string);
749026cee00SPawel Moll 
750026cee00SPawel Moll 	for (fn = initcall_levels[level]; fn < initcall_levels[level+1]; fn++)
751026cee00SPawel Moll 		do_one_initcall(*fn);
752026cee00SPawel Moll }
753e0df154fSLinus Torvalds 
754e0df154fSLinus Torvalds static void __init do_initcalls(void)
755e0df154fSLinus Torvalds {
756026cee00SPawel Moll 	int level;
757e0df154fSLinus Torvalds 
758026cee00SPawel Moll 	for (level = 0; level < ARRAY_SIZE(initcall_levels) - 1; level++)
759026cee00SPawel Moll 		do_initcall_level(level);
7601da177e4SLinus Torvalds }
7611da177e4SLinus Torvalds 
7621da177e4SLinus Torvalds /*
7631da177e4SLinus Torvalds  * Ok, the machine is now initialized. None of the devices
7641da177e4SLinus Torvalds  * have been touched yet, but the CPU subsystem is up and
7651da177e4SLinus Torvalds  * running, and memory and process management works.
7661da177e4SLinus Torvalds  *
7671da177e4SLinus Torvalds  * Now we can finally start doing some real work..
7681da177e4SLinus Torvalds  */
7691da177e4SLinus Torvalds static void __init do_basic_setup(void)
7701da177e4SLinus Torvalds {
771759ee091SLai Jiangshan 	cpuset_init_smp();
7721da177e4SLinus Torvalds 	usermodehelper_init();
77341ffe5d5SHugh Dickins 	shmem_init();
7741da177e4SLinus Torvalds 	driver_init();
775b04c3afbSEric W. Biederman 	init_irq_proc();
776b99b87f7SPeter Oberparleiter 	do_ctors();
777d5767c53SLinus Torvalds 	usermodehelper_enable();
778b0f84374Swangyanqing 	do_initcalls();
7791da177e4SLinus Torvalds }
7801da177e4SLinus Torvalds 
7817babe8dbSEduard - Gabriel Munteanu static void __init do_pre_smp_initcalls(void)
782c2147a50SEduard - Gabriel Munteanu {
783196a15b4SH Hartley Sweeten 	initcall_t *fn;
784c2147a50SEduard - Gabriel Munteanu 
785026cee00SPawel Moll 	for (fn = __initcall_start; fn < __initcall0_start; fn++)
786196a15b4SH Hartley Sweeten 		do_one_initcall(*fn);
787c2147a50SEduard - Gabriel Munteanu }
788c2147a50SEduard - Gabriel Munteanu 
789d7627467SDavid Howells static void run_init_process(const char *init_filename)
7901da177e4SLinus Torvalds {
7911da177e4SLinus Torvalds 	argv_init[0] = init_filename;
79267608567SArnd Bergmann 	kernel_execve(init_filename, argv_init, envp_init);
7931da177e4SLinus Torvalds }
7941da177e4SLinus Torvalds 
795ee5bfa64SVivek Goyal /* This is a non __init function. Force it to be noinline otherwise gcc
796ee5bfa64SVivek Goyal  * makes it inline to init() and it becomes part of init.text section
797ee5bfa64SVivek Goyal  */
798f99ebf0aSRakib Mullick static noinline int init_post(void)
799ee5bfa64SVivek Goyal {
80022a9d645SArjan van de Ven 	/* need to finish all async __init code before freeing the memory */
80122a9d645SArjan van de Ven 	async_synchronize_full();
802ee5bfa64SVivek Goyal 	free_initmem();
803ee5bfa64SVivek Goyal 	mark_rodata_ro();
804ee5bfa64SVivek Goyal 	system_state = SYSTEM_RUNNING;
805ee5bfa64SVivek Goyal 	numa_default_policy();
806ee5bfa64SVivek Goyal 
807ee5bfa64SVivek Goyal 
808fae5fa44SOleg Nesterov 	current->signal->flags |= SIGNAL_UNKILLABLE;
809fae5fa44SOleg Nesterov 
810ee5bfa64SVivek Goyal 	if (ramdisk_execute_command) {
811ee5bfa64SVivek Goyal 		run_init_process(ramdisk_execute_command);
812ee5bfa64SVivek Goyal 		printk(KERN_WARNING "Failed to execute %s\n",
813ee5bfa64SVivek Goyal 				ramdisk_execute_command);
814ee5bfa64SVivek Goyal 	}
815ee5bfa64SVivek Goyal 
816ee5bfa64SVivek Goyal 	/*
817ee5bfa64SVivek Goyal 	 * We try each of these until one succeeds.
818ee5bfa64SVivek Goyal 	 *
819ee5bfa64SVivek Goyal 	 * The Bourne shell can be used instead of init if we are
820ee5bfa64SVivek Goyal 	 * trying to recover a really broken machine.
821ee5bfa64SVivek Goyal 	 */
822ee5bfa64SVivek Goyal 	if (execute_command) {
823ee5bfa64SVivek Goyal 		run_init_process(execute_command);
824ee5bfa64SVivek Goyal 		printk(KERN_WARNING "Failed to execute %s.  Attempting "
825ee5bfa64SVivek Goyal 					"defaults...\n", execute_command);
826ee5bfa64SVivek Goyal 	}
827ee5bfa64SVivek Goyal 	run_init_process("/sbin/init");
828ee5bfa64SVivek Goyal 	run_init_process("/etc/init");
829ee5bfa64SVivek Goyal 	run_init_process("/bin/init");
830ee5bfa64SVivek Goyal 	run_init_process("/bin/sh");
831ee5bfa64SVivek Goyal 
8329a85b8d6SAndreas Mohr 	panic("No init found.  Try passing init= option to kernel. "
8339a85b8d6SAndreas Mohr 	      "See Linux Documentation/init.txt for guidance.");
834ee5bfa64SVivek Goyal }
835ee5bfa64SVivek Goyal 
836aae5f662SSam Ravnborg static int __init kernel_init(void * unused)
8371da177e4SLinus Torvalds {
838b433c3d4SPeter Zijlstra 	/*
839b433c3d4SPeter Zijlstra 	 * Wait until kthreadd is all set-up.
840b433c3d4SPeter Zijlstra 	 */
841b433c3d4SPeter Zijlstra 	wait_for_completion(&kthreadd_done);
842*31a67102SLinus Torvalds 
843*31a67102SLinus Torvalds 	/* Now the scheduler is fully set up and can do blocking allocations */
844*31a67102SLinus Torvalds 	gfp_allowed_mask = __GFP_BITS_MASK;
845*31a67102SLinus Torvalds 
84658568d2aSMiao Xie 	/*
84758568d2aSMiao Xie 	 * init can allocate pages on any node
84858568d2aSMiao Xie 	 */
8495ab116c9SMiao Xie 	set_mems_allowed(node_states[N_HIGH_MEMORY]);
8501da177e4SLinus Torvalds 	/*
8511da177e4SLinus Torvalds 	 * init can run on any cpu.
8521da177e4SLinus Torvalds 	 */
8531a2142afSRusty Russell 	set_cpus_allowed_ptr(current, cpu_all_mask);
8541da177e4SLinus Torvalds 
8559ec52099SCedric Le Goater 	cad_pid = task_pid(current);
8569ec52099SCedric Le Goater 
857ca74a6f8SAndi Kleen 	smp_prepare_cpus(setup_max_cpus);
8581da177e4SLinus Torvalds 
8591da177e4SLinus Torvalds 	do_pre_smp_initcalls();
860004417a6SPeter Zijlstra 	lockup_detector_init();
8611da177e4SLinus Torvalds 
8621da177e4SLinus Torvalds 	smp_init();
8631da177e4SLinus Torvalds 	sched_init_smp();
8641da177e4SLinus Torvalds 
8651da177e4SLinus Torvalds 	do_basic_setup();
8661da177e4SLinus Torvalds 
8672bd3a997SEric W. Biederman 	/* Open the /dev/console on the rootfs, this should never fail */
8682bd3a997SEric W. Biederman 	if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
8692bd3a997SEric W. Biederman 		printk(KERN_WARNING "Warning: unable to open an initial console.\n");
8702bd3a997SEric W. Biederman 
8712bd3a997SEric W. Biederman 	(void) sys_dup(0);
8722bd3a997SEric W. Biederman 	(void) sys_dup(0);
8731da177e4SLinus Torvalds 	/*
8741da177e4SLinus Torvalds 	 * check if there is an early userspace init.  If yes, let it do all
8751da177e4SLinus Torvalds 	 * the work
8761da177e4SLinus Torvalds 	 */
877ffdfc409SOlof Johansson 
878ffdfc409SOlof Johansson 	if (!ramdisk_execute_command)
879ffdfc409SOlof Johansson 		ramdisk_execute_command = "/init";
880ffdfc409SOlof Johansson 
881ffdfc409SOlof Johansson 	if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {
882ffdfc409SOlof Johansson 		ramdisk_execute_command = NULL;
8831da177e4SLinus Torvalds 		prepare_namespace();
884ffdfc409SOlof Johansson 	}
8851da177e4SLinus Torvalds 
8861da177e4SLinus Torvalds 	/*
8871da177e4SLinus Torvalds 	 * Ok, we have completed the initial bootup, and
8881da177e4SLinus Torvalds 	 * we're essentially up and running. Get rid of the
8891da177e4SLinus Torvalds 	 * initmem segments and start the user-mode stuff..
8901da177e4SLinus Torvalds 	 */
89171566a0dSFrederic Weisbecker 
892ee5bfa64SVivek Goyal 	init_post();
893ee5bfa64SVivek Goyal 	return 0;
8941da177e4SLinus Torvalds }
895