ChangeSet 1.990.1.4, 2003/02/19 10:39:00-08:00, greg@kroah.com Cset exclude: kai@tp1.ruhr-uni-bochum.de|ChangeSet|20030217001132|22043 diff -Nru a/init/Kconfig b/init/Kconfig --- a/init/Kconfig Wed Feb 19 11:41:05 2003 +++ b/init/Kconfig Wed Feb 19 11:41:05 2003 @@ -170,15 +170,5 @@ replacement for kerneld.) Say Y here and read about configuring it in . -config INITRAMFS - bool "Initial RAM FS" - depends on EXPERIMENTAL - help - This option moves the initial setup of the root filesystem - from kernel code (init/do_mounts.c) into early userspace - running from initramfs. - For now, the initial userspace does only support rooting - a local root filesystem, no NFS root, no initrd, no devfs. - endmenu diff -Nru a/init/Makefile b/init/Makefile --- a/init/Makefile Wed Feb 19 11:41:05 2003 +++ b/init/Makefile Wed Feb 19 11:41:05 2003 @@ -2,12 +2,7 @@ # Makefile for the linux kernel. # -obj-y := main.o version.o -obj-$(CONFIG_INITRAMFS) += initramfs.o -# Yeah, we need a obj-no-$(CONFIG_INITRAMFS) ... -ifndef CONFIG_INITRAMFS -obj-y += do_mounts.o -endif +obj-y := main.o version.o do_mounts.o initramfs.o # files to be removed upon make clean clean-files := ../include/linux/compile.h diff -Nru a/init/do_mounts.c b/init/do_mounts.c --- a/init/do_mounts.c Wed Feb 19 11:41:05 2003 +++ b/init/do_mounts.c Wed Feb 19 11:41:05 2003 @@ -63,10 +63,12 @@ int __initdata rd_doload; /* 1 = load RAM disk, 0 = don't load */ -extern dev_t ROOT_DEV; -extern int root_mountflags; +int root_mountflags = MS_RDONLY | MS_VERBOSE; static char root_device_name[64]; static char saved_root_name[64]; + +/* this is initialized in init/main.c */ +dev_t ROOT_DEV; static int do_devfs = 0; diff -Nru a/init/main.c b/init/main.c --- a/init/main.c Wed Feb 19 11:41:05 2003 +++ b/init/main.c Wed Feb 19 11:41:05 2003 @@ -43,10 +43,6 @@ #include #endif -/* this is initialized in arch code */ -dev_t ROOT_DEV; -int root_mountflags = MS_RDONLY | MS_VERBOSE; - /* * Versions of gcc older than that listed below may actually compile * and link okay, but the end product can have subtle run time bugs. @@ -231,8 +227,6 @@ if (val) val[-1] = '='; - printk("unknown %s\n", param); - /* Handle obsolete-style parameters */ if (obsolete_checksetup(param)) return 0; @@ -276,15 +270,7 @@ */ for (i = 1; i < MAX_INIT_ARGS; i++) argv_init[i] = NULL; - -#ifdef CONFIG_INITRAMFS - /* By returning 0 here, the init=... option will be added to the - * environment, so that the the code in the initramfs will know - * what init to execute */ - return 0; -#else return 1; -#endif } __setup("init=", init_setup); @@ -442,9 +428,7 @@ vfs_caches_init(num_physpages); radix_tree_init(); signals_init(); -#ifdef CONFIG_INITRAMFS populate_rootfs(); -#endif #ifdef CONFIG_PROC_FS proc_root_init(); #endif @@ -540,9 +524,7 @@ smp_init(); do_basic_setup(); -#ifndef CONFIG_INITRAMFS prepare_namespace(); -#endif /* * Ok, we have completed the initial bootup, and @@ -553,9 +535,6 @@ unlock_kernel(); system_running = 1; -#ifdef CONFIG_INITRAMFS - execve("/sbin/init",argv_init,envp_init); -#else if (open("/dev/console", O_RDWR, 0) < 0) printk("Warning: unable to open an initial console.\n"); @@ -575,6 +554,5 @@ execve("/etc/init",argv_init,envp_init); execve("/bin/init",argv_init,envp_init); execve("/bin/sh",argv_sh,envp_init); -#endif panic("No init found. Try passing init= option to kernel."); } diff -Nru a/scripts/Makefile b/scripts/Makefile --- a/scripts/Makefile Wed Feb 19 11:41:05 2003 +++ b/scripts/Makefile Wed Feb 19 11:41:05 2003 @@ -17,8 +17,7 @@ # Let clean descend into subdirs subdir- := lxdialog kconfig -# fixdep is needed to compile the rest -$(addprefix $(obj)/,$(filter-out fixdep,$(build-targets))): $(obj)/fixdep +# fixdep is needed to compile other host programs # dependencies on generated files need to be listed explicitly diff -Nru a/usr/Makefile b/usr/Makefile --- a/usr/Makefile Wed Feb 19 11:41:05 2003 +++ b/usr/Makefile Wed Feb 19 11:41:05 2003 @@ -19,7 +19,7 @@ # but we need the information for the build as well, so it's duplicated # here. -initramfs-y := $(obj)/root/init +initramfs-y := $(obj)/root/hello quiet_cmd_cpio = CPIO $@ cmd_cpio = ./$< > $@ diff -Nru a/usr/gen_init_cpio.c b/usr/gen_init_cpio.c --- a/usr/gen_init_cpio.c Wed Feb 19 11:41:05 2003 +++ b/usr/gen_init_cpio.c Wed Feb 19 11:41:05 2003 @@ -215,7 +215,7 @@ cpio_mknod("/dev/console", 0600, 0, 0, 'c', 5, 1); cpio_mkdir("/root", 0700, 0, 0); cpio_mkdir("/sbin", 0700, 0, 0); - cpio_mkfile("usr/root/init", "/sbin/init", 0700, 0, 0); + cpio_mkfile("usr/root/hello", "/sbin/hotplug", 0700, 0, 0); cpio_trailer(); exit(0); diff -Nru a/usr/root/Makefile b/usr/root/Makefile --- a/usr/root/Makefile Wed Feb 19 11:41:05 2003 +++ b/usr/root/Makefile Wed Feb 19 11:41:05 2003 @@ -1,4 +1,3 @@ -user-progs := init - -build-targets := $(user-progs) \ No newline at end of file +user-progs := hello +build-targets := hello \ No newline at end of file diff -Nru a/usr/root/init.c b/usr/root/init.c --- a/usr/root/init.c Wed Feb 19 11:41:05 2003 +++ b/usr/root/init.c Wed Feb 19 11:41:05 2003 @@ -1,442 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* FIXME: For the definition of Root_* */ -#include -#include -#include - -#include - -#include -#include -#include - - -#define BUF_SZ 4096 - -/* FIXME: arch bootblock param passing */ - -int do_devfs = 0; // FIXME -char *execute_command; // FIXME - -/* ---------------------------------------------------------------------- */ -/* Debugging */ - -#undef DEBUG - -#ifdef DEBUG - -static void -dbg_args(int argc, char **argv, char **envp) -{ - int i; - - for (i = 0; i < argc; i++) { - printf("%d: %s\n", i, argv[i]); - } - for (i = 0; envp[i]; i++) { - printf("%d: %s\n", i, envp[i]); - } -} - -#else - -static inline void dbg_args(int argc, char **argv, char **envp) {} - -#endif - -/* ---------------------------------------------------------------------- */ - -int _argc; -char **_argv; - -/* Was this argument passed? */ -int -getarg(const char *name) -{ - int i; - - for (i = 1; i < _argc; i++) { - if (_argv[i] && strcmp(_argv[i], name) == 0) - return 1; - } - return 0; -} - -/* Find dev_t for e.g. "hda,NULL" or "hdb,2" */ -dev_t -try_name(char *name, int part) -{ - char path[64]; - char buf[32]; - int range; - dev_t res; - char *s; - int len; - int fd; - - /* read device number from /sys/block/.../dev */ - sprintf(path, "/sys/block/%s/dev", name); - fd = open(path, 0, 0); - if (fd < 0) - goto fail; - len = read(fd, buf, 32); - close(fd); - - if (len <= 0 || len == 32 || buf[len - 1] != '\n') - goto fail; - buf[len - 1] = '\0'; - res = (dev_t) strtoul(buf, &s, 16); - if (*s) - goto fail; - - /* if it's there and we are not looking for a partition - that's it */ - if (!part) - return res; - - /* otherwise read range from .../range */ - sprintf(path, "/sys/block/%s/range", name); - fd = open(path, 0, 0); - if (fd < 0) - goto fail; - len = read(fd, buf, 32); - close(fd); - if (len <= 0 || len == 32 || buf[len - 1] != '\n') - goto fail; - buf[len - 1] = '\0'; - range = strtoul(buf, &s, 10); - if (*s) - goto fail; - - /* if partition is within range - we got it */ - if (part < range) - return res + part; - -fail: - return (dev_t) 0; -} - -/* - * Convert a name into device number. We accept the following variants: - * - * 1) device number in hexadecimal represents itself - * 2) /dev/nfs represents Root_NFS (0xff) - * 3) /dev/ represents the device number of disk - * 4) /dev/ represents the device number - * of partition - device number of disk plus the partition number - * 5) /dev/p - same as the above, that form is - * used when disk name of partitioned disk ends on a digit. - * - * If name doesn't have fall into the categories above, we return 0. - * Driverfs is used to check if something is a disk name - it has - * all known disks under bus/block/devices. If the disk name - * contains slashes, name of driverfs node has them replaced with - * dots. try_name() does the actual checks, assuming that driverfs - * is mounted on rootfs /sys. - */ - -dev_t -name_to_dev_t(const char *name) -{ - char *p; - dev_t res = 0; - char s[32]; - int part; - - mkdir("/sys", 0700); - mount("none", "/sys", "sysfs", 0, NULL); - - if (strncmp(name, "/dev/", 5) != 0) { - res = (dev_t) strtoul(name, &p, 16); - if (*p) - goto fail; - goto done; - } - name += 5; - res = Root_NFS; - if (strcmp(name, "nfs") == 0) - goto done; - - if (strlen(name) > 31) - goto fail; - strcpy(s, name); - - for (p = s; *p; p++) - if (*p == '/') - *p = '.'; - res = try_name(s, 0); - if (res) - goto done; - - while (p > s && isdigit(p[-1])) - p--; - if (p == s || !*p || *p == '0') - goto fail; - part = strtoul(p, NULL, 10); - *p = '\0'; - res = try_name(s, part); - if (res) - goto done; - - if (p < s + 2 || !isdigit(p[-2]) || p[-1] != 'p') - goto fail; - p[-1] = '\0'; - res = try_name(s, part); - done: - umount2("/sys", 0); - rmdir("/sys"); - return res; - fail: - res = (dev_t) 0; - goto done; -} - -int -find_in_devfs(char *path, dev_t dev) -{ -#ifdef CONFIG_DEVFS_FS - struct stat buf; - 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 (sys_newstat(path, &buf) < 0) - break; - if (!S_ISBLK(buf.st_mode)) - break; - if (buf.st_rdev != 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); -#endif - return -1; -} - -/* Create the device node "name" */ -int -create_dev(const char *name, dev_t dev, const char *devfs_name) -{ - char path[64]; - - unlink(name); - if (!do_devfs) - return mknod(name, S_IFBLK|0600, dev); - - if (devfs_name && devfs_name[0]) { - if (strncmp(devfs_name, "/dev/", 5) == 0) - devfs_name += 5; - sprintf(path, "/dev/%s", devfs_name); - if (access(path, 0) == 0) - return symlink(devfs_name, name); - } - if (!dev) - return -1; - - strcpy(path, "/dev"); - if (find_in_devfs(path, dev) < 0) - return -1; - - return symlink(path + 5, name); -} - -/* get a list of all filesystems to try to mount root with */ -void -get_fs_names(char *buf) -{ - char *s, *p; - char line[128]; - const char *root_fs_names; - FILE *f; - - root_fs_names = getenv("rootfstype"); - if (root_fs_names) { - strcpy(buf, root_fs_names); - for (s = buf; *s; s++) { - if (*s == ',') - *s = 0; - } - } else { - /* FIXME it'd be nice to get that information - * from /sys, to not introduce additional deps */ - mkdir("/proc", 0700); - if (mount("none", "/proc", "proc", 0, NULL) < 0) - goto out; - - buf[0] = 0; - f = fopen("/proc/filesystems", "r"); - if (!f) - goto done; - - s = buf; - while (fgets(line, 128, f)) { - if (line[0] != '\t') - continue; - p = strchr(line, '\n'); - if (!p) - continue; - - *p = 0; - strcpy(s, line + 1); - s += strlen(line + 1) + 1; - } - - done: - umount2("/proc", 0); - out: - rmdir("/proc"); - } -} - -/* mount the root filesystem from a block device */ -int -mount_block_root(dev_t root_dev, const char *root_dev_name, int flags) -{ - char fs_names[BUF_SZ]; - const char *data; - char *p; - - data = getenv("rootflags"); - - create_dev("/dev/root", root_dev, root_dev_name); - - get_fs_names(fs_names); -retry: - for (p = fs_names; *p; p += strlen(p)+1) { - if (mount("/dev/root", "/root", p, flags, data) == 0) - goto out; - - switch (errno) { - case -EACCES: - flags |= MS_RDONLY; - goto retry; - case -EINVAL: - continue; - } - /* - * Allow the user to distinguish between failed open - * and bad superblock on root device. - */ - fprintf(stderr, - "VFS: Cannot open root device \"%04x\"\n", - root_dev); - return -errno; - } - fprintf(stderr, "VFS: Unable to mount root fs on \"%04x\"\n", - root_dev); - return -ESRCH; - -out: - printf("VFS: Mounted root (%s filesystem)%s.\n", - p, (flags & MS_RDONLY) ? " readonly" : ""); - return 0; -} - -/* mount the root filesystem via NFS */ -int -mount_nfs_root(int flags) -{ - fprintf(stderr, "VFS: NFS root is not supported in initramfs yet.\n"); - return -EINVAL; -} - -/* mount root filesystem */ -void -mount_root(dev_t root_dev, const char *root_dev_name) -{ - int flags = MS_RDONLY | MS_VERBOSE; - int retval; - - if (getarg("ro")) - flags |= MS_RDONLY; - if (getarg("rw")) - flags &= ~MS_RDONLY; - - if (root_dev == Root_NFS) - retval = mount_nfs_root(flags); - else - retval = mount_block_root(root_dev, root_dev_name, flags); - - if (retval == 0) { - chdir("/root"); - } -} - -int -main(int argc, char **argv, char **envp) -{ - const char *root_dev_name, *init; - dev_t root_dev = 0; - - _argc = argc; - _argv = argv; - - if (open("/dev/console", O_RDWR, 0) < 0) - return 2; - - dup(0); - dup(0); - - dbg_args(argc, argv, envp); - - printf("INITRAMFS running.\n"); - - root_dev_name = getenv("root"); - if (root_dev_name) { - root_dev = name_to_dev_t(root_dev_name); - if (strncmp(root_dev_name, "/dev/", 5) == 0) - root_dev_name += 5; - } - - mount_root(root_dev, root_dev_name); - - umount2("/dev", 0); - mount(".", "/", NULL, MS_MOVE, NULL); - chroot("."); - - init = getenv("init"); - if (init) - execve(init, argv, envp); - - execve("/sbin/init", argv, envp); -#if 0 - execve("/etc/init", argv, envp); - execve("/bin/init", argv, envp); - execve("/bin/sh", argv_sh, envp); -#endif - fprintf(stderr, "No init found. Try passing init= option.\n"); - return 0; -}