summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--init/Kconfig108
-rw-r--r--init/Makefile1
-rw-r--r--init/do_mounts.c13
-rw-r--r--init/do_mounts.h16
-rw-r--r--init/do_mounts_devfs.c137
-rw-r--r--init/do_mounts_initrd.c6
-rw-r--r--init/do_mounts_md.c7
-rw-r--r--init/do_mounts_rd.c4
-rw-r--r--init/initramfs.c36
-rw-r--r--init/main.c79
-rw-r--r--init/version.c1
11 files changed, 190 insertions, 218 deletions
diff --git a/init/Kconfig b/init/Kconfig
index df864a358221..4381006dd666 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1,3 +1,11 @@
+config DEFCONFIG_LIST
+ string
+ option defconfig_list
+ default "/lib/modules/$UNAME_RELEASE/.config"
+ default "/etc/kernel-config"
+ default "/boot/config-$UNAME_RELEASE"
+ default "arch/$ARCH/defconfig"
+
menu "Code maturity level options"
config EXPERIMENTAL
@@ -46,8 +54,8 @@ config LOCK_KERNEL
config INIT_ENV_ARG_LIMIT
int
- default 32 if !USERMODE
- default 128 if USERMODE
+ default 32 if !UML
+ default 128 if UML
help
Maximum of each of the number of arguments and environment
variables passed to init from the kernel command line.
@@ -150,21 +158,29 @@ config BSD_PROCESS_ACCT_V3
for processing it. A preliminary version of these tools is available
at <http://www.physik3.uni-rostock.de/tim/kernel/utils/acct/>.
-config SYSCTL
- bool "Sysctl support"
- ---help---
- The sysctl interface provides a means of dynamically changing
- certain kernel parameters and variables on the fly without requiring
- a recompile of the kernel or reboot of the system. The primary
- interface consists of a system call, but if you say Y to "/proc
- file system support", a tree of modifiable sysctl entries will be
- generated beneath the /proc/sys directory. They are explained in the
- files in <file:Documentation/sysctl/>. Note that enabling this
- option will enlarge the kernel by at least 8 KB.
-
- As it is generally a good thing, you should say Y here unless
- building a kernel for install/rescue disks or your system is very
- limited in memory.
+config TASKSTATS
+ bool "Export task/process statistics through netlink (EXPERIMENTAL)"
+ depends on NET
+ default n
+ help
+ Export selected statistics for tasks/processes through the
+ generic netlink interface. Unlike BSD process accounting, the
+ statistics are available during the lifetime of tasks/processes as
+ responses to commands. Like BSD accounting, they are sent to user
+ space on task exit.
+
+ Say N if unsure.
+
+config TASK_DELAY_ACCT
+ bool "Enable per-task delay accounting (EXPERIMENTAL)"
+ depends on TASKSTATS
+ help
+ Collect information on time spent by a task waiting for system
+ resources like cpu, synchronous block I/O completion and swapping
+ in pages. Such statistics can help in setting a task's priorities
+ relative to other tasks for cpu, io, rss limits etc.
+
+ Say N if unsure.
config AUDIT
bool "Auditing support"
@@ -228,23 +244,6 @@ config RELAY
source "usr/Kconfig"
-config UID16
- bool "Enable 16-bit UID system calls" if EMBEDDED
- depends on ARM || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION)
- default y
- help
- This enables the legacy 16-bit UID syscall wrappers.
-
-config VM86
- depends X86
- default y
- bool "Enable VM86 support" if EMBEDDED
- help
- This option is required by programs like DOSEMU to run 16-bit legacy
- code on X86 processors. It also may be needed by software like
- XFree86 to initialize some video cards via BIOS. Disabling this
- option saves about 6k.
-
config CC_OPTIMIZE_FOR_SIZE
bool "Optimize for size (Look out for broken compilers!)"
default y
@@ -266,6 +265,33 @@ menuconfig EMBEDDED
environments which can tolerate a "non-standard" kernel.
Only use this if you really know what you are doing.
+config UID16
+ bool "Enable 16-bit UID system calls" if EMBEDDED
+ depends on ARM || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && SPARC32_COMPAT) || UML || (X86_64 && IA32_EMULATION)
+ default y
+ help
+ This enables the legacy 16-bit UID syscall wrappers.
+
+config SYSCTL
+ bool
+
+config SYSCTL_SYSCALL
+ bool "Sysctl syscall support"
+ default n
+ select SYSCTL
+ ---help---
+ Enable the deprecated sysctl system call. sys_sysctl uses
+ binary paths that have been found to be a major pain to maintain
+ and use. The interface in /proc/sys is now the primary and what
+ everyone uses.
+
+ Nothing has been using the binary sysctl interface for some time
+ time now so nothing should break if you disable sysctl syscall
+ support, and you kernel will get marginally smaller.
+
+ Unless you have an application that uses the sys_syscall interface
+ you should probably say N here.
+
config KALLSYMS
bool "Load all symbols for debugging/kksymoops" if EMBEDDED
default y
@@ -343,6 +369,7 @@ config BASE_FULL
config FUTEX
bool "Enable futex support" if EMBEDDED
default y
+ select RT_MUTEXES
help
Disabling this option will cause the kernel to be built without
support for "fast userspace mutexes". The resulting kernel may not
@@ -375,8 +402,21 @@ config SLAB
SLOB is more space efficient but does not scale well and is
more susceptible to fragmentation.
+config VM_EVENT_COUNTERS
+ default y
+ bool "Enable VM event counters for /proc/vmstat" if EMBEDDED
+ help
+ VM event counters are only needed to for event counts to be
+ shown. They have no function for the kernel itself. This
+ option allows the disabling of the VM event counters.
+ /proc/vmstat will only show page counts.
+
endmenu # General setup
+config RT_MUTEXES
+ boolean
+ select PLIST
+
config TINY_SHMEM
default !SHMEM
bool
diff --git a/init/Makefile b/init/Makefile
index a2300078f2b7..633a268d270d 100644
--- a/init/Makefile
+++ b/init/Makefile
@@ -6,7 +6,6 @@ obj-y := main.o version.o mounts.o initramfs.o
obj-$(CONFIG_GENERIC_CALIBRATE_DELAY) += calibrate.o
mounts-y := do_mounts.o
-mounts-$(CONFIG_DEVFS_FS) += do_mounts_devfs.o
mounts-$(CONFIG_BLK_DEV_RAM) += do_mounts_rd.o
mounts-$(CONFIG_BLK_DEV_INITRD) += do_mounts_initrd.o
mounts-$(CONFIG_BLK_DEV_MD) += do_mounts_md.o
diff --git a/init/do_mounts.c b/init/do_mounts.c
index 21b3b8f33a72..b290aadb1d3f 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -8,6 +8,7 @@
#include <linux/security.h>
#include <linux/delay.h>
#include <linux/mount.h>
+#include <linux/device.h>
#include <linux/nfs_fs.h>
#include <linux/nfs_fs_sb.h>
@@ -325,7 +326,7 @@ static int __init mount_nfs_root(void)
{
void *data = nfs_root_data();
- create_dev("/dev/root", ROOT_DEV, NULL);
+ create_dev("/dev/root", ROOT_DEV);
if (data &&
do_mount_root("/dev/root", "nfs", root_mountflags, data) == 0)
return 1;
@@ -386,7 +387,7 @@ void __init mount_root(void)
change_floppy("root floppy");
}
#endif
- create_dev("/dev/root", ROOT_DEV, root_device_name);
+ create_dev("/dev/root", ROOT_DEV);
mount_block_root("/dev/root", root_mountflags);
}
@@ -397,14 +398,16 @@ void __init prepare_namespace(void)
{
int is_floppy;
- mount_devfs();
-
if (root_delay) {
printk(KERN_INFO "Waiting %dsec before mounting root device...\n",
root_delay);
ssleep(root_delay);
}
+ /* wait for the known devices to complete their probing */
+ while (driver_probe_done() != 0)
+ msleep(100);
+
md_run_setup();
if (saved_root_name[0]) {
@@ -428,10 +431,8 @@ void __init prepare_namespace(void)
mount_root();
out:
- umount_devfs("/dev");
sys_mount(".", "/", NULL, MS_MOVE, NULL);
sys_chroot(".");
security_sb_post_mountroot();
- mount_devfs_fs ();
}
diff --git a/init/do_mounts.h b/init/do_mounts.h
index e0a7ac9649e1..e7f2e7fa066e 100644
--- a/init/do_mounts.h
+++ b/init/do_mounts.h
@@ -1,6 +1,5 @@
#include <linux/config.h>
#include <linux/kernel.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/init.h>
#include <linux/syscalls.h>
#include <linux/unistd.h>
@@ -15,25 +14,12 @@ void mount_root(void);
extern int root_mountflags;
extern char *root_device_name;
-#ifdef CONFIG_DEVFS_FS
-
-void mount_devfs(void);
-void umount_devfs(char *path);
-int create_dev(char *name, dev_t dev, char *devfs_name);
-
-#else
-
-static inline void mount_devfs(void) {}
-static inline void umount_devfs(const char *path) {}
-
-static inline int create_dev(char *name, dev_t dev, char *devfs_name)
+static inline int create_dev(char *name, dev_t dev)
{
sys_unlink(name);
return sys_mknod(name, S_IFBLK|0600, new_encode_dev(dev));
}
-#endif
-
#if BITS_PER_LONG == 32
static inline u32 bstat(char *name)
{
diff --git a/init/do_mounts_devfs.c b/init/do_mounts_devfs.c
deleted file mode 100644
index cc526474690a..000000000000
--- a/init/do_mounts_devfs.c
+++ /dev/null
@@ -1,137 +0,0 @@
-
-#include <linux/kernel.h>
-#include <linux/dirent.h>
-#include <linux/string.h>
-
-#include "do_mounts.h"
-
-void __init mount_devfs(void)
-{
- sys_mount("devfs", "/dev", "devfs", 0, NULL);
-}
-
-void __init umount_devfs(char *path)
-{
- sys_umount(path, 0);
-}
-
-/*
- * If the dir will fit in *buf, return its length. If it won't fit, return
- * zero. Return -ve on error.
- */
-static int __init do_read_dir(int fd, void *buf, int len)
-{
- long bytes, n;
- char *p = buf;
- sys_lseek(fd, 0, 0);
-
- for (bytes = 0; bytes < len; bytes += n) {
- n = sys_getdents64(fd, (struct linux_dirent64 *)(p + bytes),
- len - bytes);
- if (n < 0)
- return n;
- if (n == 0)
- return bytes;
- }
- return 0;
-}
-
-/*
- * Try to read all of a directory. Returns the contents at *p, which
- * is kmalloced memory. Returns the number of bytes read at *len. Returns
- * NULL on error.
- */
-static void * __init read_dir(char *path, int *len)
-{
- int size;
- int fd = sys_open(path, 0, 0);
-
- *len = 0;
- if (fd < 0)
- return NULL;
-
- for (size = 1 << 9; size <= (PAGE_SIZE << MAX_ORDER); size <<= 1) {
- void *p = kmalloc(size, GFP_KERNEL);
- int n;
- if (!p)
- break;
- n = do_read_dir(fd, p, size);
- if (n > 0) {
- sys_close(fd);
- *len = n;
- return p;
- }
- kfree(p);
- if (n == -EINVAL)
- continue; /* Try a larger buffer */
- if (n < 0)
- break;
- }
- sys_close(fd);
- return NULL;
-}
-
-/*
- * recursively scan <path>, looking for a device node of type <dev>
- */
-static int __init find_in_devfs(char *path, unsigned dev)
-{
- char *end = path + strlen(path);
- int rest = path + 64 - end;
- int size;
- char *p = read_dir(path, &size);
- char *s;
-
- if (!p)
- return -1;
- for (s = p; s < p + size; s += ((struct linux_dirent64 *)s)->d_reclen) {
- struct linux_dirent64 *d = (struct linux_dirent64 *)s;
- if (strlen(d->d_name) + 2 > rest)
- continue;
- switch (d->d_type) {
- case DT_BLK:
- sprintf(end, "/%s", d->d_name);
- if (bstat(path) != dev)
- break;
- kfree(p);
- return 0;
- case DT_DIR:
- if (strcmp(d->d_name, ".") == 0)
- break;
- if (strcmp(d->d_name, "..") == 0)
- break;
- sprintf(end, "/%s", d->d_name);
- if (find_in_devfs(path, dev) < 0)
- break;
- kfree(p);
- return 0;
- }
- }
- kfree(p);
- return -1;
-}
-
-/*
- * create a device node called <name> which points to
- * <devfs_name> if possible, otherwise find a device node
- * which matches <dev> and make <name> a symlink pointing to it.
- */
-int __init create_dev(char *name, dev_t dev, char *devfs_name)
-{
- char path[64];
-
- sys_unlink(name);
- if (devfs_name && devfs_name[0]) {
- if (strncmp(devfs_name, "/dev/", 5) == 0)
- devfs_name += 5;
- sprintf(path, "/dev/%s", devfs_name);
- if (sys_access(path, 0) == 0)
- return sys_symlink(devfs_name, name);
- }
- if (!dev)
- return -1;
- strcpy(path, "/dev");
- if (find_in_devfs(path, new_encode_dev(dev)) < 0)
- return -1;
- return sys_symlink(path + 5, name);
-}
diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c
index 405f9031af87..a06f037fa000 100644
--- a/init/do_mounts_initrd.c
+++ b/init/do_mounts_initrd.c
@@ -44,7 +44,7 @@ static void __init handle_initrd(void)
int pid;
real_root_dev = new_encode_dev(ROOT_DEV);
- create_dev("/dev/root.old", Root_RAM0, NULL);
+ create_dev("/dev/root.old", Root_RAM0);
/* mount initrd on rootfs' /root */
mount_block_root("/dev/root.old", root_mountflags & ~MS_RDONLY);
sys_mkdir("/old", 0700);
@@ -54,7 +54,6 @@ static void __init handle_initrd(void)
sys_chdir("/root");
sys_mount(".", "/", NULL, MS_MOVE, NULL);
sys_chroot(".");
- mount_devfs_fs ();
current->flags |= PF_NOFREEZE;
pid = kernel_thread(do_linuxrc, "/linuxrc", SIGCHLD);
@@ -71,7 +70,6 @@ static void __init handle_initrd(void)
sys_chroot(".");
sys_close(old_fd);
sys_close(root_fd);
- umount_devfs("/old/dev");
if (new_decode_dev(real_root_dev) == Root_RAM0) {
sys_chdir("/old");
@@ -107,7 +105,7 @@ static void __init handle_initrd(void)
int __init initrd_load(void)
{
if (mount_initrd) {
- create_dev("/dev/ram", Root_RAM0, NULL);
+ create_dev("/dev/ram", Root_RAM0);
/*
* Load the initrd data into /dev/ram0. Execute it as initrd
* unless /dev/ram0 is supposed to be our actual root device,
diff --git a/init/do_mounts_md.c b/init/do_mounts_md.c
index f6f36806f84a..2429e1bf8c60 100644
--- a/init/do_mounts_md.c
+++ b/init/do_mounts_md.c
@@ -125,19 +125,18 @@ static void __init md_setup_drive(void)
int err = 0;
char *devname;
mdu_disk_info_t dinfo;
- char name[16], devfs_name[16];
+ char name[16];
minor = md_setup_args[ent].minor;
partitioned = md_setup_args[ent].partitioned;
devname = md_setup_args[ent].device_names;
sprintf(name, "/dev/md%s%d", partitioned?"_d":"", minor);
- sprintf(devfs_name, "/dev/md/%s%d", partitioned?"d":"", minor);
if (partitioned)
dev = MKDEV(mdp_major, minor << MdpMinorShift);
else
dev = MKDEV(MD_MAJOR, minor);
- create_dev(name, dev, devfs_name);
+ create_dev(name, dev);
for (i = 0; i < MD_SB_DISKS && devname != 0; i++) {
char *p;
char comp_name[64];
@@ -272,7 +271,7 @@ __setup("md=", md_setup);
void __init md_run_setup(void)
{
- create_dev("/dev/md0", MKDEV(MD_MAJOR, 0), "md/0");
+ create_dev("/dev/md0", MKDEV(MD_MAJOR, 0));
if (raid_noautodetect)
printk(KERN_INFO "md: Skipping autodetection of RAID arrays. (raid=noautodetect)\n");
else {
diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c
index c2683fcd792d..ed652f40f075 100644
--- a/init/do_mounts_rd.c
+++ b/init/do_mounts_rd.c
@@ -262,8 +262,8 @@ int __init rd_load_disk(int n)
{
if (rd_prompt)
change_floppy("root floppy disk to be loaded into RAM disk");
- create_dev("/dev/root", ROOT_DEV, root_device_name);
- create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n), NULL);
+ create_dev("/dev/root", ROOT_DEV);
+ create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, n));
return rd_load_image("/dev/root");
}
diff --git a/init/initramfs.c b/init/initramfs.c
index f81cfa40a719..d28c1094d7e5 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -30,6 +30,7 @@ static void __init free(void *where)
static __initdata struct hash {
int ino, minor, major;
+ mode_t mode;
struct hash *next;
char name[N_ALIGN(PATH_MAX)];
} *head[32];
@@ -41,7 +42,8 @@ static inline int hash(int major, int minor, int ino)
return tmp & 31;
}
-static char __init *find_link(int major, int minor, int ino, char *name)
+static char __init *find_link(int major, int minor, int ino,
+ mode_t mode, char *name)
{
struct hash **p, *q;
for (p = head + hash(major, minor, ino); *p; p = &(*p)->next) {
@@ -51,14 +53,17 @@ static char __init *find_link(int major, int minor, int ino, char *name)
continue;
if ((*p)->major != major)
continue;
+ if (((*p)->mode ^ mode) & S_IFMT)
+ continue;
return (*p)->name;
}
q = (struct hash *)malloc(sizeof(struct hash));
if (!q)
panic("can't allocate link hash entry");
- q->ino = ino;
- q->minor = minor;
q->major = major;
+ q->minor = minor;
+ q->ino = ino;
+ q->mode = mode;
strcpy(q->name, name);
q->next = NULL;
*p = q;
@@ -229,13 +234,25 @@ static int __init do_reset(void)
static int __init maybe_link(void)
{
if (nlink >= 2) {
- char *old = find_link(major, minor, ino, collected);
+ char *old = find_link(major, minor, ino, mode, collected);
if (old)
return (sys_link(old, collected) < 0) ? -1 : 1;
}
return 0;
}
+static void __init clean_path(char *path, mode_t mode)
+{
+ struct stat st;
+
+ if (!sys_newlstat(path, &st) && (st.st_mode^mode) & S_IFMT) {
+ if (S_ISDIR(st.st_mode))
+ sys_rmdir(path);
+ else
+ sys_unlink(path);
+ }
+}
+
static __initdata int wfd;
static int __init do_name(void)
@@ -248,9 +265,15 @@ static int __init do_name(void)
}
if (dry_run)
return 0;
+ clean_path(collected, mode);
if (S_ISREG(mode)) {
- if (maybe_link() >= 0) {
- wfd = sys_open(collected, O_WRONLY|O_CREAT, mode);
+ int ml = maybe_link();
+ if (ml >= 0) {
+ int openflags = O_WRONLY|O_CREAT;
+ if (ml != 1)
+ openflags |= O_TRUNC;
+ wfd = sys_open(collected, openflags, mode);
+
if (wfd >= 0) {
sys_fchown(wfd, uid, gid);
sys_fchmod(wfd, mode);
@@ -291,6 +314,7 @@ static int __init do_copy(void)
static int __init do_symlink(void)
{
collected[N_ALIGN(name_len) + body_len] = '\0';
+ clean_path(collected, 0);
sys_symlink(collected + N_ALIGN(name_len), collected);
sys_lchown(collected, uid, gid);
state = SkipIt;
diff --git a/init/main.c b/init/main.c
index f715b9b89753..0766e69712b2 100644
--- a/init/main.c
+++ b/init/main.c
@@ -11,11 +11,9 @@
#define __KERNEL_SYSCALLS__
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/proc_fs.h>
-#include <linux/devfs_fs_kernel.h>
#include <linux/kernel.h>
#include <linux/syscalls.h>
#include <linux/string.h>
@@ -43,10 +41,16 @@
#include <linux/cpu.h>
#include <linux/cpuset.h>
#include <linux/efi.h>
+#include <linux/taskstats_kern.h>
+#include <linux/delayacct.h>
#include <linux/unistd.h>
#include <linux/rmap.h>
#include <linux/mempolicy.h>
#include <linux/key.h>
+#include <linux/unwind.h>
+#include <linux/buffer_head.h>
+#include <linux/debug_locks.h>
+#include <linux/lockdep.h>
#include <asm/io.h>
#include <asm/bugs.h>
@@ -79,7 +83,6 @@ extern void mca_init(void);
extern void sbus_init(void);
extern void sysctl_init(void);
extern void signals_init(void);
-extern void buffer_init(void);
extern void pidhash_init(void);
extern void pidmap_init(void);
extern void prio_tree_init(void);
@@ -125,6 +128,18 @@ static char *ramdisk_execute_command;
static unsigned int max_cpus = NR_CPUS;
/*
+ * If set, this is an indication to the drivers that reset the underlying
+ * device before going ahead with the initialization otherwise driver might
+ * rely on the BIOS and skip the reset operation.
+ *
+ * This is useful if kernel is booting in an unreliable environment.
+ * For ex. kdump situaiton where previous kernel has crashed, BIOS has been
+ * skipped and devices will be in unknown state.
+ */
+unsigned int reset_devices;
+EXPORT_SYMBOL(reset_devices);
+
+/*
* Setup routine for controlling SMP activation
*
* Command-line option of "nosmp" or "maxcpus=0" will disable SMP
@@ -150,6 +165,14 @@ static int __init maxcpus(char *str)
__setup("maxcpus=", maxcpus);
+static int __init set_reset_devices(char *str)
+{
+ reset_devices = 1;
+ return 1;
+}
+
+__setup("reset_devices", set_reset_devices);
+
static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
char * envp_init[MAX_INIT_ENVS+2] = { "HOME=/", "TERM=linux", NULL, };
static const char *panic_later, *panic_param;
@@ -159,16 +182,19 @@ extern struct obs_kernel_param __setup_start[], __setup_end[];
static int __init obsolete_checksetup(char *line)
{
struct obs_kernel_param *p;
+ int had_early_param = 0;
p = __setup_start;
do {
int n = strlen(p->str);
if (!strncmp(line, p->str, n)) {
if (p->early) {
- /* Already done in parse_early_param? (Needs
- * exact match on param part) */
+ /* Already done in parse_early_param?
+ * (Needs exact match on param part).
+ * Keep iterating, as we can have early
+ * params and __setups of same names 8( */
if (line[n] == '\0' || line[n] == '=')
- return 1;
+ had_early_param = 1;
} else if (!p->setup_func) {
printk(KERN_WARNING "Parameter %s is obsolete,"
" ignored\n", p->str);
@@ -178,7 +204,8 @@ static int __init obsolete_checksetup(char *line)
}
p++;
} while (p < __setup_end);
- return 0;
+
+ return had_early_param;
}
/*
@@ -446,10 +473,28 @@ static void __init boot_cpu_init(void)
cpu_set(cpu, cpu_possible_map);
}
+void __init __attribute__((weak)) smp_setup_processor_id(void)
+{
+}
+
asmlinkage void __init start_kernel(void)
{
char * command_line;
extern struct kernel_param __start___param[], __stop___param[];
+
+ smp_setup_processor_id();
+
+ /*
+ * Need to run as early as possible, to initialize the
+ * lockdep hash:
+ */
+ unwind_init();
+ lockdep_init();
+
+ local_irq_disable();
+ early_boot_irqs_off();
+ early_init_irq_lock_class();
+
/*
* Interrupts are still disabled. Do necessary setups, then
* enable them
@@ -489,7 +534,13 @@ asmlinkage void __init start_kernel(void)
init_timers();
hrtimers_init();
softirq_init();
+ timekeeping_init();
time_init();
+ profile_init();
+ if (!irqs_disabled())
+ printk("start_kernel(): bug: interrupts were enabled early\n");
+ early_boot_irqs_on();
+ local_irq_enable();
/*
* HACK ALERT! This is early. We're enabling the console before
@@ -499,8 +550,16 @@ asmlinkage void __init start_kernel(void)
console_init();
if (panic_later)
panic(panic_later, panic_param);
- profile_init();
- local_irq_enable();
+
+ lockdep_info();
+
+ /*
+ * Need to run this when irqs are enabled, because it wants
+ * to self-test [hard/soft]-irqs on/off lock inversion bugs
+ * too:
+ */
+ locking_selftest();
+
#ifdef CONFIG_BLK_DEV_INITRD
if (initrd_start && !initrd_below_start_ok &&
initrd_start < min_low_pfn << PAGE_SHIFT) {
@@ -541,6 +600,8 @@ asmlinkage void __init start_kernel(void)
proc_root_init();
#endif
cpuset_init();
+ taskstats_init_early();
+ delayacct_init();
check_bugs();
diff --git a/init/version.c b/init/version.c
index 3ddc3ceec2fe..e290802c6bd2 100644
--- a/init/version.c
+++ b/init/version.c
@@ -10,6 +10,7 @@
#include <linux/module.h>
#include <linux/uts.h>
#include <linux/utsname.h>
+#include <linux/utsrelease.h>
#include <linux/version.h>
#define version(a) Version_ ## a
OpenPOWER on IntegriCloud