Gentoo Wiki




This guide was heavily based on the "Gentoo Linux LiveCD for Dummies!" guide by veezi. This guide has changed considerably during its first month of life but it started as a simple upgrade/update on the one by veezi and still shares many things with it.

Introduction / Disclaimer

First of all, I have no idea what you can or cannot do with Catalyst so it could be that this is just a complicated way of re-inventing the wheel. The one and only thing I can assure you is that it works.

This is a relatively simple method most experienced Gentoo users will be able to follow without too many problems. Here is a rough list of what you should be confident with before attempting to follow this guide, some is common knowledge and some you may not be confident with:

Keep in mind that even if I provide a few scripts -- very simple ones as they're not meant to be powerful -- and some bash code fragment, they won't add up to a big complete installation script that you can run once to get a working iso. Always make sure you know exactly what you're doing unless I tell you "you will understand this later" and remember that the ctrl-c,ctrl-v combo can't really replace your brain :p

I tried to be as informative as I could; this is not a quick howto, it's meant to be a complete guide. The best way to follow this guide is to read a whole section without doing anything, then go back to the beginning and actually do what you're told to do as you go through the section a second time. Let me know if you feel this guide lacks detail in some or all of its parts.

The Host OS

The host operating system doesn't have to be Gentoo, e.g. I only built Gentoo livecds until now but the host system has always been SourceMage. Before you start reading the guide and building the livecd make sure the host OS you use meets the following requirements.

That's all.

First Steps (a.k.a emerge system)

This guide assumes you're always logged as root. Throughout the guide we'll also use features that imply you're going to run a 2.6 kernel on your livecd; if you want to run 2.4 you'll have to figure out what you have to change by yourself.

We need to install a Gentoo base system either inside a directory or in its own partition. It doesn't make a difference which approach you use but using a simple directory will be quicker and easier. On the other hand if you use a partition you can test the livecd without even creating an iso.

Create a directory that you will use exclusively for the building of the livecd. Set an environment variable to that path, like this:

export LIVEDIR="~/livecd"

or something like that. In the few scripts I provide and in the guide itself the variable LIVEDIR will be used extensively. In this guide and those scripts ${LIVEDIR} means "the content of the variable LIVEDIR", in this case ~/livecd.

Under ${LIVEDIR} create a directory called "source". If you have chosen to install Gentoo in its own partition you must now format it and mount it under ${LIVEDIR}/source. If you have a working Gentoo inside that partition, you're ready to go on; read the rest of this section just in case you have to make some changes (e.g. fstab and isolinux) and then go on with the guide. Make sure your installation isn't too big for the media you want to use; you can't tell how much space it will take on the cd until you've compressed it (more on that much later) but as a reference I can tell you my 1.1 GB gentoo installation produces a 316 MB iso. This guide will go on assuming you're building from scratch.

Inside ${LIVEDIR}/source/ unpack a stage3 tarball, chroot into it and rebuild the Gentoo base system with your own optimizations.

Warning: From now on we're chrooted inside the Gentoo base system. Keep in mind that /var really is ${LIVEDIR}/source/var on your HD.

When you build the base system follow this guidelines:

Once you're done, don't forget to activate whatever services you need. By the way, go for the parallel startup of services (RC_PARALLEL_STARTUP in /etc/conf.d/rc), it makes a huge difference when booting from a livecd.

File: /etc/fstab
 unionfs                 /               unionfs         defaults           0 0
 none                    /proc           proc            defaults           0 0
 none                    /dev/shm        tmpfs           defaults           0 0
 none                    /dev/pts        devpts          defaults           0 0

Whatever the system you built, this is what you must use. Add whatever you want but leave these lines unchanged. If you don't understand this particular configuration don't worry, by the end of this guide everything will be clear. Read it again after you've read the section of this guide that explains the initrd and the linuxrc script.

