# initrd woes

## square_

gentoo wont boot with an initrd. its been to long since i used one last, maybe anyone can point out the error ...

the error message is something like 

```
Kernel panic: no init found. Try passing init= option...
```

linuxrc is executable, its in the / of my initrd, which lies in /boot on my harddisk. no separate /boot-partition.

btw, is there no more option in make menuconfig to set the size of the initrd? i didnt find any.

```
# cat linuxrc 

#!/bin/sh

export PATH=/bin

# Get kernel CMDLINE

mount -t proc none /proc

CMDLINE=`cat /proc/cmdline`

umount /proc

mount -t reiserfs /dev/hda /new > /dev/null 2>&1

mount -t tmpfs -o size=20m none /new/etc > /dev/null 2>&1

mount -t tmpfs -o size=20m none /new/bin > /dev/null 2>&1

mount -t tmpfs -o size=20m none /new/lib > /dev/null 2>&1

mount -t tmpfs -o size=20m none /new/sbin > /dev/null 2>&1

mount -t tmpfs -o size=240m none /new/var > /dev/null 2>&1

mount -t tmpfs -o size=180m none /new/tmp > /dev/null 2>&1

tar -zpxf /new/etc.tar.gz -C /new/etc > /dev/null 2>&1

tar -zpxf /new/bin.tar.gz -C /new/bin > /dev/null 2>&1

tar -zpxf /new/lib.tar.gz -C /new/lib > /dev/null 2>&1

tar -zpxf /new/sbin.tar.gz -C /new/sbin > /dev/null 2>&1

tar -zpxf /new/var.tar.gz -C /new/var > /dev/null 2>&1

# Pivot root and start real init

cd /new

pivot_root . newroot

exec chroot . /bin/sh <<- EOF >dev/console 2>&1

exec /sbin/init ${CMDLINE}

EOF 
```

```

# cat /boot/grub/grub.conf

default 1

timeout 5

title=Gentoo Linux 2.6.23

root (hd0,0)

kernel /boot/kernel-gentoo-2.6.23 root=/dev/hda1

title=Gentoo Linux 2.6.24-r3

root (hd0,0)

kernel /boot/kernel-gentoo-2.6.24-r3 root=/dev/hda1

title=Gentoo Linux 2.6.24-r3 pivot_root

root (hd0,0)

kernel /boot/kernel-gentoo-2.6.24-r3 root=/dev/ram0 rw init=/linuxrc

initrd /boot/initrd
```

```
# ls -lh linuxrc 

-rwxr-xr-x 1 root root 937 2008-03-24 14:13 linuxrc
```

----------

## VinzC

Try renaming /linuxrc into /init. Make sure Block devices > Ram disk support (CONFIG_BLK_DEV_RAM), General setup > Initial RAM filesystem and RAM disk (CONFIG_BLK_DEV_INITRD) are enabled in your kernel config.

I don't know about Grub but with syslinux/extlinux and initial RAM drives, you must have root argument point to the real root filesystem (i.e. /dev/hda1 for you) instead of /dev/ram0 otherwise you'll have the RAM disk used twice. When using an initrd, all I had to do was append initrd=/inirtd argument.

So you might try the following:

```
title=Gentoo Linux 2.6.24-r3 pivot_root

    root (hd0,0)

    kernel /boot/kernel-gentoo-2.6.24-r3 root=/dev/hda1 rw initrd=/boot/initrd
```

Last note, I've used busybox instead of nash and switch_root instead of pivot_root.

----------

## square_

ok i changed root= in grub.conf. i changed linuxrc to init, too, but that didnt have any effect, so its back to linuxrc.

im either one step closer or one farther away, hard to say   :Laughing: 

heres the output of dmesg:

```
420-ReiserFS: hda1: checking transaction log (hda1)

421-ReiserFS: hda1: Using r5 hash to sort names

422-VFS: Mounted root (reiserfs filesystem).

423:Trying to move old root to /initrd ... /initrd does not exist. Ignored.

424-Unmounting old root

425-Trying to free ramdisk memory ... okay

426-Freeing unused kernel memory: 220k freed
```

