update to uml.txt hint

Randy Hron rwhron at earthlink.net
Tue Aug 28 21:26:25 PDT 2001


-------------- next part --------------
TITLE:		User Mode Linux
LFS VERSION:	Any
AUTHOR:		Randy Hron <rwhron (at) earthlink.net>
 
SYNOPSIS:
	How to configure a basic user-mode-linux on lfs.
	  
HINT:
This hint is for user-mode-linux (uml) for linux-2.4.x.  We just set
up a small root filesystem, you may want to do more when you get up
and running.  

Why user-mode-linux?
====================
Experimentation.  It's cool.  You could try a new glibc or gcc without trashing 
your LFS by running it in user-mode-linux first.  Setup a virtual network with only 
one box.  Whatever you want.

Where can I find out more?
==========================
Project:  http://user-mode-linux.sourceforge.net/
HOWTO:    http://user-mode-linux.sourceforge.net/UserModeLinux-HOWTO.html
Patch:    http://sourceforge.net/project/showfiles.php?group_id=429

UML Patch for Linus kernel
==========================
The patch for user-mode-linux is at the site too.  You need the patch
for the version of the kernel you are running.  jdike and friends usually 
have a uml patch out within a day or so of a new Linus Torvalds (vanilla) 
kernel hitting http://www.kernel.org/.

Or no patch for Alan kernel
===========================
Alternatively, if you use Alan Cox kernels for LFS, you don't need a patch.  
acox and jdike keep pretty well synchonized.

This hint has a script for Linus kernels (build_uml) and Alan kernels 
(build_uml_ac).  Use the script that fits your host system.

Glossary
========
host:			Your linux box.  It is "hosting" the virtual
			uml machine(s).
host kernel:		The kernel for your LFS system.  It "hosts" the
			uml kernel.
kernel pool:		Source code tree of Linus kernel.  AKA extracted
			vanilla kernel.
pool:			The HOWTO uses pool to refer to a directory tree,
			like cvs, linux source, or the uml source tree.
uml:			User Mode Linux
user-mode-linux:	Let's user run a virtual instance of linux
vanilla kernel:		Term some kernel hackers call the official Linus 
			release.
virtual machine: 	Another name for a uml instance.

What do I need?
===============


Assumptions for this hint
=========================
o  You are Braveheart.  That's a given, you're an LFSer :)
o  You have Loopback Device (CONFIG_BLK_DEV_LOOP) support configured in 
   your host kernel (this doesn't mean lo0 = 127.0.0.1.  It means a regular
   file can be mounted as a filesystem).
o  You have Ethertap CONFIG_ETHERTAP configured in your kernel.
o  You want CONFIG_IP_MULTICAST=y in your kernel if you want to network 
   between two or more virual machines.
o  You need the uml-net-tools (possibly), (uml_net.c and Makefile)(for sure),
   uml_mconsole.c and Makefile are handy too.  All of these are available
   at the project site, but you have to get the tools from the uml cvs, as
   they don't have a tarball of tools yet.  Everything is at the project site.
o  You don't have anything in /mnt/uml or /usr/src/uml, as the build scripts
   included here will unquestionably stomp these directories.
o  You have reiserfsprogs installed.  ext2 will work too, you'll just have
   to edit the build_rootfs a little.
o  You have at least 16 megs of free ram.  You can boot uml with less, by
   passing mem=#m on the command line.  I.E. ./linux init=/bin/bash mem=8m
   will boot a virtual machine with 8 megs of ram.



Installing uml_net
=================
We'll start with the easiest part.  uml_net is used for setting
up a network between the host system and uml.  Grab uml_net.c and it's
Makefile from the download page for user-mode-linux.  make 
and install uml_net on your "host" (the only system you have
so far).  uml_net should be in your PATH and must be setuid root.

	chown root:root /usr/bin/uml_net &&
	chmod 4755 /usr/bin/uml_net

Installing uml_router
=====================
If you want to setup a network between the virtual uml machine and
the host system, you should grab uml_router.c and it's Makefile from
CVS at sourceforge.  uml_router is also installed in /usr/bin on the
host system.


