# initrd, initramfs, and 2.6 kernel

## psychocandy

Am I right in saying that in 2.6, initramfs is used rather than initrd?

OK. So this is what I've done.

1. Enabled RAM disk support etc in kernel and set default initial ramdisk size in the kernek to 32767.

2. Created a directory structire for the new ramdisk.

3. find . | cpio --dereference -o -H newc | gzip -9 > ../initramfs.cpio.gz to create the ramdisk file.

4. Copied this into my new /boot directory.

5. Copied the kernel image to my new /boot directory.

5. Edited my bootloader file (silo.conf) to include initrd=/boot/initramfs.cpio.gz

6. Burned my CD.

Boots. Starts to load kernel and then fails with 'Cannot open root device' again....

What am I doing wrong ???

----------

## VoVaN

Are you using initramfs as root? If that so, waht is your fstab? I'm using initramfs for diskless workstations and it works fine. The procedure you described looks fine with me, only few things:

1) fstab with initramfs at root

/dev/ram0                               /       tmpfs           size=64m                        0 0

2) bootloader should have root=/dev/ram0 option togeather with initrd=initramfs.cgz

3) If you mentioned, I'm using tmpfs instead original initramfs as it has some advantages like size option, it's possible with following patch:

```

diff -ur linux-2.6.14.orig/fs/Kconfig linux-2.6.14/fs/Kconfig

--- linux-2.6.14.orig/fs/Kconfig        2005-09-11 03:19:07.000000000 +0000

+++ linux-2.6.14/fs/Kconfig     2005-09-11 03:19:42.000000000 +0000

@@ -805,6 +805,18 @@

          See <file:Documentation/filesystems/tmpfs.txt> for details.

+config EARLYUSERSPACE_ON_TMPFS

+       bool "Unpack the early userspace onto tmpfs"

+       depends TMPFS

+       default y

+       help

+         Use this to have your early userspace placed (decompressed)

+         onto tmpfs as opposed ramfs. This will allow you to

+         restrict the size of your root-filesystem and it will also

+         be swappable.

+

+         If unsure, say Y.

+

 config HUGETLBFS

        bool "HugeTLB file system support"

        depends X86 || IA64 || PPC64 || SPARC64 || SUPERH || X86_64 || BROKEN

Only in linux-2.6.14/fs: Kconfig.orig

diff -ur linux-2.6.14.orig/init/initramfs.c linux-2.6.14/init/initramfs.c

--- linux-2.6.14.orig/init/initramfs.c  2005-08-28 23:41:01.000000000 +0000

+++ linux-2.6.14/init/initramfs.c       2005-09-11 03:19:42.000000000 +0000

@@ -6,6 +6,7 @@

 #include <linux/delay.h>

 #include <linux/string.h>

 #include <linux/syscalls.h>

+#include <asm/uaccess.h>

 static __initdata char *message;

 static void __init error(char *x)

@@ -463,6 +464,49 @@

        return message;

 }

+/* If we want the rootfs on initramfs so we mount initramfs over the

+ * rootfs before we unpack it. The little dance we do by creating a

+ * pivot point and moving the root to that is in fact necessary

+ * because lookups of "." don't resolve mountpoints.

+ */

+static inline void __init overmount_rootfs(void)

+   {

+#ifdef CONFIG_EARLYUSERSPACE_ON_TMPFS

+    int init_tmpfs(void);

+    int (*initfunc)(void) = init_tmpfs;

+    mm_segment_t oldfs;

+    char pivot[] = "/pivot";

+

+    /* Explicitly go and init the overmount fs early (long-term

+     * the need for this will probably go away. */

+

+    if (initfunc())

+    goto err;

+

+    oldfs = get_fs();

+    set_fs(KERNEL_DS);

+

+    if (sys_mkdir(pivot, 0700) < 0)

+    goto err;

+    if (sys_mount("tmpfs", pivot, "tmpfs", 0, "size=90%"))

+    goto err;

+

+    /* Below here errors are unlikely and icky to deal with. */

+    sys_chdir(pivot);

+    sys_mount(".", "/", NULL, MS_MOVE, NULL);

+    sys_chdir(".");

+    sys_chroot(".");

+    printk(KERN_INFO "Overmounted tmpfs\n");

+    goto out;

+

+    err:

+    printk(KERN_ERR "Overmount error\n");

+

+    out:

+    set_fs(oldfs);

+#endif /* CONFIG_EARLYUSERSPACE_ON_TMPFS */

+}

+

 extern char __initramfs_start[], __initramfs_end[];

 #ifdef CONFIG_BLK_DEV_INITRD

 #include <linux/initrd.h>

@@ -482,6 +526,9 @@

                        initrd_end - initrd_start, 1);

                if (!err) {

                        printk(" it is\n");

+#ifdef CONFIG_EARLYUSERSPACE_ON_TMPFS

+                        overmount_rootfs();

+#endif /* CONFIG_EARLYUSERSPACE_ON_TMPFS */

                        unpack_to_rootfs((char *)initrd_start,

                                initrd_end - initrd_start, 0);

                        free_initrd_mem(initrd_start, initrd_end);

diff -ur linux-2.6.14.orig/init/main.c linux-2.6.14/init/main.c

--- linux-2.6.14.orig/init/main.c       2005-09-11 03:19:07.000000000 +0000

+++ linux-2.6.14/init/main.c    2005-09-11 03:22:43.000000000 +0000

@@ -701,6 +701,11 @@

        if (sys_access((const char __user *) ramdisk_execute_command, 0) != 0) {

                ramdisk_execute_command = NULL;

                prepare_namespace();

+#ifdef CONFIG_EARLYUSERSPACE_ON_TMPFS

+                int init_tmpfs(void);

+                int (*initfunc)(void) = init_tmpfs;

+                initfunc();

+#endif /* CONFIG_EARLYUSERSPACE_ON_TMPFS */

        }

        /*

diff -ur linux-2.6.14.orig/mm/shmem.c linux-2.6.14/mm/shmem.c

--- linux-2.6.14.orig/mm/shmem.c        2005-09-11 03:19:07.000000000 +0000

+++ linux-2.6.14/mm/shmem.c     2005-09-11 03:19:42.000000000 +0000

@@ -2136,7 +2136,7 @@

 };

 static struct vfsmount *shm_mnt;

-static int __init init_tmpfs(void)

+int __init init_tmpfs(void)

 {

        int error;

@@ -2169,7 +2169,12 @@

        shm_mnt = ERR_PTR(error);

        return error;

 }

+/* Don't do this if we are calling it early explicity */

+#ifndef CONFIG_EARLYUSERSPACE_ON_TMPFS

+/* If CONFIG_EARLYUSERSPACE_ON_TMPFS is set then we will interpose

+ * ramfs so this will get called explicitly and early */

 module_init(init_tmpfs)

+#endif /* !CONFIG_EARLYUSERSPACE_ON_TMPFS */

 /*

  * shmem_file_setup - get an unlinked file living in tmpfs

```

