...making Linux just a little more fun!

<-- prev | next -->

# Not Screws and Bolts

By Kapil Hari Paranjape

### 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 why1 you may want to do this is addressed in the last section, along with various philosophical 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:

- experienced user of Debian GNU/Linux
- developer of software on GNU/Linux
- experienced developer of software

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 Linux Gazette, as well). So we deal with the following cases:

- Your computer is running GNU/Linux, and you have root access.
- You are logged in as a non-root user on GNU/Linux.
- You are running some other operating/system on your computer.

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.

### Contents

- 1 The root suite
- 1.1 Doing the base thing
- 2 Root-less explorer
- 2.1 Polishing the UML
- 3 Birds of another feather
- 3.2 Adding some nuts
- 4 Why and eggs

### 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 the Debian mirror that 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 shut down 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 that 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, the archive contains `vmlinuz`, `initrd`, `image`, which 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 the 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 with 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 created 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 their 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 that 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:

- They own a computer or hardware that is not yet supported by Debian.
- They have hardware that "just works" with some (pre-)installed software (which may be GNU/Linux or some other operating system).
- They work on computers that are maintained by others.

Assuming 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 sandboxed environment requires some work to set up, which should probably form the basis of a second article!

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." ↩

Talkback: Discuss this article with The Answer Gang

Kapil Hari Paranjape has been a ``hack''-er since his punch-card days. Specifically, this means that he has never written a ``real'' program. He has merely tinkered with programs written by others. After playing with Minix in 1990-91 he thought of writing his first program---a ``genuine'' *nix kernel for the x86 class of machines. Luckily for him a certain L. Torvalds got there first---thereby saving him the trouble (once again) of actually writing code. In eternal gratitude he has spent a lot of time tinkering with and promoting Linux and GNU since those days---much to the dismay of many around him who think he should concentrate on mathematical research---which is his paying job. The interplay between actual running programs, what can be computed in principle and what can be shown to exist continues to fascinate him.

Copyright © 2008, Kapil Hari Paranjape. Released under the Open Publication License unless otherwise noted in the body of the article. Linux Gazette is not produced, sponsored, or endorsed by its prior host, SSC, Inc.

Published in Issue 156 of Linux Gazette, November 2008

<-- prev | next -->