Building the user-mode-linux kernel
===================================
IMPORTANT NOTE: Don't build user-mode-linux in /usr/src/linux because uml 
replaces some headers that other linux programs could use.  Also, you don't 
want to stomp your "host" kernel.

Note: the commands below assume your linux kernel source is in 
/usr/src/sources/l and the user-mode-linux patch in /usr/src/sources/u.
Change these paths to match where you have the kernel and uml-patch 
tarballs.  There may be an updated kernel or uml-patch that you want 
to use.  

There is some explanation of the scripts below.

Build uml kernel script from Linus source
=========================================
#!/bin/bash
# build_uml - create user mode linux kernel from Linus source
#
# silent_make="-s"
#
# tar uncompress options
tar_z_opt=j
# basedir for new uml tree
src=/usr/src
# kernel_src is the path to the kernel source
kernel_src=/usr/src/sources/l/linux-2.4.9.tar.bz2
# path to uml patch from http://user-mode-linux.sourceforge.net/
uml_src=/usr/src/sources/u/uml-patch-2.4.9-2.bz2
[ -c /dev/tap0 ] || mknod /dev/tap0 c 36 16 &&
[ -w $src ] || (echo cannot write to $src && exit 1)
cd /usr/src &&
rm -rf uml &&
mkdir uml &&
cd uml &&
echo "extracting $kernel_src in $PWD" &&
tar x${tar_z_opt}f $kernel_src &&
cd linux &&
bzcat $uml_src|patch -p1 &&
make mrproper &&
make mrproper ARCH=um &&
unset PAGER &&
cp /usr/src/linux/.config /usr/src/uml/linux &&
yes "y" | make oldconfig ARCH=um &&
sed 's:^CONFIG_GPROF.*:# CONFIG_GPROF is not set:' .config>.config~ &&
mv .config~ .config &&
sed 's:^CONFIG_GCOV.*:# CONFIG_GCOV is not set:' .config>.config~ &&
mv .config~ .config &&
yes "" | make config ARCH=um &&
make dep ARCH=um &&
make linux ARCH=um &&
make modules ARCH=um 
# end of build_uml

Or build the kernel from Alan Cox source
========================================
#!/bin/bash
# build_uml_ac build uml from alan cox source
#
# silent_make="-s"
#
# if non-priv user can write to $src, then non-priv user
# and build and run uml with this script.
src=/usr/src
ac_ver=-2.4.8-ac12
ac_src_tree=$src/linux${ac_ver}
[ -c /dev/tap0 ] || mknod /dev/tap0 c 36 16 &&
[ -w $src ] || (echo cannot write to $src && exit 1)
cd $sc &&
rm -rf uml &&
mkdir uml &&
cd uml &&
echo "copying $ac_src_tree to $PWD" &&
cp -rp $ac_src_tree $PWD
ln -s $src/uml/linux${ac_ver} $src/uml/linux
cd linux &&
make mrproper &&
make mrproper ARCH=um &&
unset PAGER &&
cp $ac_src_tree/.config /usr/src/uml/linux &&
yes "y" | make oldconfig ARCH=um &&
sed 's:^CONFIG_GPROF.*:# CONFIG_GPROF is not set:' .config>.config~ &&
mv .config~ .config &&
sed 's:^CONFIG_GCOV.*:# CONFIG_GCOV is not set:' .config>.config~ &&
mv .config~ .config &&
yes "" | make config ARCH=um &&
make dep ARCH=um &&
make linux ARCH=um &&
make modules ARCH=um &&
echo "user mode linux kernel is: $src/uml/linux/linux"
# end of build_uml_ac

Comments on uml kernel build commands
=====================================
Extract the pristine linux source for your uml tree.  Install the uml patch.
Keep most of your current configuration by copying .config from /usr/src/linux 
(not really necessary, just convenient).  Say "y" to the new config options
from the uml patch.  We run 'sed' against the .config file as CONFIG_GPROF
and CONFIG_GCOV were not be working perfectly when this was written.
We unset PAGER because I saw "make oldconfig" using $PAGER once.  Creates
/dev/tap0 if it doesn't exist.  (you will configure ethertap in the kernel, 
right?)

