diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index b98048b..a5b44b2 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -3771,8 +3771,14 @@ debug-uart get routed to the D+ and D- pins of the usb port and the regular usb controller gets disabled. - root= [KNL] Root filesystem - See name_to_dev_t comment in init/do_mounts.c. + root= [KNL] Fallback root filesystem when not using initramfs + If initramfs contains an /init file to run as PID 1 the + kernel ignores this setting. When initramfs doesn't have + /init (or whatever rdinit= points to) the kernel calls + prepare_namespace() in init/do_mounts.c to mount another + filesystem over / and chroot into it, then looks for + /sbin/init in there. (And /etc/init, /bin/init, and + /bin/sh for historical reasons.) rootdelay= [KNL] Delay (in seconds) to pause before attempting to mount the root filesystem diff --git a/Documentation/filesystems/ramfs-rootfs-initramfs.txt b/Documentation/filesystems/ramfs-rootfs-initramfs.txt index b176928..f3c57ba 100644 --- a/Documentation/filesystems/ramfs-rootfs-initramfs.txt +++ b/Documentation/filesystems/ramfs-rootfs-initramfs.txt @@ -67,6 +67,10 @@ A ramfs derivative called tmpfs was created to add size limits, and the ability to write the data to swap space. Normal users can be allowed write access to tmpfs mounts. See Documentation/filesystems/tmpfs.txt for more information. +The kernel uses tmpfs for ramfs when CONFIG_TMPFS=y and no "root=" is +specified in the kernel command line. If you can't stop yourself from +specifying root= you can also use "root=tmpfs". + What is rootfs? --------------- @@ -236,22 +240,10 @@ An initramfs archive is a complete self-contained root filesystem for Linux. If you don't already understand what shared libraries, devices, and paths you need to get a minimal root filesystem up and running, here are some references: -http://www.tldp.org/HOWTO/Bootdisk-HOWTO/ -http://www.tldp.org/HOWTO/From-PowerUp-To-Bash-Prompt-HOWTO.html -http://www.linuxfromscratch.org/lfs/view/stable/ - -The "klibc" package (http://www.kernel.org/pub/linux/libs/klibc) is -designed to be a tiny C library to statically link early userspace -code against, along with some related utilities. It is BSD licensed. -I use uClibc (http://www.uclibc.org) and busybox (http://www.busybox.net) -myself. These are LGPL and GPL, respectively. (A self-contained initramfs -package is planned for the busybox 1.3 release.) - -In theory you could use glibc, but that's not well suited for small embedded -uses like this. (A "hello world" program statically linked against glibc is -over 400k. With uClibc it's 7k. Also note that glibc dlopens libnss to do -name lookups, even when otherwise statically linked.) + http://www.tldp.org/HOWTO/Bootdisk-HOWTO/ + http://www.tldp.org/HOWTO/From-PowerUp-To-Bash-Prompt-HOWTO.html + http://www.linuxfromscratch.org/lfs/view/stable/ A good first step is to get initramfs to run a statically linked "hello world" program as init, and test it under an emulator like qemu (www.qemu.org) or @@ -264,11 +256,12 @@ User Mode Linux, like so: int main(int argc, char *argv[]) { printf("Hello world!\n"); - sleep(999999999); + sleep(999999999); // because if PID 1 exits the kernel panics } EOF gcc -static hello.c -o init echo init | cpio -o -H newc | gzip > test.cpio.gz + # Testing external initramfs using the initrd loading mechanism. qemu -kernel /boot/vmlinuz -initrd test.cpio.gz /dev/zero @@ -330,30 +323,3 @@ the above threads) is: http://www.uwsg.iu.edu/hypermail/linux/kernel/0112.2/1638.html and, most importantly, designed and implemented the initramfs code. - -Future directions: ------------------- - -Today (2.6.16), initramfs is always compiled in, but not always used. The -kernel falls back to legacy boot code that is reached only if initramfs does -not contain an /init program. The fallback is legacy code, there to ensure a -smooth transition and allowing early boot functionality to gradually move to -"early userspace" (I.E. initramfs). - -The move to early userspace is necessary because finding and mounting the real -root device is complex. Root partitions can span multiple devices (raid or -separate journal). They can be out on the network (requiring dhcp, setting a -specific MAC address, logging into a server, etc). They can live on removable -media, with dynamically allocated major/minor numbers and persistent naming -issues requiring a full udev implementation to sort out. They can be -compressed, encrypted, copy-on-write, loopback mounted, strangely partitioned, -and so on. - -This kind of complexity (which inevitably includes policy) is rightly handled -in userspace. Both klibc and busybox/uClibc are working on simple initramfs -packages to drop into a kernel build. - -The klibc package has now been accepted into Andrew Morton's 2.6.17-mm tree. -The kernel's current early boot code (partition detection, etc) will probably -be migrated into a default initramfs, automatically created and used by the -kernel build. diff --git a/init/do_mounts.c b/init/do_mounts.c index 7cf4f6d..62232f3 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -603,7 +603,6 @@ void __init prepare_namespace(void) sys_chroot("."); } -static bool is_tmpfs; static struct dentry *rootfs_mount(struct file_system_type *fs_type, int flags, const char *dev_name, void *data) { @@ -613,7 +612,7 @@ static struct dentry *rootfs_mount(struct file_system_type *fs_type, if (test_and_set_bit(0, &once)) return ERR_PTR(-ENODEV); - if (IS_ENABLED(CONFIG_TMPFS) && is_tmpfs) + if (IS_ENABLED(CONFIG_TMPFS)) fill = shmem_fill_super; return mount_nodev(fs_type, flags, data, fill); @@ -632,13 +631,7 @@ int __init init_rootfs(void) if (err) return err; - if (IS_ENABLED(CONFIG_TMPFS) && !saved_root_name[0] && - (!root_fs_names || strstr(root_fs_names, "tmpfs"))) { - err = shmem_init(); - is_tmpfs = true; - } else { - err = init_ramfs_fs(); - } + err = IS_ENABLED(CONFIG_TMPFS) ? shmem_init() : init_ramfs_fs(); if (err) unregister_filesystem(&rootfs_fs_type);