From: Olaf Hering initramfs can not be used in current 2.6 kernels, the files will never be executed because prepare_namespace doesn't care about them. The only way to workaround that limitation is a root=0:0 cmdline option to force rootfs as root filesystem. This will break further booting because rootfs is not the final root filesystem. This patch checks for the presence of /sbin/init which comes from the cpio archive (and thats the only way to store files into the rootfs). This binary/script has to do all the work of prepare_namespace(). One can specify a different binary from the cpio archive via the kinit= option. It does not break current setups because initrd will not touch rootfs. Any why would one want to do that? After some thought, only 2 reasons come to mind: the cpio archive can be built as user (no loop mount required), and it should simplify migration to 2.7 (I hope the stuff behind prepare_namespace will disappear). --- Documentation/early-userspace/README | 28 ++++++++++++++++++++++++++++ Documentation/kernel-parameters.txt | 3 +++ init/main.c | 17 +++++++++++++++++ 3 files changed, 48 insertions(+) diff -puN Documentation/early-userspace/README~initramfs-kinit_command Documentation/early-userspace/README --- 25/Documentation/early-userspace/README~initramfs-kinit_command 2004-02-20 23:37:11.000000000 -0800 +++ 25-akpm/Documentation/early-userspace/README 2004-02-20 23:37:11.000000000 -0800 @@ -72,4 +72,32 @@ For questions and help, you can sign up mailing list at http://www.zytor.com/mailman/listinfo/klibc +How does it work? +================= + +The kernel has currently 3 ways to mount the root filesystem: +a) all required device and filesystem drivers compiled into the + kernel, no initrd. init/main.c:init() will call prepare_namespace() + to mount the final root filesystem, based on the root= option + and optional init= to run some other init binary than listed + at the end of init/main.c:init(). +b) some device and filesystem drivers built as modules and stored in + an initrd. The initrd must contain a binary '/linuxrc' which is + supposed to load these driver modules. It is also possible to + mount the final root filesystem via linuxrc and use the pivot_root + syscall. The initrd is mounted and executed via prepare_namespace(). +c) using initramfs. The call to prepare_namespace() must be skipped. This + means that a binary must do all the work. Said binary can be stored + into initramfs either via modifying usr/gen_init_cpio.c or via the new + initrd format, an cpio archive. It must be called "/sbin/init". + A different binary can be specified with the kinit= boot option. + This binary is responsible to do all the things prepare_namespace() + would do. + To remain backwards compatibility, the kinit binary will only run if + it comes via an initramfs cpio archive, or if the kinit= option is + specified. If this is not the case, init/main.c:init() will run + prepare_namespace() to mount the final root and exec one of the + predefined init binaries. + + Bryan O'Sullivan diff -puN Documentation/kernel-parameters.txt~initramfs-kinit_command Documentation/kernel-parameters.txt --- 25/Documentation/kernel-parameters.txt~initramfs-kinit_command 2004-02-20 23:37:11.000000000 -0800 +++ 25-akpm/Documentation/kernel-parameters.txt 2004-02-20 23:37:11.000000000 -0800 @@ -499,6 +499,9 @@ running once the system is up. keepinitrd [HW,ARM] + kinit= Specify the path to the init executable to replace + prepare_namespace() (for initramfs archives) + l2cr= [PPC] lapic [IA-32,APIC] Enable the local APIC even if BIOS disabled it. diff -puN init/main.c~initramfs-kinit_command init/main.c --- 25/init/main.c~initramfs-kinit_command 2004-02-20 23:37:11.000000000 -0800 +++ 25-akpm/init/main.c 2004-02-20 23:37:11.000000000 -0800 @@ -299,6 +299,15 @@ static int __init init_setup(char *str) } __setup("init=", init_setup); +static char *kinit_command; + +static int __init kinit_setup(char *str) +{ + kinit_command = str; + return 1; +} +__setup("kinit=", kinit_setup); + extern void setup_arch(char **); extern void cpu_idle(void); @@ -534,6 +543,7 @@ static void __init do_initcalls(void) flush_scheduled_work(); } +asmlinkage long sys_access(const char __user * filename, int mode); /* * Ok, the machine is now initialized. None of the devices * have been touched yet, but the CPU subsystem is up and @@ -597,6 +607,13 @@ static int init(void * unused) sched_init_smp(); do_basic_setup(); + /* + * check if there is an early userspace init, if yes + * let it do all the work + */ + if (kinit_command || sys_access("/sbin/init", 0) == 0) + execute_command = kinit_command ? kinit_command : 0; + else prepare_namespace(); /* _