Not Screws and Bolts

Author: Kapil Hari Paranjape
Date: 28 October 2008

Introduction

The aim of these notes is to give you root access to a Debian "lenny" installation on on your existing computer without worrying about any hardware issues. To do this, you will not need to re-boot your computer and will only append to the existing data on it.

The question of why [1] you may want to do this is addressed in the last section along with various philosphical issues. You may want to read that section if you start wondering whether the steps described are worth all the trouble.

The instructions will assume that you are in at least one of the following categories of people:

The complexity of steps you need to carry out is directly proportional to the "distance" between your existing computer installation and Debian "lenny". The case when you are already running Debian GNU/Linux with root access is the topic of another article (available in the Linux Gazette as well). So we deal with the following cases:

These three cases roughly correspond to the three categories of users listed above in terms of skill required. In all cases we will make use of network access (though this can be avoided) so your computer should have a reasonable speed link to the internet.


[1] The great 20th century mathematician Andre Weil once said (in response to a request for motivation) something like: "I'm providing the mathematics. You can provide your own motivation."

The root suite

Start by getting root access to a GNU/Linux system. We don't really care how you do it, though we encourage you to do the lawful thing at all times! This system should have wget, perl, bash, ar, tar and GNU coreutils installed.

You also need to have some block device with adequate space. In what follows we will assume that the bash variable BLK_DEV contains the full path to this block device.

If you have disk space but no free partition, then you can do the following:

mkdir -p /var/lib/images
dd if=/dev/zero bs=1M count=2000 of=/var/lib/images/loop.base
BLK_DEV=$(losetup -f)
losetup -f $BLK_DEV /var/lib/images/loop.base

Doing the base thing

Create a new file system on the block device:

mke2fs $BLK_DEV
mount $BLK_DEV /mnt
mkdir /mnt/root
cd /mnt/root

Find a Debian mirror which is nearest to you (in terms of network connectivity) and set the variable DEBIAN_MIR to contain the url of this mirror (including the trailing /debian). Browse the sub-url pool/main/d/debootstrap under $DEBIAN_MIR to locate a recent version of debootstrap and let DEBOOTSTRAP_URL contain the full url for this version.

Download and extract debootstrap.deb in /mnt/root:

wget $DEBOOTSTRAP_URL -o debootstrap.deb
ar xv debootstrap.deb
tar xzf data.tar.gz

The next step is to set things up to run debootstrap:

chmod +x /mnt/root/usr/sbin/debootstrap
mkdir -p /usr/share
DEBOOTSTRAP=/mnt/root/usr/sbin/debootstrap
DEBOOTSTRAP_DIR=/mnt/root/usr/share/debootstrap
export DEBOOTSTRAP_DIR

Finally use this to install "lenny" in /mnt:

eval $DEBOOTSTRAP lenny /mnt $DEBIAN_MIR

Just a little clean up job at the end:

