Joined: 15 Nov 2004
|Posted: Tue Dec 07, 2004 7:31 pm Post subject: Installing Gentoo Stage1 inside a UML
|This howto will show you how to build gentoo from stage 1 using user-mode linux.
User-Mode-Linux is a means to run a linux kernel as an application on a linux box. The implications
are huge for secure enviroments, dedicated hosting providers and really anyone that wants to play
with some new app but doesn't want to destroy their existing linux machine. This howto will show
you how to build gentoo 2004.3 from stage1 while being inside a UML. When you are done, you will
have a complete gentoo install inside of a single file that you can run without rebooting.
The first thing you will need is to set your system up to run UML. I am going to run through this
very quickly, but it should work for most systems. If you run into problems, please search the
UML mailing lists at http://marc.theaimsgroup.com/?l=user-mode-linux-user&r=1&w=2
You will need to download 5 items.
stage1-x86-2004.3.tar.bz2 from your favorite gentoo mirror. Be sure to get the x86 version.
The first step, and the most intrusive, is you need to patch your host kernel with the skas-v7 patch.
SKAS stands for Seperate Kernel Address Space and is a security/performance patch for UML. UML will
run without this patch being installed in what is called thread tracking mode, but their are some
security risks and performance issues.
tar xvjf linux-2.6.9.tar.bz2
patch -Np1 -i ../skas-2.6.9-v7.patch
Configure and compile this kernel as you normally would. Install the kernel and boot it.
The next step requires fresh kernel sources. You do NOT want to use your systems kernel sources.
So we are going to again untar linux-2.6.9, but into a different directory.
tar xvjf linux-2.6.9.tar.bz2 -C uml_src
bzip2 -d uml-2.6.9-bb4.patch.bz2
mv uml-2.6.9-bb4.patch uml_src/
patch -Np1 -i ../uml-2.6.9-bb4.patch
make menuconfig ARCH=um
Note the "ARCH=um" statement is REALLY important. If you omit it, you won't be building a
After the kernel has been configured, you can build it with the following.
Again, the "ARCH=um" statement is awful important. Omit it and I have no idea what you will be
Once the compile completes, you will have a file called linux in the linux kernel source
directory. If you execute that file by running
you should see something like this
Checking for the skas3 patch in the host...found
Checking for /proc/mm...found
Checking PROT_EXEC mmap in /tmp...OK
The rest should look just like a regular kernel booting with the exception of the panic
at the end (yes, it's ok for it to panic at this point). The "Checking" statements
are from the UML kernel looking for the skas patch we applied and /proc/mm support.
If you dont get a found on both of those statements, odds are you either didn't apply the
skas patch or you didnt boot the kernel that you applied the skas patch to. If all went
well though, you now have a uml kernel built and ready for use. Their are a few more
steps we need to take before we can install gentoo though.
We now need to install the UML_Utils software. This includes tunctl, uml_mconsole and
some other handy programs that make umls easy to work with.
tar xvjf uml_utilities_20040406.tar.bz2
That should install UML_utils. Note that you must have readline installed.
We are now ready to create our disk
UMLs most typically use a file as their harddrive. This has a couple of benefits, the
most obvious being that the entire OS can be picked up and moved onto another machine.
COW files (copy on write) can be setup so that your UMLs can all share one OS image, but
each have their own writeable space. So instead of 4 gentoos all running with 4 2 gig
files, you could have 4 gentoos running with 1 2 gig shared root image and 4 however
large or small COW files. We can also use what is known as a sparse file to create, for
example, a 4 gig "disk" but have it only use as much disk space on our host system as
it needs. So if you only have 50 meg of data in your 4 gig "disk" then it will only
use up 50 meg of your actual drive space (plus filesystem overhead)!
To create our sparse file, do the following
dd of=root_fs bs=1024 count=0 seek=2000000
Say yes when mkfs tells you that you are not creating a filesystem on a block device. The
dd command says create a file (of=root_fs) using a block size of 1k (bs=1024), don't atually write those blocks out (count=0) but allocate 2 gig for that file (seek=2000000).
The end result is that we have a 2 gig file that only uses a couple of megs of space.
# du -h root_fs
# ls -lh root_fs
2.0G Dec 8 10:13 root_fs
Now we need to mount that filesystem. We do that be creating a directory to use as
our mount point and then mounting root_fs as a loopback filesystem.
mount root_fs uml -o loop
root_fs is now mounted as uml! do a df -h to prove it
# df -h
SIZE Used AVAIL % MOUNTED ON
1.9G 10M 1.9G 100% /home/jason/uml
Once the filesystem is mounted, we need to untar our stage1 file inside of it.
tar xvjf ../stage1-x86-2004.3.tar.bz2
The Gentoo stage1 install assumes that you are building from a chroot enviroment
inside a machine that is connected to the internet. Since we will be booting our UML
and doing our install that way, we need to make a few changes. We need to copy
over the mount and ip utilities from our host system. If you do not have the ip
program, you will need to copy over ifconfig and route. We do that with the following
cp `which mount` usr/bin
cp `which ip` usr/bin
#Do the following only if you dont have the ip program#
cp `which ifconfig` usr/bin
cp `which route` usr/bin
Next we need to unmount our root_fs and get ready to boot our UML!
One of the neat things about UML is that it uses a file for its memory also.
This is all well and good, but harddrives don't hold a candle to memory when it
comes to speed, so we are going to give our UML a little bit of actual RAM to
play with. We do that by simply mounting /tmp as a tmpfs filesystem. The UML, when
it's using space in /tmp for its memory, will actually be using RAM. It helps to
speed things up considerably.
mount none /tmp -t tmpfs
And with that, we are ready to boot our UML!
uml_src/linux-2.6.9/linux ubd0=root_fs mem=128M eth0=tuntap,,,192.168.1.1 rw
Running that last command should set your uml off and booting and drop you
into a stage1 prompt ready for an install. But you probably want to know what
in the world you just did.
Remember that we created an executable called linux when we compiled our uml
kernel earlier. So we are now running that application with some options.
ubd0=root_fs Here we are telling our UML to use the root_fs file as its first
drive on its first disk, our root filesystem or /
mem=128M We need to tell the UML how much RAM it has, since it can't really
just detect it on its own. Anything over 64M should be fine, but
remember that if you run out of memory on your host machine you
will start swapping and that slows everyone down.
eth0=tuntap The linux kernel supports tap devices that allow you to essentially
have a virtual network in your box. By giving this flag, we are
telling our UML to use the uml_utils software that we installed to
give it access to your computers physical network by tunneling
everything to the physical interface that has the ip address of
192.168.1.1 . If your computers IP is different, then you should
replace that ip with the one that you have.
rw Mount the root filesystem readwrite. Forget this option and it will
be mounted readonly.
The eth0=tuntap,,,192.168.1.1 line is where most of the confusion can come in, so I
want to spend a little time explaining it. Since your UML doesn't have access to
an actual network card, we have to figure out some way for it to be able to talk to
the world. The way we do that is by tunneling or bridging the traffic from our UMLs
virtual interface to our host machines physical interface.
The easy way to set this up is the long command that we just ran. That tells the
UML that its virtual eth0 is going to be using the abilities of the physical interface
that has the IP of 192.168.1.1. Your host machine gets setup with a new interface of
tun0 and forwarding is setup between those interfaces. Then all you have to do is
assign an ip other then 192.168.1.1, but in the same subnet, to your UML and point
its default gateway to 192.168.1.1. Tada, instant networking! Their are some
security concerns with doing it this way, they are best detailed in the UML howto
at http://user-mode-linux.sourceforge.net/UserModeLinux-HOWTO-6.html, as well as
other methods of setting up networking. For our purposes though, this works
This may seem a bit confusing, but it's really out of the scope of this document to
describe UML networking in detail, the howto really does a fine job of that.
So now we are in gentoo! Just a few more steps and we can begin our isntall!
The first step is to mount a few filesystems
mount proc /proc -t proc
mount none /dev/pts -t devpts
Next we need to edit our make.conf to reflect our new host
CFLAGS="-O2 -mcpu=i686 -fomit-frame-pointer"
The "-sandbox" is VERY important. If you don't put that option in place, the build
will not get too far before it starts erroring out about permission problems. The
stage1 install assumes that you are in a chroot enviroment and tries to protect you
from damaging the host system. Since we are in a UML, we aren't really worried about
damaging anything so it's safe to disable. Something else to keep in mind is that
you NEVER want to enable nptl flags for glibc in your UML. UML is very incompatible with
nptl and you will get yourself into a very nasty pickle if you should install with it (thanks
for the heads up blaisorblade!).
The last thing we need to do is bring up our network. If you copied over the ip program earlier,
issue the following, replacing the ips with something that represents your enviroment.
ip addr add 192.168.1.111/24 brd + dev eth0
ip link set eth0 up
ip route add default via 192.168.1.1
if you copied over ifconfig and route, issue the following instead
ifconfig eth0 192.168.1.111 netmask 255.255.255.0 broadcast 192.168.1.255 up
route add default gateway 192.168.1.1 dev eth0
And with that, you should be up and running! Be sure to edit your /etc/resolv.conf file
to match the one on your host and you can now follow the stage1 install docs from gentoo.org!
Thanks goes to R. Bosch for noticing that I forgot to include a make mrproper.
Thanks goes to Zbynek Houska for catching a typo on the dd command.
Please send any bugs, comments or questions to firstname.lastname@example.org.