Last updated $Date: 2008-06-05 12:50:40 $
Martti Kuparinen <martti.kuparinen@iki.fi>
http://www.iki.fi/kuparine/comp/ubuntu/en/uml.html
This is how I installed and configured User Mode Linux (UML) on my Ubuntu 8.04 workstation.
This article describes how I installed a small UML guest to perform some kernel debugging at work. I'm running 64-bit Ubuntu 8.04 on my workstation so the guest must also be 64-bit. This is important to remember if you use some previously created disk image.
The following packages are needed in this document. The libpcap-dev package is only needed if you activate pcap transport (UML Network Devices > pcap transport) in the kernel configuration phase.
sudo aptitude -y install debootstrap sudo aptitude -y install uml-utilities sudo aptitude -y install bridge-utils sudo aptitude -y install libpcap-dev
Please note that every guest needs its own disk image!
# Some directory on the local disk
export DSTDIR=/var/tmp
# Create 2 GB virtual disk
dd if=/dev/zero of=${DSTDIR}/imagefile seek=2 count=0 bs=1G
mkfs.ext3 -F ${DSTDIR}/imagefile
sudo mount -o loop ${DSTDIR}/imagefile /mnt
# Bootstrap a new Ubuntu host (for Debian, click here)
sudo debootstrap --verbose hardy /mnt http://archive.ubuntu.com/ubuntu
# Go into chroot and perform some configuration
sudo mount -t proc none /mnt/proc
sudo chroot /mnt /bin/bash
export LANG=C
cd /dev
mknod ubd0 b 98 0
# Ubuntu repositories (for Debian repositories, click here)
cat > /etc/apt/sources.list << EOF
deb http://archive.ubuntu.com/ubuntu hardy main restricted
deb http://archive.ubuntu.com/ubuntu hardy-updates main restricted universe
deb http://archive.ubuntu.com/ubuntu hardy-security main restricted
deb http://archive.ubuntu.com/ubuntu hardy universe multiverse
deb http://archive.ubuntu.com/ubuntu hardy-security universe multiverse
EOF
aptitude update && aptitude -y dist-upgrade
echo localhost > /etc/hostname
cat > /etc/hosts << EOF
127.0.0.1 localhost
EOF
cat > /etc/fstab << EOF
/dev/ubd0 / ext3 defaults 0 1
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
none /host hostfs defaults,noauto 0 0
EOF
mkdir -p /host
cat > /etc/network/interfaces << EOF
# We always want the loopback interface.
#
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet dhcp
EOF
sed -i '/ACTIVE_CONSOLES/s/.-./1-2/' /etc/default/console-setup
for i in /etc/event.d/tty[3-9]
do
sed -i 's/start/stop/' ${i}
done
ln -sf /usr/share/zoneinfo/Europe/Helsinki /etc/localtime
aptitude -y install less locales console-data
update-locale LANG=C
aptitude -y install tcpdump telnet openssh-client
# Prepare for optional image compression
apt-get clean
dd if=/dev/zero of=remove-this bs=8k
rm -f remove-this
exit
sudo umount /mnt/proc
sudo umount /mnt
# Optional image compression (backup to DVD, move to another host, ...)
bzip2 -9 -c ${DSTDIR}/imagefile > ${DSTDIR}/imagefile.bz2
ls -lh ${DSTDIR}/imagefile*
-rw-r--r-- 1 martti users 2.0G 2008-04-30 14:23 /var/tmp/imagefile
-rw-r--r-- 1 martti users 100M 2008-04-30 14:40 /var/tmp/imagefile.bz2
Please note how compressing the image before moving it to another host over network really makes sense, the size dropped from 2 GB to 100 MB!
export DSTDIR=/var/tmp
export KVER=2.6.24.3
cd ${DSTDIR}
wget http://www.kernel.org/pub/linux/kernel/v2.6/linux-${KVER}.tar.bz2
tar xjf linux-${KVER}.tar.bz2
# Without any saved .config
cd linux-${KVER}
make mrproper
make ARCH=um mrproper
make ARCH=um menuconfig
make ARCH=um
# With saved .config
cd linux-${KVER}
make mrproper
make ARCH=um mrproper
cp somewhere/.config .
make ARCH=um oldconfig
make ARCH=um
# Fetch the helper script cd /usr/bin sudo wget http://www.iki.fi/kuparine/comp/ubuntu/en/umlnet sudo chmod 755 umlnet # Start 5 virtual networks umlnet start 5 # Add internet connectivity (eth1) for the guests (tap0). Do NOT add eth0 # to the bridge or your host will be disconnected from the LAN... sudo ifconfig eth1 up sudo ifconfig eth1 promisc sudo brctl addbr br0 sudo brctl stp br0 off sudo brctl setfd br0 1 sudo brctl sethello br0 1 sudo brctl addif br0 eth1 sudo brctl addif br0 tap0 sudo ifconfig br0 up # Remove internet connectivity sudo ifconfig br0 down sudo brctl delbr br0 # Stop all networks when all guests have been halted umlnet stop
Guests are started after starting the virtual network (see above). As an example, to start a guest with 5 interfaces you need to execute the following commands. Please note how each interface is given a unique MAC address.
cd ${DSTDIR}/linux-${KVER}
xterm -T "Host 123" \
-e ${DSTDIR}/linux-${KVER}/vmlinux \
ubd0="${DSTDIR}/imagefile" \
umid="Host 123" \
eth0=daemon,ca:fe:ab:ba:00:00,,/tmp/link0 \
eth1=daemon,ca:fe:ab:ba:00:01,,/tmp/link1 \
eth2=daemon,ca:fe:ab:ba:00:02,,/tmp/link2 \
eth3=daemon,ca:fe:ab:ba:00:03,,/tmp/link3 \
eth4=daemon,ca:fe:ab:ba:00:04,,/tmp/link4 \
mem=128M &
These MAC addresses should be listed in the guest's /etc/udev/rules.d/70-persistent-net.rules to avoid weird-looking ethN_renamed interfaces. Please note that the MAC addresses are for some reason case sensitive!
sudo vi /etc/udev/rules.d/70-persistent-net.rules
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ca:fe:ab:ba:00:00", ATTR{type}=="1", NAME="eth0"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ca:fe:ab:ba:00:01", ATTR{type}=="1", NAME="eth1"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ca:fe:ab:ba:00:02", ATTR{type}=="1", NAME="eth2"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ca:fe:ab:ba:00:03", ATTR{type}=="1", NAME="eth3"
SUBSYSTEM=="net", ACTION=="add", ATTR{address}=="ca:fe:ab:ba:00:04", ATTR{type}=="1", NAME="eth4"
Guests are shut down by running "halt -p" inside each running guest.
In multi-UML scenario it's might be a good idea to use the umid and uml_dir options in addition to the ubdN, ethN and mem options used above. Execute the following command to see all available options.
${DSTDIR}/linux-${KVER}/vmlinux --help
You can mount the host's filesystems to be visible inside the guest by running
mount /host cd /host ls
The debugger normally intercepts some signal (like SIGSEGV) which I don't want to receive at this time. As an example, the SIGSEGV is normally caused by applications running on the userspace within the guest. Since I'm now debugging the kernel I want the debugger to ignore these signals so I can focus on the kernel problems.
cd ${DSTDIR}/linux-${KVER}
cat > .gdbinit << EOF
handle SIGUSR1 noprint nostop
handle SIGSEGV noprint nostop
set args \
ubd0=${DSTDIR}/imagefile \
umid="Host 123" \
eth0=daemon,ca:fe:ab:ba:00:00,,/tmp/link0 \
eth1=daemon,ca:fe:ab:ba:00:01,,/tmp/link1 \
eth2=daemon,ca:fe:ab:ba:00:02,,/tmp/link2 \
eth3=daemon,ca:fe:ab:ba:00:03,,/tmp/link3 \
eth4=daemon,ca:fe:ab:ba:00:04,,/tmp/link4 \
mem=128M
EOF
ddd ./vmlinux
TBD