First boot (maybe)
=================
After running the commands above you will have a file called 
/usr/src/uml/linux/linux.  This is the uml kernel.  You can run it now as
any user (suggest that you aren't root, just to be safe).  It should panic
nicely for you because there is no root filesystem for uml yet.  

Cleaning up uml processes
=========================
If you were couragous and booted the kernel to see it panic, you can clean 
things up quickly my killing the "linux" processes for the uml kernel:

kill $(ps -fu $LOGNAME|awk '/linux/ {print $2}')

or better yet, setup an alias:
alias kuml="kill \$(ps -fu\$LOGNAME|
	awk '/[l]inux.*kern|[l]inux.*init|[l]inux.*thread/{print \$2}')"

Creating a root filesystem for user-mode-linux
==============================================
User mode linux will have it's own filesystem.  You have to have 
CONFIG_BLK_DEV_LOOP defined in your kernel to create a root filesystem 
for user-mode-linux.  You can look at your /usr/src/linux/.config file 
to see if you already have that.  If you don't, configure and compile 
your normal (host) boot kernel before continuing.  Hey we talked about
this at the top of the hint. :)

We'll create a 100 megabyte root filesystem using reiserfs.  You can use
ext2 or another fileystem if you want.  This filesystem will not contain
everything that a basic LFS system has, but it could.  For now, just
/bin /sbin /lib, and a few bits of /usr.

Note: The script below uses "here documents" and is very sensitive to 
extraneous spaces.  I.E. a space after a '!' character can cause the
script to not complete.  The safe way to execute this is to pop this
file into vim and grab the script verbatum.  Then read it and change
what you want.

Also note that down about 11 lines from here is an "export user=hrandoz"
line.  You want to change that to whatever user you typically login as.  
Note that we will grab /etc/passwd from the host system, so root for
uml will be your normal root password.

Root filesystem build script
============================
#!/bin/bash
# begin of root_fs setup - this is just to give you an idea of how it is done.
# root has to run this for losetup
#
# environment for this script
# $uml is where root_fs will be mounted and built.
# [ $UID == 0 ] || { echo "root has to do this for losetup" && exit 1 }
export uml=/mnt/uml &&
# src is where uml kernel source will be installed.
export uml_src=/usr/src/uml &&
# user is a regular user who will run uml at the end of the script
export user=hrandoz
# loopback block device
export loop=/dev/loop0
# uml_ip_address is the address you want the uml machine to have.
export uml_ip_address="192.168.0.230"
# argument for make to be quiet
silent_make="-s"
[ -c /dev/tap0 ] || mknod /dev/tap0 c 36 16 
(( $? == 0 )) &&
cd $uml_src/linux &&
# create 100 meg reiserfs root fs
dd if=/dev/zero of=root_fs seek=100 count=1 bs=1M &&
losetup $loop $uml_src/linux/root_fs &&
yes | mkreiserfs $loop &&
mkdir -p $uml &&
mount -t reiserfs $loop $uml &&
cd $uml &&
# create directory structure and copy /lib /sbin /dev into rootfs
mkdir -p bin dev etc lib mnt proc root sbin tmp usr/bin usr/sbin var/run var/log &&
chmod 1777 tmp &&
mkdir -p usr/share/terminfo/l &&
[ -f /usr/share/terminfo/l/linux ] && cp -p /usr/share/terminfo/l/linux usr/share/terminfo/l &&
cd /dev &&
find . -print|cpio -pdm $uml/dev &&
mknod $uml/dev/tap0 c 36 16
cd /sbin &&
find . -print|cpio -pdm $uml/sbin &&
cd /bin &&
find . -print|cpio -pdm $uml/bin &&
cd /lib &&
find . -maxdepth 1 -print|cpio -pdm $uml/lib &&
# grab a couple useful tools
cp -p /usr/bin/vi /usr/bin/grep $uml/usr/bin &&
for f in /usr/sbin/{inetd,in.telnetd,in.rlogind,in.ftpd,tcpd} 
do	[ -f $f ] && cp -vp $f ${uml}${f}
done 	# don't include && after the for loop or we won't get /etc.
# Get passwd and shadow so we can login with the same accounts as the host
cp -p /etc/passwd /etc/shadow $uml/etc && 
cat<<!>$uml/etc/fstab
/dev/bd0	/		reiserfs	defaults	0 0
proc		/proc		proc		defaults	0 0
none		/dev/pts	devpts		defaults	0 0
!
(( $? == 0 )) &&
cat <<!>$uml/etc/inittab
# user-mode-linux inittab
id:2:initdefault:
si:S:sysinit:/etc/rc.d/rc.sysinit
l0:0:wait:/etc/rc.d/rc.0
l1:S1:wait:/etc/rc.d/rc.1
l2:2:wait:/etc/rc.d/rc.2
l3:3:wait:/etc/rc.d/rc.3
l4:4:wait:/etc/rc.d/rc.4
l5:5:wait:/etc/rc.d/rc.5
l6:6:wait:/etc/rc.d/rc.6
ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now
su:S1:respawn:/sbin/sulogin
c1:2:respawn:/sbin/agetty console 38400 console
!
(( $? == 0 )) &&
mkdir $uml/etc/rc.d &&
cat <<!>$uml/etc/rc.d/rc.0
#!/bin/sh
# /etc/rc.d/rc.0
#Sending TERM signal to all processes.
/sbin/killall5 -15