Our bootloader will be ISOLINUX since Grub doesn't work properly on many laptops. First create a directory under /boot called "isolinux". Copy inside that directory the file /usr/lib/syslinux/isolinux.bin and create an empty isolinux.cfg:

mkdir /boot/isolinux

cp /usr/lib/syslinux/isolinux.bin /boot/isolinux/

touch /boot/isolinux/isolinux.cfg

File: isolinux.cfg
timeout 1

default linux

label linux
 kernel vmlinuz
 append initrd=initrd init=/linuxrc root=/dev/ram0

As you can see our kernel will be named "vmlinuz". The "append" command does exactly what you think it does, which is appending whatever follows it to the kernel command line. The first parameter specifies the initrd to load in memory, the second states that the kernel must start an executable called "/linuxrc" instead of the default /sbin/init and the last tells the kernel to mount as root /dev/ram0, which will point to the initrd loaded in memory. We'll talk extensively about initrd and linuxrc scripts later on so for the moment hold your horses.

Don't exit the chroot yet; we need to make some tuning and install a generic kernel.

You have completed the first, most boring part of the guide.

Tuning the Directory Tree (And Other Important Things) (a.k.a. fix Gentoo so it will run from the cd)

If for any reason you dropped out of the system we're building, chroot back into it.

The directory /var contains two huge directories that we won't put inside the finished livecd; they are "cache" and "db". These are portage-related and completely useless as you won't emerge anything from a running read-only livecd, so let's move them together with other portage components that will be left out of our disk:

cd /var

mv cache db /usr/lib/portage/

ln -s /usr/lib/portage/cache cache

ln -s /usr/lib/portage/db db

That's it for /var. As you will see later, /usr/lib/portage will be left out of our livecd, freeing some precious space.

One other thing we must do is to modify the checkroot service. If we don't it'll try to remount the root filesystem readonly, causing problems with unionfs and making the bootup fail. Change the file so that it contains only the following:

