chrootedI have an old game, Civilization Call to Power, that did not run on my current system. As the distributor of the Linux version, Loki Entertainment Software, no longer exists, I could get no support from there. Luckily they packaged a SuSE 6.1 Evaluation Version CD with the game. That is the software from the era (mid 1999), so I supposed that should work.
But I did not feel like dedicating a partition to SuSE and rebooting just to play this game. I don't suppose the old Kernel could cope with my SATA drive anyway. So I tried to get SuSE installed into a directory of my system and to run programs chrooted in this directory. Here is a summary of the tricks that got me there. I cannot guarantee completeness, but I'll try my best.
First you need to get the Environment SuSE ist using for the
installation. You find it in the directory suse/inst-sys/
of the CD-ROM. Copy this whole directory to your hard drive.
I could only get the installation process to do the initial installation on a block device. Of course I don't want to use a real partition; instead I'm using a loop device.
First create a file that will receive the installation file
system. I created a 256MiB file using this command: dd
if=/dev/zero of=loopdev bs=64k count=4096.
Then you can associate the loop device with this file using
losetup /dev/loop0 loopdev. Now /dev/loop
behaves almost like a normal partition, but the data is actuallay
stored in the file loopdev.
You can now create an Ext2 file system on this device: mke2fs
/dev/loop0.
The SuSE setup tool YaST tries to be clever and would not let you
specify a target device for the installation. Instead it asks
fdisk -l to display a list of partitions and parses this
result.
The simplest way to avoid this is by replacing the
fdisk command of the installation environment with a
simple script that outputs a hard coded result. The command called by
YaST is stored in a directory of its own, its path is
inst-sys/usr/lib/YaST/fdisk.
I derived the geometry of the loop device from fdisk -l
/dev/loop0, the format of a partition list from fdisk
-l and the size of the loop device in blocks from
/proc/partitions. The result was included in my
replacement for inst-sys/usr/lib/YaST/fdisk. Remember to
set execute permission on this file once you have created it.
#!/usr/sh if [ "$*" = "-l" ]; then echo "" echo "Disk /dev/hda: 67 MB, 67108864 bytes" echo "255 heads, 63 sectors/track, 8 cylinders" echo "Units = cylinders of 16065 * 512 = 8225280 bytes" echo "" echo " Device Boot Start End Blocks Id System" echo "/dev/hda1 * 1 8 65536 83 Linux" else exec /sbin/fdisk "$@" fi
Next you need to make the setup environment to look real
enough. You mount the proc file system there as well: mount
--bind /proc $PWD/inst-sys/proc.
You have to populate the dev directory as
well. copy -RLp /dev/null /dev/zero /dev/tty
inst-sys/dev/. As you can see in the fake partition list above,
I decided to have my partition named hda1. So I rename
the loop device: copy -RLp /dev/loop0
inst-sys/dev/hda1.
To access the instalation CD in the chrooted environment, you
should probably mount it before you start installation, by issuing
mount /dev/cdrom $PWD/inst-sys/cdrom.
By issuing chroot inst-sys YaST, you can start the
installation. You should probably do this from a text console, as I
had trouble using F4 to set a mount point in xterm.
The installation is straightforward. As your instalation medium you
select a reachable directory, namely /cdrom. Choose not
to repartition any drives, set the mount point of the only listed
partition /dev/hda1 to /. You can choose
very few packages for now, as you can always add more later on when
you are out of the loop device and in a native directory of your host
system. You can save a lot of space by dispensing with the kernel
sources. Don't build any boot disks, as you won't have to boot this
system.
Once installation is complete, you can unmount your auxiliary
mounts: umount $PWD/inst-sys/cdrom and umount
$PWD/inst-sys/proc.
Mount the loop device to some available mount point in your system:
mount /dev/loop0 $PWD/inst-sys/mnt. Now you can copy the
installed system out of this device: cp -pR inst-sys/mnt
SuSE. Then you won't need the loop device any longer, you can
unmount it using umount /dev/loop0 and disassociate the
loop device using losetup -d /dev/loop0. You can even
remove the backing file and installation environment: rm -r
loopdev inst-sys.
To have your device permissions only in one place, it is probably a
good idea to remove the dev directory of the installed
system. rm -r SuSE/dev
To use this system, you should first mount --bind /proc
$PWD/SuSE/proc and mount --bind /dev
$PWD/SuSE/dev. Then you can Enter your new system using
chroot SuSE bash --login or something similar. If you
want to drop root privileges in the chroot, you first should make sure
that appropriate users exist there, by examining
SuSE/etc/passwd and SuSE/etc/group. Then you
can use su - UserName to temporarily drop root
privileges.
If you want to access an X11 server running outside the chroot, you
have to take care of three things. The first is authentication
information. This is stored in the file .Xauthority in
the home directory of the user. Copy this file to the matching home
directory inside the SuSE directory, but take care of
file permissions and ownership.
The other thing is the unix domain socket used to communicate with
the server. Usually for your primary display this is
/tmp/.X11-unix/X0. You can create an empty file inside
the chroot and then bind it using mount --bind /tmp/.X11-unix/X0
SuSE/tmp/.X11-unix/X0. To connect you have to make sure that
the DISPLAY environment variable inside the chroot is the
same as outside, usually DISPLAY=:0.0.
Using this installation, I was able to run the game and have a look at the atimes of the system libraries. In this way I identified which libraries are used by the game, and could provide a rather convenient description on how to fix the original problem.