Not Screws and Bolts
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 gettys 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!
- 
        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.
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.
 