File: /etc/init.d/checkroot
# Copyright 1999-2005 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
depend() {
        before *
start() {
        return 0
# vim:ts=4

Nothing less, nothing more than this.

We're finished adjusting things.

Don't exit from the chroot yet.

Kernel Configuration (a.k.a.: beyond genkernel)

Writing a generic kernel configuration is far from trivial. We're lucky enough since genkernel does it for us when we need a generic kernel for a regular Gentoo installation, but that tool is not perfectly suited for the custom livecd we want to build; kernels generated with it rely on the functionality of genkernel's initrd, which contains a complex script we don't want to modify as it would make things way too complex. My advice is to start with a simple kernel that runs on the hardware you own; you can go back inside our "build environment" (next section) later and spend some more time on kernel configuration once most of the difficult things have been dealt with.

If you feel like doing it right now but you still don't have the knowledge needed to do it, here's what I did the first time I built a livecd: I simply ran genkernel and stopped it while it was compiling. At that point genkernel had already placed a fine .config in /usr/src/linux. All I needed to do was to run "make menuconfig" and switch from "M" to "Y" anything I thought would be needed before mounting /, like IDE and SCSI drivers. Easy and fast, but I got a huge kernel with support for lots of hardware almost nobody owns.

Make sure you choose "Y" for ext2, squashfs and iso9660 filesystem support; you also need initrd support and you should make the default initrd size more than 9 megabytes.

Since we're going to use union, you'll have to include union support too. To keep things simple, please avoid doing emerge unionfs as it will only build a module. We want unionfs INSIDE the kernel. To get union among the other filesystems you see in menuconfig, download the source and run the therein. Next time you run menuconfig, unionfs will be there.

Once you're done configuring, compile the kernel and install its modules; name the kernel bzImage "vmlinuz", copying it in /boot/isolinux/. If you want you can use a better name, like "kernel-2.6.12-gentoo-r2", but make sure you change isolinux.cfg accordingly.

You can now exit from the chroot. We won't be going back into our Gentoo installation for a while.

Preparation Of The Build Environment (a.k.a.: make "mkdir" sound cool)

The following list of directories describes the "environment" in which our livecd will be built:

All of this dirs must be created under ${LIVEDIR}, except of course the directory "source" we have just filled with Gentoo c00ln3ss. Create all of them now.

So, how does it work? The directory usr-include will hold the contents of /usr/include, usr-portage the contents of /usr/portage and so on. This are some of the many dirs containing totally useless things that portage installed, like headers or documentation. We do need headers when we emerge something and docs to read up things we forgot, so instead of deleting them we're moving them out of the installation, keeping them nearby. In the end they'll be left out of the cd since we'll include only what's under the ${LIVEDIR}/source directory.

Before you actually move the files, take note of the following:

Note that we're moving /boot out of the system even though it'll obviously be required. That's ok, when we get to the point of building the livecd you'll see that it will be included on the disc after all, just not in the same way as the rest of the system. Indeed ${LIVEDIR}/source/* will be compressed inside a single file while we want the kernel to be present on the CD outside that file.

Here's the list of mv commands. The directories belonging to Xorg and gtk are included here as an example:

Warning: It's NOT /source/usr/share/gtk/doc

In the same way you can move anything that you think isn't needed out of the base system, e.g. most of gcc. If you mess up you can always go back by moving things back under their original directory. At the moment, however, you should stick to this list; it won't save a huge space but it's good enough for our first prototype. After you've made your first iso you'll be able to go beyond this guide easily.

Now that we have cleaned our base system from uncool things we can't emerge anything anymore. To get back the ability of adding software and read man pages we need to bind the directories under ${LIVEDIR} back to their original place under ${LIVEDIR}/source. Here's the script to do it, just to save some of your time. It also mounts proc and binds dev and sys so you can chroot into it immediately after you run it:

File: prepare_env
mount -t proc none source/proc

mount -o bind /sys source/sys
mount -o bind /dev source/dev
mount -o bind usr-src/ source/usr/src
mount -o bind usr-portage/ source/usr/portage
mount -o bind usr-lib-portage/ source/usr/lib/portage
mount -o bind usr-include/ source/usr/include
mount -o bind usr-share-info/ source/usr/share/info
mount -o bind usr-share-man/ source/usr/share/man
mount -o bind usr-share-doc/ source/usr/share/doc
mount -o bind usr-share-gtk-doc/ source/usr/share/gtk-doc
mount -o bind usr-X11R6-man/ source/usr/X11R6/man 

Tip: I also found it helpful to bind my Host Computer's distfiles to the CD. Saves a lot of bandwidth. --fREW

Here is the script to umount everything so you don't have to waste time writing it:

File: release_env
umount source/proc
umount source/sys
umount source/dev
umount source/usr/src
umount source/usr/portage
umount source/usr/lib/portage
umount source/usr/include
umount source/usr/share/info
umount source/usr/share/man
umount source/usr/share/doc
umount source/usr/share/gtk-doc
umount source/usr/X11R6/man

Tip: Make sure to umount the distfiles to if you followed my other tip! --fREW

Now we're all set. We can "switch on and off" the directories needed to compile packages; while they're "switched on" we can chroot inside ${LIVEDIR}/source and emerge whatever. If you want to backup your system before making some dangerous changes, just run prepare_env, umount sys dev and proc by hand and finally tar source/*.

For the advanced users: if you're wondering why I didn't just build an exclude list so I could pass it to mksquashfs, there's a simple reason. If you move something out of the base system and you're not sure if it really is unneeded, you can just mount proc, sys and dev and chroot inside the system to see if things still work. That's a lot of time gained since the alternative is to spend 20 minutes running the build script and burning the cd.

Initrd Creation (a.k.a.: head starts to spin)

An initrd is the image of a partition, usually formatted in ext2 (it must be little), containing some basic tools like mount and our linuxrc script. What we're going to do right now is to create an initrd that contains everything linuxrc needs.

Here is a simple list of things that happen when Linux boots up. It's not complete or exaustive, just good enough for what we have to do. Refer to the isolinux configuration I gave you in the first section as you read the list.

  1. The kernel and initrd are loaded in the RAM
  2. The kernel takes over and goes through a hardware recognition routine, activating all the drivers you compiled inside it. Anything compiled as module isn't usable yet.
  3. The kernel mounts the root partition specified by the "root" parameter specified in isolinux's configuration. In our case root equals /dev/ram0, which is the device bound to the initrd that has been loaded. That means the kernel mounts the initrd as the root partition.
  4. The kernel calls init. Since we passed the parameter init=/linuxrc, instead of /sbin/init the kernel executes /linuxrc. That's a script we'll write later (next section)
  5. The linuxrc script takes over. What it can or cannot do depends on what we put inside the initrd (this section deals with just that). Kernel modules are still off-limits with the initrd we'll create. At the end the script will call the real /sbin/init
  6. /sbin/init takes over. Gentoo boots normally going through all the services you activated.

Keep all this in mind and this section and the next will make a lot more sense.

We're going to create an initrd and then write a linuxrc script, effectively completing the livecd "framework". Once we've gone through this we can finally backup everything and start building whatever system we want, be it it a MythTV box or a diagnostics system.

First of all, create an empty file, 8 MB should be enough:

dd if=/dev/zero of=${LIVEDIR}/boot/isolinux/initrd bs=1M count=8

Bind the file to a loop device and format it ext2:

losetup /dev/loop0 ${LIVEDIR}/boot/isolinux/initrd

mkfs.ext2 /dev/loop0

Now we have an 8 MB "partition file" bound to /dev/loop0 and we can mount/umount it and copy files in it at will. Start by mounting it anywhere, laying out the basic directory structure of a root partion and touching some files:

mount /dev/loop0 /mnt/initrd

cd /mnt/initrd

mkdir etc dev lib bin proc new cdrom static dynamic union

touch linuxrc

chmod +x linuxrc

touch etc/mtab

touch etc/fstab

All those files go under /mnt/initrd/bin. pivot_root goes there too. Copy them now.

Next we have to copy inside the initrd all the libraries needed by those executables we just copied. To find out which libraries you need, use the comamnd "ldd". Like this:

#> ldd /bin/sh =>  (0xffffe000) => /lib/ (0xb7f72000) => /lib/ (0xb7f6b000) => /lib/ (0xb7f33000) => /lib/ (0xb7f2f000) => /lib/ (0xb7e42000)
/lib/ (0xb7fad000)

Run ldd once for each executable and copy all the libraries listed by it under /mnt/initrd/lib. Ignore

We need to populate /dev with devices so we have access to the hardware. Since we're not going to use udev in the initrd, we have to create the following devices by hand:

mknod /mnt/initrd/dev/console c 5 1

mknod /mnt/initrd/dev/null c 1 3

mknod /mnt/initrd/dev/hda b 3 0

mknod /mnt/initrd/dev/hdb b 3 64

mknod /mnt/initrd/dev/hdc b 22 0

mknod /mnt/initrd/dev/hdd b 22 64

mknod /mnt/initrd/dev/tty c 4 0

mknod /mnt/initrd/dev/loop0 b 7 0

Console, null and tty are the bare minimun you can have. Then we have the hd*, which will let us mount the cdrom, while loop0 will be needed to mount the compressed (squashfs) root image.

If your cd-rom drive is not an IDE or if you plan on adding support for non-IDE drives you'll need to create other devices and modify slightly the linuxrc script; however this guide will now proceed assuming you, like most people, own and use and IDE drive.

Don't umount the initrd yet.

Retrieved from ""

Last modified: Thu, 04 Sep 2008 03:56:00 +0000 Hits: 2,412