With the arrival of systems supporting AMD's new architecture AMD64, comes a transition period where several applications developed to Intel's IA-32 architecture are not still ported to AMD64. Thus, many times it is not possible to have a 100% pure AMD64 system, due to the need to run this legacy IA-32 applications, such as Flash, Skype or Opera.
In this scenario, it is possible to configure a system containing two full installations, one for each architecture, almost transparent to end user. This way, we are able to enjoy simultaneously the advantages of AMD's architecture and still being able to run the whole bunch of applications that are IA-32 only.
It is important to note that this article is focused on Debian systems, however the concepts here presented are applicable to any Linux distribution.
A full working AMD64 system must be installed on the computer. This system must have a kernel able to execute binaries to both architectures (Debian distributed kernels are capable). Just proceed the installation as you would usually do.
Once you have the AMD64 system working, the IA-32 system must be installed in an arbitrary directory. This can be done from within the running AMD64 system, with the help of an utility called debootstrap. This utility will execute a process similar to the one that happens when you install a Debian system from a CD for example, but there is no need to reboot or record a CD.
# mkdir /ia32 # debootstrap --arch i386 --verbose etch /ia32 http://ftp.br.debian.org/debian
In the example, a whole IA-32 Debian Etch system will be installed under /ia32. This directory will be the root for the new system, despite the fact that it is not AMD64's system root (/). For example, /etc belongs to the AMD64 system and /ia32/etc belongs to the IA-32 system.
Access to the IA-32 system will be granted via chroot (explanation to follow).
Networking configuration must be shared by both systems. To make it so, some files from inside the chroot (IA-32) must be overwritten by symbolic links to the root (AMD64) system, as the table below:r:
| File | Symbolic Link |
|---|---|
/ia32/etc/hostname | ../amd64/etc/hostname |
/ia32/etc/hosts | ../amd64/etc/hosts |
/ia32/etc/hosts.allow | ../amd64/etc/hosts.allow |
/ia32/etc/hosts.deny | ../amd64/etc/hosts.deny |
/ia32/etc/resolv.conf | ../amd64/etc/resolv.conf |
/ia32/etc/networks | ../amd64/etc/networks |
Example:
# ln -sf ../amd64/etc/hostname /ia32/etc/hostname
Will make /ia32/etc/hostname a symbolic link to ../amd64/etc/hostname. Do not worry about the /ia32/amd64, we will cover that below.
It is important that the users and groups database to be exactly the same among both systems. A simple (not perfect) way to achieve that, is to substitute database files from within the chroot by symbolic links to the root system (such as the above network configuration), as shown by the table below:
| File | Symbolic Link |
|---|---|
/ia32/etc/passwd | ../amd64/etc/passwd |
/ia32/etc/shadow | ../amd64/etc/shadow |
/ia32/etc/group | ../amd64/etc/group |
/ia32/etc/gshadow | ../amd64/etc/gshadow |
Example:
# ln -sf ../amd64/etc/passwd /ia32/etc/passwd
This will make /ia32/etc/passwd a symbolic link to ../amd64/etc/passwd (/amd64 will be covered below).
WARNING: SOME UTILITIES SUCH AS passwd(1) or adduser(8) THAT MANIPULATE THE ABOVE FILES ARE NOT PREPARED TO DEAL WITH SYMBOLIC LINKS. BE SURE THAT AFTER ANY ALTERATION OF ONE OF THE ABOVE FILES FROM WITHIN THE CHROOT (IA-32) SYSTEM, THEY REMAIN SYMBOLIC LINKS AND IF NOT, MANUALLY SYNCHRONIZE BOTH FILES AND RECREATE THE SYMBOLIC LINK.
A better solution would be to use some database backend such as NIS, configuring the AMD64 as master, and IA-32 as slave, to 100% of the database.
An explanation on how to do this is (or a better solution) is appreciated.
[random]> couldn't you just use a hardlink?
You may use
ln -sf ../amd64/lib/modules/ /lib/modules
to get access to the modules of the amd64 kernel. For example the CUPS-Server needs access to this directory to automatically load the modules for accessing the printer ports. – Thomas Bayen
To ensure transparency on the operation inside and outside the chroot, some paths on the AMD64 system must be remounted1) inside the IA-32 chroot. It will be also necessary to start up some services inside the IA-32 system.
To achieve this, one can create two files on the initialization of the AMD64 system, responsible for starting up some IA-32 services.
The first file, must be created at /etc/init.d/ia32S.sh (belonging to root, permission 755) with the following content:
#!/bin/bash
IA32_PATH="/ia32"
IA32_SERVICES="screen-cleanup xfree86-common sudo"
case "$1" in
start)
echo -n "Mounting IA-32 filesystems "
for p in /dev /home /proc /root /sys /tmp /var/mail /var/tmp ; do
mount -n -o rbind "$p" "$IA32_PATH""$p"
done
if [ ! -e "$IA32_PATH"/amd64 ] ; then
mkdir "$IA32_PATH"/amd64
fi
mount -n -o rbind / "$IA32_PATH"/amd64
echo OK
echo "Starting IA-32 services..."
for SERVICE in $IA32_SERVICES ; do
dchroot -q -c ia32 "/etc/init.d/$SERVICE start"
done
echo "Finished starting IA-32 services."
;;
*)
echo "Error: Wrong usage." 1>&2
exit 1
;;
esac
And added to AMD64 system initialization:
# update-rc.d ia32S.sh start 99 S .
This script will:
/ at /ia32/amd64).IA32_SERVICES).
The remounted directories make sure that some virtual filesystems (such as procfs and sysfs) exists inside IA-32 system, home directories are the same inside and outside the chroot, temporary directories are shared (specially /tmp to allow X11 applications to access always the same UNIX Sockets) and users to access always the same mail box.
The services initialized (IA32_SERVICES) depends on what is installed inside the chroot. The ones on the example above are only for reference. You must look at /ia32/rcS.d and see which ones applies to your system. Some that must not be executed are: mountvirtfs, bootlogd, keymap.sh, checkroot.sh, hwclockfirst.sh, ifupdown-clean, checkfs.sh, procps.sh, mountall.sh, mountvirtfs, ifupdown, hostname.sh, networking, mountnfs.sh, console-screen.sh, hwclock.sh, bootmisc.sh and urandom.
Some services must be executed inside the chroot (apart from the AMD64 system) to ensure some system parts to work. In special, cron(8) must be executed, because many log rotating tasks are done by it. To configure these services, create the file /etc/init.d/ia32.sh (on the AMD64 root system, belonging to root, permissions 755) with the following content:
#!/bin/bash
IA32_SERVICES="nullmailer atd cron"
case "$1" in
start)
echo "Starting IA-32 services..."
for SERVICE in $IA32_SERVICES ; do
dchroot -q -c ia32 "/etc/init.d/$SERVICE start"
done
echo "Finished starting IA-32 services."
;;
stop)
echo "Stopping IA-32 services..."
for SERVICE in $IA32_SERVICES ; do
dchroot -q -c ia32 "/etc/init.d/$SERVICE stop"
done
echo "Finished stopping IA-32 services..."
;;
*)
echo "Error: Wrong usage." 1>&2
exit 1
;;
esac
And add it to the initialization:
# update-rc.d ia32.sh defaults 99 1
The variable IA32_SERVICES must be configured to the services which will/must be initialized. It is recommended that the above services are always initialized (nullmailer will be discussed below).
To ensure mail delivery inside and outside the chroot, one can configure some MTA of choice on the AMD64 system (eg. Postfix) and on the IA-32 system, use nullmailer fake MTA. Then nullmailer is configured to relay messages to the smart host at address localhost (where Postfix of AMD64 system must be listening on port 25).
To do so, create the file /etc/nullmailer/remotes (owned by root, permissions 644) containing just the line:
localhost
No other file must exist at /etc/nullmailer.
Note also that the directory /var/spool/mail was remounted inside the chroot. Therefore, users can check email normally from within any system he/she wishes.
Also make sure to insert nullmailer on the initializaion.
It is interesting that both systems have their own task schedulers (insert both cron and at at initializaion). This ensures all maintenance routines are executed on both systems.
The file /etc/mtab from inside the IA-32 system (/ia32/etc/mtab from within the AMD64 system) is used to store information about mounted filesystems. You must make sure this file is correct and the only way to do it is to manually correct it to reflect all mounted filesystems seen from within the IA-32 system.
The easiest way to do that, is to configure everything until the end of this article, make a system reboot to test everything, access the chroot with dchroot, verify /proc/mounts to see what is mounted and corret /etc/mtab. To check if it worked, try the df tool.
The following line must be fixed on the AMD64 system:
PRUNEPATHS="/tmp /usr/tmp /var/tmp /afs /amd /alex /var/spool /sfs /media /ia32/dev /ia32/home /ia32/proc /ia32/amd64 /ia32/root /ia32/sys /ia32/tmp /ia32/var/mail /ia32/var/tmp"
of the file /etc/updatedb.conf to avoid recursive behavior on the database of locate.
Similarly, inside the IA-32 chroot:
PRUNEPATHS="/tmp /usr/tmp /var/tmp /afs /amd /alex /var/spool /sfs /media /amd64"
You have to install the debian package "cupsys-client" inside the chroot-jail. You have to configure it like in the amd64 system. For my System, in the file /etc/cups/client.conf I entered
ServerName printserver
(You may want to use localhost instead of printserver for a local printer setup). So every 32 Bit Application (e.g. your browser) can use all your configured printers. – ThomasBayen
Access to the IA-32 system is granted via chroot2). The command chroot(8) (common to all Linux distributions) does that, however only for root. Debian systems come with a tool called dchroot which allows system administrator to grant privileges inside certain chroots to ordinary users.
The utility is configured by the file /etc/dchroot.conf. Add a line like this:
ia32 /ia32
This will allow any user on the (AMD64) system (even not root) to access the IA-32 chroot at /ia32 with the command:
$ dchroot -d -c ia32 [command]
The command [command] will be executed inside the IA-32 chroot at /ia32. The [command] will "see" /ia32 as the actual root. For it, everything passes as if it is being executed on a full ordinary IA-32 system, without even the knowledge that another full AMD64 exists on the same machine. The absence of [command] will give a Shell inside the chroot.
Now you can install everything you wish on the AMD64 system and just those few IA-32 only applications inside the IA-32 chroot. Just make sure to be executing the command on the correct environment!
dchroot). The opposite is not valid and currently there is no solution to that. This can be specially bad if you run Iceweasel (Firefox) inside the IA-32 system and want it to launch Evince installed on the AMD64 system to open a PDF from a site for example.