i specified /boot/initrd in grub.conf, so i dont know why he looks for /initrd. moving /boot/initrd to /initrd doesnt help.

kernel config:

```
localhost / # cat /boot/config-kernel-gentoo-2.6.24-r3 | grep CONFIG_BLK_DEV_RAM

CONFIG_BLK_DEV_RAM=y

CONFIG_BLK_DEV_RAM_COUNT=16

CONFIG_BLK_DEV_RAM_SIZE=8192

CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024

localhost / # cat /boot/config-kernel-gentoo-2.6.24-r3 | grep CONFIG_BLK_DEV_INITRD

CONFIG_BLK_DEV_INITRD=y
```

----------

## square_

i would really appreciate help, im not getting any further here.

one thing: i created the initrd myself, a ext2 formated file filled with bins and libs. the kernel seems to complain about it not being initramfs, but that might only be the normal autodetection ... ?

----------

## VinzC

For your exact issue I have no answer yet. You might as well take a look at a post I wrote about creating an initramfs to load firmware for QLogic cards. The principle remains and it's the only direction I headed.

You might also take a look at that topic. There's also RedHat's mkinitrd but it should be considered a template for going on. It doesn't fit Gentoo for several reasons but it's a nice start if you need to understand what to do.

----------

## x22

The initrd file should be gzipped ext2 filesystem image (or any filesystem which is supported by kernel). Is your initrd image gzipped?

root=/dev/ram0 and init=/linuxrc should be correct options. 

I don't use initrd but initramfs, which is different thing. I need it since my root fs is on LVM.

Do you really need initrd?

----------

## square_

 *x22 wrote:*   

> The initrd file should be gzipped ext2 filesystem image (or any filesystem which is supported by kernel). Is your initrd image gzipped?
> 
> root=/dev/ram0 and init=/linuxrc should be correct options. 
> 
> I don't use initrd but initramfs, which is different thing. I need it since my root fs is on LVM.
> ...

 

no i dont need initrd. but its just simpler. and afaik it doesnt need to be gzipped.

when i want to build initramfs i depend on a program to build it because theres no way i can ever understand it   :Razz: 

hmmm, do i need to write something in /etc/fstab in my initrd? i just realized the file is there but its empty.

what would i write in there? 

```
/dev/ram0     /     etx2
```

?

----------

## VinzC

 *x22 wrote:*   

> root=/dev/ram0 and init=/linuxrc should be correct options.

 

The default script for RAM disks is /linuxrc. The default script for RAMFS is /init. RAMFS are CPIO images, compressed or uncompressed. This is the prefered way now. CPIO images don't need a loopback filesystem.

In your script you either hardcode the root filesystem with a mount instruction or can, say, parse the root=/dev/xxx command line argument - provided your shell supports this; busybox does. You can also rely on specifics provided by tools like nash, which parses the command line for you and lets you create the device nodes that you need to hand control to the real /sbin/init script.

You don't need root=/dev/ram0 with RAMFS because 2.6 kernels use /dev/ram0 internally as the initial boot device as soon as argument initrd=xxx is present.

You can then parse command line arguments in your initrd - with busybox as the shell - to determine which device to mount as the new root filesystem. You can also use nash, since it has a much shorter footprint; it provides instruction mkrootdev, which parses the command line to find the real root device. In this case you must either provide argument root=/dev/xxx with xxx being the device that contains the real root filesystem or write the corresponding device number into /proc/sys/kernel/real-root-dev. (It's indeed much simpler to rely on nash's ability to parse the command line...  :Wink:  )

With just the argument initrd=xxx appended to the command line the kernel expects to find a script in the root directory of the ramdisk image with name init. It needs to be a physical file with execute permission, not a symlink. You can make a /sbin/init symlink that points to /init if you want to.