rm -rf /mnt/root/*
cd /

You then have a brand-new shiny Debian lenny image in $BLK_DEV mounted at /mnt. This can be used in different ways, the simplest being something like:

umount /mnt
mkdir -p /srv/chroot/lenny
cat >> /etc/fstab <<EOF
$BLK_DEV /srv/chroot/lenny ext2 defaults 0 0
EOF
mount /srv/chroot/lenny

The command to use this image will then be

DEB_ROOT_CMD="chroot /srv/chroot/lenny"

You could also use the image with schroot, vserver, openVZ, kvm or Xen. The latter two will require the addition of an appropriate Linux kernel in a manner similar to that in the section on "Adding some nuts".

Root-less explorer

When you do not have root access to your GNU/Linux machine (or you have root access but do not want to use it), you must first perform some preliminary steps.

The most crucial step is to get User Mode Linux (UML) working on your GNU/Linux system. How easy this is will depend on your distribution and on how much software is already installed by your GNU/Linux system administrator. We will also need to use networking with UML. The method that does not need root intervention uses Slirp; this is what the steps outlined below use.

To check that your installation of this software is adequate for our purposes, you should run the following test:

UML_CMD='linux root=/dev/root rootfstype=hostfs rootflags=/ \
  eth0=slirp,,slirp-fullbolt con0=fd:0,fd:1 \
  umid=mkimg init=/bin/bash'

eval $UML_CMD

Of course, if you use something other than slirp for networking then you should use the appropriate eth0= option.

This should give you a root prompt. You should check that networking works and then shutdown your UML with halt -f. To set up networking you run a sequence of commands like the following (which are for slirp).

ifconfig eth0 up
ifconfig eth0 10.0.2.15 netmask 255.255.255.0
route add default dev eth0

Test it by trying to connect to some local service like ssh at 10.0.2.2 or to some internet service like your nearest Debian mirror.

Also set the variable UML_DIR to the path which contains the modules for your UML kernel.

At this point you could skip the rest of this section and install rootstrap by downloading the source from the sub-directory pool/main/r/rootstrap of your nearest Debian mirror. This can be configured to carry out the remaining steps in this section automatically,

Proceeding manually, create a file to hold a file-system image:

WKDIR=$HOME/uml
mkdir -p $WKDIR
dd if=/dev/zero bs=1M count=2000 of=$WKDIR/uml.img

and boot the system with

eval $UML_CMD udb0=uml.img

You will get a root prompt in your UML.

Start by setting up some important filesystems like /proc, /dev, /sys, /tmp and /verb/lib/modules. On a Debian system this would be done by executing commands given below. Do the right thing for your system! (Hint: Look at what file systems are listed in /proc/mounts.)

/etc/init.d/mountkernfs.sh start
/etc/init.d/udev start
mount --bind $UML_DIR /lib/modules/
mount -t tmpfs tmpfs /tmp

Also setup networking as outlined above. Next, create device node for ubd0 and set it as the block device.

mknod /tmp/ubd0 b 98 0
BLK_DEV=/tmp/ubd0

The final step is to setup the PATH variable if that is not set automatically:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
export PATH

You are now in a position where you can follow the instructions in the section on "Doing the base thing". After that some more steps need to be carried out to setup this image to boot as a UML image.

Polishing the UML

If you have followed things so far, you should have used debootstrap to create a Debian lenny filesystem under /mnt.

Enter the image using chroot

mount -t proc proc /mnt/proc
chroot /mnt

Install udev which is what Debian uses for managing the /dev heirarchy.

apt-get update
apt-get install udev

If you don't want to use udev then you need to create the device nodes manually; in that case don't forget to create /dev/ubd* for the filesystem image based block devices.

Next, create an appropriate /etc/fstab file:

cat >> /etc/fstab <<EOF
/dev/ubda /     ext2 defaults                   0 1
proc    /proc   proc    defaults                        0 0
tmpfs   /tmp    tmpfs   defaults,size=768M              0 0
EOF

and the network configuration file:

cat >> /etc/network/interfaces <<EOF
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 10.0.2.15
    netmask 255.255.0.0
    up route add -net 0.0.0.0 dev eth0
    up route add -net 0.0.0.0 gw 10.0.2.2
EOF

Then exit the chroot and copy the modules directory:

cp -a $UML_MOD/. /mnt/lib/modules/.

Finally, unmount /mnt and halt the UML system:

umount /mnt/proc
umount /mnt
halt -f

The command for entering the new system is:

DEB_ROOT_CMD="linux root=/dev/ubda ubd0=$WKDIR/uml.img \
  eth0=slirp,,slirp-fullbolt \
  con0=fd:0,fd:1 con=pty \
  umid=lenny ro"

This will attach getty's to your terminal and to a number of pseudo-ttys on your system. You can use any of these to login to your Debian "lenny" system; no root password is set.

Birds of another feather

The Qemu system is a way to run different systems inside another system. We will use it to run Debian "lenny".

The critical step is to get qemu working along with some usable GNU/Linux disk image. For example, I used to provide an archive which contained vmlinuz, initrd, image. It can be booted as follows:

QEMU_CMD="qemu -hda image -snapshot -kernel vmlinuz -initrd initrd \
  -append ' root=/dev/hda quiet console=ttyS0 ro single' \
  -no-reboot -nographic"

eval $QEMU_CMD

At the prompt you press enter to get a root prompt.

On the other hand, you may have a bootable disk image hdimage lying around which you could test with some command like:

$QEMU_CMD="qemu -hda hdimage -snapshot -boot c -no-reboot"

eval $QEMU_CMD

This image should have a working bash, perl, tar and GNU coreutils (at the very least). You should also have some way to transfer data from inside the Qemu to the outside.

Note that the -snapshot option to qemu ensures that you do not write to your image file. After testing the image you can halt the system and it will not have written anything to your image.

Now create a qemu image to hold the file-system:

WKDIR=$HOME/qemu
mkdir -p $WKDIR
cd $WKDIR
qemu-img create -f qcow2 lenny.img 500M

and boot the system with

eval $QEMU_CMD -hdb lenny.img

At the root prompt set BLK_DEV=/dev/hdb.

You are now in a position where you can apply the instructions in section on "Doing the base thing". After that you will need to carry out some more steps to make the image bootable under Qemu as explained below.

Adding some nuts

At this point you should be in qemu with $BLK_DEV mounted at /mnt. You need to add a kernel to your Debian "lenny" file-system to get it ready to boot.

First enter it with chroot.

mount -t proc proc /mnt/proc
chroot /mnt

and install an appropriate linux kernel according to your architecture:

apt-get update
apt-get install linux-image-2.6-686

(Select the option to create an initrd image when prompted.) Next, create some required files on this file-system. The /etc/fstab file:

cat >> /etc/fstab <<EOF
/dev/hda /     ext2 defaults                   0 1
proc    /proc   proc    defaults                        0 0
tmpfs   /tmp    tmpfs   defaults,size=768M              0 0
EOF

and the network configuration file:

cat >> /etc/network/interfaces <<EOF
auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
    address 10.0.2.15
    netmask 255.255.0.0
    up route add -net 0.0.0.0 dev eth0
    up route add -net 0.0.0.0 gw 10.0.2.2
EOF

We also setup the /etc/inittab to use serial port logins:

sed -i -e '/^#T[01]/s/^#//' /etc/inittab

You can now exit the chroot.

The kernel and initrd need to be extracted from the image and put into the workdir $WKDIR so that you can boot using them. For example, you could use the ssh client dropbear which is on the image (if you used the downloadable one).

cat /mnt/boot/vmlinuz* | \
  dbclient user@10.0.2.2 'cat > $WKDIR/vmlinuz'
cat /mnt/boot/initrd* | \
  dbclient user@10.0.2.2 'cat > $WKDIR/initrd'

Finally, you can unmount the image and halt the system:

umount /mnt/proc
umount /mnt
halt -f

The command for using the new system is:

DEB_ROOT_CMD="qemu -hda $WKDIR/lenny.img \
  -kernel vmlinuz -initrd initrd \
  -append ' root=/dev/hda console=ttyS0 ro' \
  -no-reboot -nographic"

You can add the -snapshot option to avoid overwriting the image by mistake while you are playing this system.

Why and eggs

Why would one choose this method of installing Debian when there is the new and revamped Debian installer that even has a graphical installer?

This article was worked on primarily to help the people who belong to the categories listed in the introduction and want to develop software for Debian. All such people need to have a nicely working Debian environment in which they can build and test their packages. They may not want to (or be able to) run the Debian "testing" distribution directly on the hardware. The environment created in the article forms a base where they can install a collection of useful packages and start hacking on Debian.

There is a more philosophical reason why I like this method of installing Debian. I appreciate the enormous amount of effort that people have put into getting all manners of diverse hardware to work with GNU/Linux. However, creating an installer which can be used by any new user of computers is only one way to achieve "World Domination".

There are a number of creative people who could benefit by using Debian to create text, programs, music, graphics, video but cannot/will not use it natively on their hardware because:

Assuming that some of these people actually want to use Debian to be creative, they represent a chicken and egg problem for those who advocate using Debian. I hope this article points one way out for them.

There is likely to be some criticism that the methods described above will be very slow and use a lot of use of network bandwidth. Indeed using emulation does need good hardware and some tuning. Moreover, using graphics, audio and video at near native speeds in such a sandbox-ed environment requires some work to setup which should probably form the basis of a second article!