#Sending KILL signal to all processes.
/sbin/killall5 -9

#Unmounting swap partitions.
#/sbin/swapoff -a

case "$0" in
        *6)
          /sbin/reboot -w
          ;;
        *0)
          /sbin/halt -w
          ;;
esac

#Syncing filesystems.
/bin/sync

#Remounting root filesystem ro.
/bin/mount -n -o remount,ro /

#Unmounting other filesystems
/bin/umount -a

case "$0" in
        *6)
          /sbin/reboot -d -f -i
          ;;
        *0)
          /sbin/halt -d -f -p
          ;;
esac
# end of /etc/rc.d/rc.0
!
(( $? == 0 )) &&
cat<<!>$uml/etc/rc.d/rc.1
#!/bin/sh
# /etc/rc.d/rc.1
#Disabling eth0.
#/sbin/ifconfig eth0 down

#Sending TERM signal to all processes.
/sbin/killall5 -15

#Sending KILL signal to all processes.
/sbin/killall5 -9
!
(( $? == 0 )) &&
cat<<!>$uml/etc/rc.d/rc.2
#!/bin/sh
# /etc/rc.d/rc.2
#Initializing eth0.
#/sbin/ifconfig eth0 192.168.0.250 broadcast 192.168.0.255 netmask 255.255.255.0

#Starting inetd server.
[ -f /etc/inetd.conf ] && /usr/sbin/inetd

#Starting NFS server.
[ -x /usr/sbin/rpc.portmap ] && /usr/sbin/rpc.portmap

#Mount other filesystems
/bin/mount -a &
# end of /etc/rc.d/rc.1
!
(( $? == 0 )) &&
cd $uml/etc/rc.d &&
ln -s rc.2 rc.3 &&
ln -s rc.2 rc.4 &&
ln -s rc.2 rc.5 &&
ln -s rc.0 rc.6 &&
cat<<!>$uml/etc/rc.d/rc.sysinit
#!/bin/sh
# begin of /etc/rc.d/rc.sysinit

#Mounting root device ro.
/bin/mount -n -o remount,ro /

#Mounting swap partitions.
#/sbin/swapon -a

#Remounting root device rw.
/bin/mount -n -v -o remount,rw /

echo "" > /etc/mtab
/bin/mount -f -o remount,rw /

#Mount special filesystems
/bin/mount /proc
/bin/mount /dev/pts

#Initializing loopback network interface.
/sbin/ifconfig lo 127.0.0.1
/sbin/route add -net 127.0.0.0 netmask 255.0.0.0 lo

#Setting hostname.
/bin/hostname uml

#Recreate the utmp file so w/who is correct.
rm -f /var/run/utmp &&
touch /var/run/utmp &&
chmod 0644 /var/run/utmp

