Gentoo Wiki


This article is still a Stub. You can help Gentoo-Wiki by expanding it.

Please improve it in any way that you see fit, and remove this notice {{Cleanup}} from the article. For tips on cleaning and formatting see Cleanup process

Please format this article according to the guidelines and Wikification suggestions, then remove this notice {{Wikify}} from the article

This article will show you how to construct a custom initramfs from the ground up, to do whatever you want. This article will focus on creating an initramfs for lvm2 root.

Warning: While I have done this quite a number of times, this article is currently written completely from memory. Errors and omissions are likely, proceed at your own risk. ALWAYS have another way to boot into your system available - if ash doesn't like the script, things can get tricky.
Note: Most of this process should work fine in a user's home directory except mounting stuff into the chroot and copying the new kernel to /boot


Working Directories

First, we set up some working directories:

Code: Set up working directories
cd /usr/src
mkdir -p initramfs/{usr/portage,image/{dev,proc,newroot}}


Then, we download and unpack a stage3 to initramfs-chroot:

Note: This is to keep uclibc out of your main system
Code: Create minimal gentoo in chroot

We pull in some things from our host to keep things easy:

Warning: PAY ATTENTION to where the slashes are - half these directories are inside the chroot, half outside. You do not want to get them mixed up
Code: Link stuff from host to save space and time
mount -o bind /dev dev/
mount -o bind /dev/pts dev/pts
mount -t sysfs sysfs-chroot sys
mount -t proc proc-chroot proc
mount -o bind /usr/portage usr/portage
cp /etc/resolv.conf etc/

Then we chroot:

Code: Chroot
chroot . bash
source /etc/profile

Making Uclibc

We make ourselves a minimal c library, in this case uclibc:

Note: TODO: pare uclibc down to the minimum we need to save space
Code: Emerge uclibc
emerge -avt uclibc

Static busybox and LVM2

We make ourselves a static busybox and lvm2:

Warning: Placing USE flags on the command line like this is a BAD IDEA - however, in this specific case it does exactly what we want.
Note: TODO: pare busybox down to the minimum we need to save space - just ash, mdev, mount, umount and switch_root
Note: The ROOT directive here tells emerge to put the resultant files somewhere other than /
Code: Emerge static busybox and lvm2
USE="static" ROOT="/image" emerge -avt busybox lvm2

Finishing the Image

We remove all the extraneous cruft that got installed, and pull in a few things that were missing:

Warning: PAY ATTENTION to where the slashes are - we are doing stuff to the image pointed to by ROOT directive above, NOT your chroot or main filesystem
Code: Cleanup
cd /image
rm -r usr/{doc,share,man,info}
cp -av /dev/{console,null} dev/

Boot Script

We write a script that will set up our lvm and then hop into the new root:

Note: TODO: test and refine this script - It's presented here purely from memory
Code: Boot Script
cat <<END > /image/linuxrc
fail() {
  echo "hrm, something is broke, have a shell"
  exec ash
echo -n Mounting /proc...
mount -t proc proc /proc || fail
echo " OK"

echo -n Mounting tmpfs over /dev...
mount -t tmpfs dev-tmpfs /dev
echo " OK"

echo -n Starting Mdev...
mdev -s
echo " OK"

echo -n Starting LVM2
vgchange -ay || fail
echo " OK"

echo -n Creating Nodes
vgmknodes || fail
echo " OK"

echo -n Mounting rootfs...
echo " OK"

echo Umounting intermediaries...
umount /proc
umount /dev
echo " OK"

echo Switching root, hold on!
switch_root /newroot /sbin/init


Kernel Setup

We set our kernel up to use the new image:

Linux Kernel Configuration: Initramfs Options
General setup  --->
[*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
(/usr/src/initramfs/image)    Initramfs source file(s)

Now make and install your kernel as usual:

Warning: This is how I do my kernels. Your process is probably different
Note: TODO: figure out how to make this wrap without the wiki clobbering it
Code: Install new kernel
cd /usr/src/linux
make O=../linux-build bzImage modules modules_install && \
mount /boot && \
cp ../linux-build/arch/i386/boot/bzImage /boot/kernel-$(( head -n5 Makefile | sed 's/ //g'; echo 'echo $VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION'; ) | bash) && \
mv /boot/new /boot/current && \
ln -s kernel-$(( head -n5 Makefile | sed 's/ //g'; echo 'echo $VERSION.$PATCHLEVEL.$SUBLEVEL$EXTRAVERSION'; ) | bash) /boot/new && \
umount /boot

Final Step

Reboot and see how you went!

Triffid hunter

See Also

Retrieved from ""

Last modified: Mon, 08 Sep 2008 06:35:00 +0000 Hits: 3,449