and set EARLYUSERSPACE_ON_TMPFS=yes ofr you kernel

one more thing, if kernel detects initramfs it's using /init  as init, but not /sbin/init, so you have to create symlink or use own init (like I'm doing):

```

#!/bin/sh

echo " * Running networkboot prescript"

/bin/mount -o remount,size=64m /

#Now transfer the init to the original init application (got this from the livecd-ng)

exec /sbin/init </dev/console >/dev/console 2>&1

```

----------

## psychocandy

I dont really need to run init on start up but I think you'ver answered my question - i.e. you can have a script file as linuxrc / init.....

----------

## VoVaN

 *psychocandy wrote:*   

> I dont really need to run init on start up...

 

Probably you don't need, but you have to run init in order to have system booted successfully  :Wink: 

 *psychocandy wrote:*   

>  but I think you'ver answered my question - i.e. you can have a script file as linuxrc / init.....

 

it should be /init in case of initramfs, unless you set something else in your boot loader (like init=/linuxrc)

----------

## psychocandy

I still cant get system to boot if I use a shell script as linuxrc (or init)....

Get a kernel panic and it says could not mount root or something....

I'm currently using a binary linuxrc file I 'found' on an old 2.4 boot disk...

----------

## VoVaN

 *psychocandy wrote:*   

> I still cant get system to boot if I use a shell script as linuxrc (or init)....
> 
> Get a kernel panic and it says could not mount root or something....
> 
> I'm currently using a binary linuxrc file I 'found' on an old 2.4 boot disk...

 

/etc/fstab is your problem. Place a correct line for mounting root as I explaned above.

----------

## psychocandy

 *VoVaN wrote:*   

>  *psychocandy wrote:*   I still cant get system to boot if I use a shell script as linuxrc (or init)....
> 
> Get a kernel panic and it says could not mount root or something....
> 
> I'm currently using a binary linuxrc file I 'found' on an old 2.4 boot disk... 
> ...

 

I'll check my etc/fstab....

What should the correct entry be?

----------

## psychocandy

/dev/ram0 /   tmpfs size=64m 0 0

Is this for initramfs (cpio version) or other one (whats the proper name for this - ram disk?)

At the moment, with the linuxrc I've got, it seems to mount the ram stuff (whichever I use) onto / which is good.....

----------

## VoVaN

 *psychocandy wrote:*   

> 
> 
> ```
> /dev/ram0 /   tmpfs size=64m 0 0
> ```
> ...

 

this one for initramfs with the match above or use just

```
/dev/ram0 /   tmpfs rw 0 0
```

without the patch applied...

----------

## psychocandy

 *VoVaN wrote:*   

>  *psychocandy wrote:*   
> 
> ```
> /dev/ram0 /   tmpfs size=64m 0 0
> ```
> ...

 

OK. So this goes into /etc/fstab on my ramdisk, yeh?

So how does this get read if the ramdisk isnt mounted yet then?

Do I need to have anything in linuxrc or init then?

----------

## VoVaN

Sorry for saying that, but in my opinion you really need to read something in order to understand how the Linux boot process works. You're missing the background... There's a lot of documentation and HOWTO's...

----------