#Loading kernel modules.
#depmod|grep ethertap || insmod ethertap

#Setup eth0
#/sbin/ifconfig eth0 192.168.0.250
# end of /etc/rc.d/rc.sysinit
!
(( $? == 0 )) &&
cd $uml/etc/rc.d &&
chmod 754 rc.[0-2] &&
chmod 754 rc.sysinit &&
cd $uml_src/linux &&
make $silent_make modules_install INSTALL_MOD_PATH=$uml ARCH=um &&
cd / &&
umount $uml &&
losetup -d $loop &&
echo "change user=$user at the top of $0 to whatever your login name is" &&
chown $user:root $uml_src/linux/root_fs &&
modprobe ethertap || insmod ethertap 
cd $uml_src/linux &&
# use the line to try networking.
su - $user -c "cd $uml_src/linux&&./linux rootfs=root_fs eth0=ethertap,tap0,,$uml_ip_address"

# use the line below for no networking, and no init.
#su - $user -c "cd $uml_src/linux&&./linux rootfs=root_fs init=/bin/bash"
# end of root_fs setup

Comments on commands to build root_fs
=========================================
Create a 100 megabyte sparse file called root_fs and associate it
with /dev/loop0.  Copy devices, lib, sbin, bin, and a few things
from /etc into the loopback root filesystem.  Build bsd style init
scripts (thanks saai).  

Switch back to a non-priveledged user and run the kernel:
./linux init=/bin/bash
or
./linux rootfs=root_fs eth0=ethertap,tap0,,$uml_ip_address

You will be root in the uml environment.  Take a look around.
When you are done, type /sbin/halt to (hopefully) kill uml.
(you may need to kill some "linux" processes from uml if
halt doesn't do the job.  Did you try the kuml alias?
Have you fixed it so it actually works?

Now that you can boot, you'll probably want to get the real
init and initscripts working.  Definitely check out the 
uml web site.  There's a lot more you can do, and the
HOWTO at the site is improving.

Using mconsole
==============
You have to compile uml_mconsole.  You can use uml_mconsole
to "manage" the uml system.  The "management" device is 
printed in the boot message, and it changes from boot to boot.

	uml_mconsole /tmp/uml/IS8HfR/mconsole
	(mconsole) version
	OK Linux (none) 2.4.7-2um #1 Thu Aug 2 22:19:09 EDT 2001 i686
	(mconsole) halt
	OK
	(mconsole) quit


Taking down uml
===============
sync		# halt in mconsole doesn't sync the filesystem.
/sbin/halt	# from within uml (this isn't working yet)
kuml		# alias mentioned earlier if uml processes are still out there.

Taking down loopback filesystem if something went wrong
=======================================================
umount /mnt/uml
losetup -d /dev/loop0

Troubleshooting
===============
o If your X terminal goes haywire, after killing uml, try "clear;reset;clear".
o Kernel panic when you have a root_fs.  If you run uml as non-root, the 
  user running uml must own root_fs.  chown the root_fs file, (not everything 
  inside root_fs).
o Error building kernel:
  gcc -Wl,-T,/usr/src/uml/linux/arch/um/link.ld  -o linux -static \
        /usr/src/uml/linux/arch/um/main.o vmlinux.o -L/usr/lib
	vmlinux.o: In function `linux_main':
	/usr/src/uml/linux/arch/um/kernel/um_arch.c:211: undefined reference
	to `remap_profiling_buffers'
	collect2: ld returned 1 exit status
	make: *** [linux] Error 1
  Somehow CONFIG_GPROF in .config is defined to 1.  make mrproper and try building
  the kernel again.  Read the script, there's a hack in there for this.

Other helpful docs
==================
HOWTO: Loopback Encrypted Filesystem HOWTO
HOWTO: The Linux Bootdisk HOWTO

Resources
=========
irc.openprojects.org #kernelnewbies and #uml

Help save the world
===================
If you have suggestions, or want clarification, please send comments so we 
can make this hint more helpful.

Wed Aug 29 00:24:24 EDT 2001
hrandoz


More information about the hints mailing list