If you need firmware loading you'll need busybox. Otherwise nash is enough. In the latter case use switch_root instead of pivot_root.

----------

## x22

Everything in your original configuration seems to be OK.  I tried it and it worked.

Here is my test configuration:

grub.conf:

```

title=[test] Gentoo Linux 64 2.6.24-gentoo-r3-64v02rd, initrd

root (hd0,2)

kernel /boot/bzImage-2.6.24-gentoo-r3-64v02rd vga=773 root=/dev/ram0 rw init=/linuxrc ramdisk_size=10000

initrd /boot/initrd.test

```

I need the ramdisk_size parameter because my compiled-in ramdisk size is 4096KB and ramdisk has 10000KB. I have tried it without ramdisk_size=10000 and kernel complained about too small size.

/linuxrc:

```

#!/bin/bash

echo Mounting /proc

mount -t proc none /proc

echo Mounting /sys

mount -t sysfs none /sys

initargs=$(cat /proc/cmdline)

echo initargs: $initargs

echo activating lvm

vgchange -a y gentoo_main

echo mounting newroot

mount -t ext3  /dev/gentoo_main/root64 /new

echo chdir

cd /new

echo umounting /proc

umount /proc

echo umounting /sys

umount /sys

echo pivot

pivot_root . newroot

exec chroot . /bin/sh <<- EOF >dev/console 2>&1

exec /sbin/init ${initargs}

EOF

```

You should have /newroot directory in real root filesystem but it boots even without it. 

Kernel config:

```

# grep DEV_RAM /boot/config-2.6.24-gentoo-r3-64v02rd

CONFIG_BLK_DEV_RAM=y

CONFIG_BLK_DEV_RAM_COUNT=16

CONFIG_BLK_DEV_RAM_SIZE=4096

CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024

# grep INITRD /boot/config-2.6.24-gentoo-r3-64v02rd

CONFIG_BLK_DEV_INITRD=y

```

dmesg:

```

...

checking if image is initramfs...it isn't (bad gzip magic numbers); looks like an initrd

Freeing initrd memory: 10000k freed

...

RAMDISK driver initialized: 16 RAM disks of 10000K size 1024 blocksize

...

RAMDISK: ext2 filesystem found at block 0

RAMDISK: Loading 10000KiB [1 disk] into ram disk... done.

VFS: Mounted root (ext2 filesystem).

Freeing unused kernel memory: 232k freed

kjournald starting.  Commit interval 5 seconds

...

```

(the last message comes from the mount command in initrd)

The initrd is completely custom (I didn't use mkinitrd or something like that). It uses mostly standard programs (I copied all required files from the real system). 

(initrd.test is uncompressed ext2 image.)

----------

## square_

ok, that last post made me go through linuxrc more carefully again.

it was possibly the most stupid mistake.

my file started with 

```
#!/bin/sh
```

, but i have only /bin/bash on the initrd and no symlink.

thanks and sorry    :Smile: 

----------

## VinzC

I then suggest you used busybox (or even nash from package mkinitrd) instead of bash. just symlink /bin/nash or /bin/bb with /bin/sh.

----------

## square_

 *VinzC wrote:*   

> I then suggest you used busybox (or even nash from package mkinitrd) instead of bash. just symlink /bin/nash or /bin/bb with /bin/sh.

 

i guess that would work too, but i just changed

```
#!/bin/sh
```

to

```
#!/bin/bash
```

 :Razz: 

i want to try initramfs next, but at least this old method still works.

----------

## VinzC

Well, it's best to add a symlink /bin/sh that points to the current shell - if you take a look to Gentoo you'll see /bin/sh actually points to /bin/bash. Now if you put another shell in the initrd you'll have to change the script header accordingly. To avoid such mistakes it's best to adopt the convention that the default shell is always /bin/sh. Hence changing a shell only requires changing the symlink, leaving the script untouched.

----------

