#include <linux/cpu.h>
#include <linux/cpuset.h>
#include <linux/efi.h>
+#include <linux/tick.h>
+#include <linux/interrupt.h>
#include <linux/taskstats_kern.h>
#include <linux/delayacct.h>
#include <linux/unistd.h>
#include <linux/lockdep.h>
#include <linux/pid_namespace.h>
#include <linux/device.h>
+#include <linux/kthread.h>
#include <asm/io.h>
#include <asm/bugs.h>
#warning gcc-4.1.0 is known to miscompile the kernel. A different compiler version is recommended.
#endif
-static int init(void *);
+static int kernel_init(void *);
extern void init_IRQ(void);
extern void fork_init(unsigned long);
extern void mca_init(void);
extern void sbus_init(void);
-extern void sysctl_init(void);
extern void signals_init(void);
extern void pidhash_init(void);
extern void pidmap_init(void);
extern void prio_tree_init(void);
extern void radix_tree_init(void);
extern void free_initmem(void);
-extern void prepare_namespace(void);
#ifdef CONFIG_ACPI
extern void acpi_early_init(void);
#else
unsigned long nr_possible_cpus = num_possible_cpus();
/* Copy section for each CPU (we discard the original) */
- size = ALIGN(__per_cpu_end - __per_cpu_start, SMP_CACHE_BYTES);
-#ifdef CONFIG_MODULES
- if (size < PERCPU_ENOUGH_ROOM)
- size = PERCPU_ENOUGH_ROOM;
-#endif
- ptr = alloc_bootmem(size * nr_possible_cpus);
+ size = ALIGN(PERCPU_ENOUGH_ROOM, PAGE_SIZE);
+ ptr = alloc_bootmem_pages(size * nr_possible_cpus);
for_each_possible_cpu(i) {
__per_cpu_offset[i] = ptr - __per_cpu_start;
/* Called by boot processor to activate the rest. */
static void __init smp_init(void)
{
- unsigned int i;
+ unsigned int cpu;
/* FIXME: This should be done in userspace --RR */
- for_each_present_cpu(i) {
+ for_each_present_cpu(cpu) {
if (num_online_cpus() >= max_cpus)
break;
- if (!cpu_online(i))
- cpu_up(i);
+ if (!cpu_online(cpu))
+ cpu_up(cpu);
}
/* Any cleanup work */
static void noinline rest_init(void)
__releases(kernel_lock)
{
- kernel_thread(init, NULL, CLONE_FS | CLONE_SIGHAND);
+ int pid;
+
+ kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
numa_default_policy();
+ pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
+ kthreadd_task = find_task_by_pid(pid);
unlock_kernel();
/*
* enable them
*/
lock_kernel();
+ tick_init();
boot_cpu_init();
page_address_init();
printk(KERN_NOTICE);
int count = preempt_count();
for (call = __initcall_start; call < __initcall_end; call++) {
+ ktime_t t0, t1, delta;
char *msg = NULL;
char msgbuf[40];
int result;
print_fn_descriptor_symbol(": %s()",
(unsigned long) *call);
printk("\n");
+ t0 = ktime_get();
}
result = (*call)();
+ if (initcall_debug) {
+ t1 = ktime_get();
+ delta = ktime_sub(t1, t0);
+
+ printk("initcall 0x%p", *call);
+ print_fn_descriptor_symbol(": %s()",
+ (unsigned long) *call);
+ printk(" returned %d.\n", result);
+
+ printk("initcall 0x%p ran for %Ld msecs: ",
+ *call, (unsigned long long)delta.tv64 >> 20);
+ print_fn_descriptor_symbol("%s()\n",
+ (unsigned long) *call);
+ }
+
if (result && result != -ENODEV && initcall_debug) {
sprintf(msgbuf, "error code %d", result);
msg = msgbuf;
init_workqueues();
usermodehelper_init();
driver_init();
-
-#ifdef CONFIG_SYSCTL
- sysctl_init();
-#endif
-
+ init_irq_proc();
do_initcalls();
}
kernel_execve(init_filename, argv_init, envp_init);
}
-static int init(void * unused)
+/* This is a non __init function. Force it to be noinline otherwise gcc
+ * makes it inline to init() and it becomes part of init.text section
+ */
+static int noinline init_post(void)
+{
+ free_initmem();
+ unlock_kernel();
+ mark_rodata_ro();
+ system_state = SYSTEM_RUNNING;
+ numa_default_policy();
+
+ if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
+ printk(KERN_WARNING "Warning: unable to open an initial console.\n");
+
+ (void) sys_dup(0);
+ (void) sys_dup(0);
+
+ if (ramdisk_execute_command) {
+ run_init_process(ramdisk_execute_command);
+ printk(KERN_WARNING "Failed to execute %s\n",
+ 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.");
+}
+
+static int __init kernel_init(void * unused)
{
lock_kernel();
/*
* we're essentially up and running. Get rid of the
* initmem segments and start the user-mode stuff..
*/
- free_initmem();
- unlock_kernel();
- mark_rodata_ro();
- system_state = SYSTEM_RUNNING;
- numa_default_policy();
-
- if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
- printk(KERN_WARNING "Warning: unable to open an initial console.\n");
-
- (void) sys_dup(0);
- (void) sys_dup(0);
-
- if (ramdisk_execute_command) {
- run_init_process(ramdisk_execute_command);
- printk(KERN_WARNING "Failed to execute %s\n",
- 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.");
+ init_post();
+ return 0;
}