I have a Gentoo amd64 no-multilib configuration and sometimes I really need to run 32-bit application (Skype or Android SDK that are available only for 32bit environment).
For these I have prepared a 32-bit chroot-ed environment as specified in 32Bit Chroot Guide for Gentoo/AMD64.
Inside the 32-bit chroot environment I want to use the XServer with Xfce desktop environment. To make sure I will have a basic Xfce environment as I already have in the amd64 environment, I just copied the /etc/make.conf file to /mnt/gentoo32/etc/make.conf and I have adjust few options (tunned for my 32-bit virtual environment)
Gentoo 32-bit chroot environment on amd64 no-multilib
# These settings were set by the catalyst build script that automatically # built this stage. # Please consult /usr/share/portage/config/make.conf.example for a more # detailed example. # compiler optimization CFLAGS="-O2 -pipe -march=native -mtune=native -fomit-frame-pointer -fno-var-tracking" CXXFLAGS="${CFLAGS}" LDFLAGS="-Wl,-O1 -Wl,--as-needed" # parallel build " gcc cache MAKEOPTS="-j2" CCACHE_DIR="/var/tmp/ccache" CCACHE_SIZE="1G" FEATURES="parallel-fetch userfetch ccache candy compress-build-logs" # WARNING: Changing your CHOST is not something that should be done lightly. # Please consult http://www.gentoo.org/doc/en/change-chost.xml before changing. CHOST="i686-pc-linux-gnu" ACCEPT_KEYWORDS="x86" LINGUAS="en" # use the following gentoo repository servers: GENTOO_MIRRORS="http://mirror.mdfnet.se/gentoo" SYNC="rsync://rsync.se.gentoo.org/gentoo-portage" # by default we acknowledge the have the following devices INPUT_DEVICES="keyboard mouse evdev synaptics" VIDEO_CARDS="radeon vesa fbdev" ALSA_CARDS="ens1370" WEB_CAM="v4l v4l2" APACHE2_MODULES="*-" CAMERAS="*-" CALLIGRA_FEATURES="*-" GPSD_PROTOCOLS="*-" LCD_DEVICES="*-" # do not unmask automatically anything but accept any 3rd party license agreement EMERGE_DEFAULT_OPTS="--autounmask=n" ACCEPT_LICENSE="*" # These are the USE flags that were used in addition to what is provided by the # profile used for building. # See: http://www.gentoo.org/dyn/use-index.xml USE_OPTIMIZATION="optimization strong-optimization mmx pch sharedmem smp sse sse2 lto graphite optimized-qmake" USE_SYS_KERNEL="savedconfig" USE_SYS_LIBS="glibc-omitfp python" USE_LAPTOP="acpi" # bluetooth" USE_X="truetype X new-login xorg" USE_IMAGE="jpeg gif tiff png svg pdf" USE_MEDIA="sound alsa mad vidix asf win32codecs dvd mp4 aac x264 xvid nsplugin mp3 real gstreamer" USE_GENERAL="udev ncurses bash-completion libnotify ftp samba java bzip2 symlink sqlite threadsafe spell xml lm_sensors" USE_SYSTEM="hal fam dbus aoss nptl threads" USE_DONT="-arts -qt4 -ipv6 -opengl" USE_KDE="-kde -qt3" #USE_GNOME="gtk cairo gnome gnome-keyring archive sendto aisleriot" USE_GNOME="-gnome -gnome-keyring" USE_LXDE="-lxde cairo" USE_XFACE="session startup-notification" USE_APP_ADMIN="edit sudo custom-optimization" USE_APP_EMULATION="consolekit" USE_WWW_PLUGINS="32bit" USE_X11_TERMS="mousewheel" USE_X11_DUALMONITOR="-xinerama" USE_X_COMPOSITE="xcomposite" USE="${USE_DONT} ${USE_SYSTEM} ${USE_GENERAL} ${USE_IMAGE} ${USE_X} ${USE_KDE} ${USE_MEDIA} ${USE_OPTIMIZATION} ${USE_APP_ADMIN} ${USE_APP_EMULATION} ${USE_GNOME}" USE="${USE} ${USE_SYS_KERNEL} ${USE_SYS_LIBS} ${USE_WWW_PLUGINS} ${USE_X11_DRIVERS} ${USE_X11_TERMS} ${USE_LXDE} ${USE_XFACE} ${USE_X11_DUALMONITOR} ${USE_X_COMPOSITE} ${USE_KVM} ${WEB_CAM} ${USE_LAPTOP}"
Also, I have configured the /mnt/gentoo32/etc/portage/package.use and /mnt/gentoo32/etc/portage/package.keywords configuration files with those options necessary to build my 32-bit environment:
package.use
x11-base/xorg-server udev sys-auth/consolekit policykit sys-apps/hal policykit dev-libs/libxml2 python sys-fs/udev extras app-crypt/pinentry gtk gnome-base/gvfs gdu media-libs/libpng apng app-emulation/wine custom-cflags
package.keywords
>=net-im/skype-2.2.0.35-r1 app-emulation/winetricks **
In the virtual 32-bit environment I have installed just those applications I will really need, such as:
- app-admin/sudo
- app-editors/nano
- app-emulation/wine
- app-emulation/winetricks
- app-portage/gentoolkit
- dev-util/ccache
- net-im/skype
- gnome-extra/zenity
- x11-base/xorg-drivers
- x11-base/xorg-server
- x11-terms/terminal
- xfce-base/thunar
- xfce-base/xfce4-meta
- xfce-extra/thunar-archive-plugin
- xfce-extra/thunar-volman
- xfce-extra/tumbler
For building the above 32-bit application within the chroot-ed environment just chroot inside the 32-bit environment (eg: sudo linux32 chroot /mnt/gentoo32/ /bin/bash) and run (as root) the command below:
emerge -DuN world
After several minutes/hours (this depends on your hardware) you should have a 32-bit environment with everythig that is need it for running a XServer with Xfce desktop environment.
Inside the chroot-ed environment create the following file in the home directory of
.bashrc
# /etc/skel/.bashrc # # This file is sourced by all *interactive* bash shells on startup, # including some apparently interactive shells such as scp and rcp # that can't tolerate any output. So make sure this doesn't display # anything or bad things will happen ! # Test for an interactive shell. There is no need to set anything # past this point for scp and rcp, and it's important to refrain from # outputting anything in those cases. if [[ $- != *i* ]] ; then # Shell is non-interactive. Be done now! return fi # Put your fun stuff here. # if X is not started already then start your favorite X session # otherwise just run the normal terminal (within the chroot-ed X session) if [ -z $DISPLAY ];then startxfce4 -- :1 exit fi
Inside the chroot-ed environment create a file named 90xsession in the /etc/env.d/ folder:
XSESSION="Xfce4"
Now, if you issue the X command at the console within the chroot-ed environment, it should start the XServer and launch the Xfce desktop environment for you. When you logoff from the Xfce session it should return to the console within the chroot-ed environment.
Let's automate little bit the way we get into the chroot environment and how we launch the Xfce session on that environment!
Instead of mounting/unmounting the virtual filesystem (as described in step 2.c) I have created a bash script which will help me to:
- automatically mount the necessary folders/devices for my chroot environment virtual file system
- copy the necessary configuration files into the chroot-ed environment (eg: resolv.conf, hosts, passwd)
- enter to 32-bit chroot-ed environment and login as prefered user
- start Xfce session (or whatever program from the chrooted environment) in the chroot-ed environment on display 1 (or even on the display 0), so both sessions - the amd64 default Xfce session and the newly created chroot-ed 32bit Xfce session - are available simultaneously (switch between them with Ctrl+Alt+Fn, where n could be 7,8,...); if you started just a program on current display (eg: display 0) then no switch available/need it
- exit cleanly from chroot-ed environment and umount previously mounted folders for the virtual file system
So just launching the bash script it will create automatically for you the chroot environment and will start a new X session on another virtual display (eg: display 1). You can, as explained above, work on both sessions, but you have to switch between them with Ctrl+Alt+Fn keys.
First create a bash script called gentoo32 as bellow:
#!/bin/bash ###################################################################### # # Title : Linux x86 chroot bootstrap # # Author: Eugen Mihailescu# Created date: 2011, November # Last modified 2012-09-06 # # Generic bash script to chroot into a x86 Linux environment # (e.g. from a x86_64 Linux environment), to mount some custom mount # points then to launch a command (e.g start a Xfce4 session in # display #2). On exist it clears all the way back, clean & smooth. # # Note: all options are described in print_syntax() function bellow. ###################################################################### # Path where the chroot environment is installed CHROOT_ENV_PATH="/mnt/gentoo32" # Print the script help syntax function print_syntax() { echo -e "Usage : $0 [OPTION]...\nLogin to a chrooted environment as then imediately run the command on the specified display.\n" echo -e "Mandatory arguments to long options are mandatory for short options too.\n" echo -e " -s, --service \tmount|unmount necessary folders and start|stop chroot-ed environment" echo -e " -c, --command \trun the command immediately after loging in the chroot-ed environment" echo -e " -d, --display \tthe virtual terminal used to display the command" echo -e " -u, --user \tthe user used to login in the chroot-ed environment\n" echo "Report bugs to " } SHORTOPTS="s: c: d: u:" LONGOPTS="service: command: display: user:" set -- `getopt -a -u --options="$SHORTOPTS" --longoptions="$LONGOPTS" --name="$0" -- "$@"` || print_syntax # Check for sufficent args if [ $# -lt 2 ] ; then print_syntax exit 1 fi # Read the options/arguments from command-line while [ $# -gt 0 ];do case $1 in -s|--service) SERVICE=$2;shift;; -c|--command) COMMAND=$2;shift;; -d|--display) VT=$2;shift;; -u|--user) CHROOT_USR=$2;shift;; \?) echo "Invalid option: -$1"; print_syntax; exit 1; ;; :) echo "Option -$1 requires an argument."; print_syntax; exit 1; ;; -h) print_syntax;; --) shift;break;; -*) print_syntax;; *) break;; esac shift done if [ "${CHROOT_USR}" == "" ];then CHROOT_USR="`whoami`" fi kernel_version=`uname -r` # Set terminal title # @param string $1 Tab/window title # @param string $2 (optional) Separate window title # The latest version of this function can be obtained here: # http://fvue.nl/wiki/NameTerminal function nameTerminal() { [ "${TERM:0:5}" = "xterm" ] && local ansiNrTab=0 [ "$TERM" = "rxvt" ] && local ansiNrTab=61 [ "$TERM" = "konsole" ] && local ansiNrTab=30 ansiNrWindow=0 # Change tab title [ $ansiNrTab ] && echo -n $'\e'"]$ansiNrTab;$1"$'\a' # If terminal support separate window title, change window title as well [ $ansiNrWindow -a "$2" ] && echo -n $'\e'"]$ansiNrWindow;$2"$'\a' } # Terminal title nameTerminal "32bit chroot enviroment" # Create a .bashrc file on the home directory of chrooted user ${CHROOT_USR} # This .bashrc file is prepared to run the command on display function prepare_bashrc(){ # Replace and " in with a space respectively with double quote # Note: you can specify in your instead of ASCII, # the script will convert it to ASCII space at runtime startup_app=$(echo $1|awk '{p=gsub(/ /, " ");gsub(/"/, "\""); print}') display=$2 bashrc_path="${CHROOT_ENV_PATH}/home/${CHROOT_USR}/.bashrc" echo "#Automatically created by $0" > ${bashrc_path} echo "export PS1=\"(\`uname -m\`) \$PS1\"" >> ${bashrc_path} echo "if [[ \$- != *i* ]] ; then" >> ${bashrc_path} echo " return" >> ${bashrc_path} echo "fi" >> ${bashrc_path} echo "if [ -z \$DISPLAY ];then" >> ${bashrc_path} if [ "${display}" != "" ];then echo " export DISPLAY=":${display}"" >> ${bashrc_path} fi echo " ${startup_app}" >> ${bashrc_path} echo " exit" >> ${bashrc_path} echo "fi" >> ${bashrc_path} chown ${CHROOT_USR}:${CHROOT_USR} ${bashrc_path} } start() { echo -e "\E[1;31m[1] Mounting chroot dirs...\033[0m" # MANDATORY : mount the volume where gentoo32 is installed is_mounted=$(mount|grep -i ${CHROOT_ENV_PATH}/proc) if [ "$is_mounted" == "" ];then mount /dev/vg/lvgentoo32 ${CHROOT_ENV_PATH} else echo "${CHROOT_ENV_PATH} already mounted. Carry on..." fi if [ "$is_mounted" == "" ];then # MANDATORY : bind the local system folders to the corresponding folders inside the chrooted environment mount -o bind /proc ${CHROOT_ENV_PATH}/proc mount -o bind /sys ${CHROOT_ENV_PATH}/sys mount -o bind /tmp ${CHROOT_ENV_PATH}/tmp mount -o bind /dev ${CHROOT_ENV_PATH}/dev mount -o bind /dev/pts ${CHROOT_ENV_PATH}/dev/pts mount -o bind /dev/shm ${CHROOT_ENV_PATH}/dev/shm mkdir -p ${CHROOT_ENV_PATH}/lib/modules/${kernel_version} mount -o bind /lib/modules/${kernel_version}/ ${CHROOT_ENV_PATH}/lib/modules/${kernel_version}/ mount -o remount,ro ${CHROOT_ENV_PATH}/lib/modules/${kernel_version}/ mount -o bind /var/run/dbus/ ${CHROOT_ENV_PATH}/var/run/dbus mount -o remount,ro ${CHROOT_ENV_PATH}/var/run/dbus # OPTIONAL : bind the local user folders to the corresponding folders inside the chrooted environment mount -o bind /home/eugen/svn ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/svn 2>/dev/null mount -o bind /home/eugen/git/cubiquelicadmin ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/workspace/java/CubiqueLicAdmin/ 2>/dev/null mount -o bind /home/eugen/git/cubiquelicadminj ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/workspace/java/CubiqueLicAdminJ/ 2>/dev/null mount -o bind /home/eugen/git/cubiquelicadminphp ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/workspace/java/CubiqueLicAdminPHP/ 2>/dev/null mount -o bind /home/eugen/git/cubiquelicmngr ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/workspace/java/CubiqueLicMngr/ 2>/dev/null mount -o bind /home/eugen/Dev/bash.scripts ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/Dev/bash.scripts 2>/dev/null mount -o remount,ro ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/Dev/bash.scripts 2>/dev/null mount -o bind /usr/src/linux ${CHROOT_ENV_PATH}/usr/src/linux/ 2>/dev/null mount -o remount,ro ${CHROOT_ENV_PATH}/usr/src/linux/ 2>/dev/null echo -e "\E[1;32m[1] Done.\033[0m" # MANDATORY : copy the local system security files/settings to the corresponding files inside the chrooted environment echo -e "\E[1;31m[2] Copying neccessary files for chrooted environment...\033[0m" cp -pf /etc/resolv.conf ${CHROOT_ENV_PATH}/etc 2>/dev/null cp -pf /etc/passwd ${CHROOT_ENV_PATH}/etc 2>/dev/null cp -pf /etc/shadow ${CHROOT_ENV_PATH}/etc 2>/dev/null cp -pf /etc/group ${CHROOT_ENV_PATH}/etc 2>/dev/null cp -pf /etc/gshadow ${CHROOT_ENV_PATH}/etc 2>/dev/null cp -pf /etc/hosts ${CHROOT_ENV_PATH}/etc 2>/dev/null cp -Ppf /etc/localtime ${CHROOT_ENV_PATH}/etc 2>/dev/null echo -e "\E[1;32m[2] Done.\033[0m" fi } # Function for unmounting the stop() { multiple_chroot="`who|grep \"(:0.0)\"|awk '{print $NF}'`" if [ "$is_mounted" = "" ];then # if the volume was mounted by other parallel chroot session then don't touch the mount points echo -e "\E[1;31m[*] Unmounting chrooted dirs...\033[0m" # MANDATORY : unmount the chrooted environment system folder bindings umount -l ${CHROOT_ENV_PATH}/dev/{pts,shm} umount -l ${CHROOT_ENV_PATH}/{dev,proc,sys,tmp} umount -l ${CHROOT_ENV_PATH}/lib/modules/${kernel_version}/ umount -l ${CHROOT_ENV_PATH}/var/run/dbus # OPTIONAL : unmount the chrooted environment user folder bindings umount -l ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/workspace/java/{CubiqueLicAdmin,CubiqueLicAdminJ,CubiqueLicAdminPHP,CubiqueLicMngr} umount -l ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/Dev/bash.scripts umount -l ${CHROOT_ENV_PATH}/home/${CHROOT_USR}/svn umount -l ${CHROOT_ENV_PATH}/usr/src/linux umount -l ${CHROOT_ENV_PATH} echo -e "\E[1;32m[*] Done.\033[0m" fi } # Switch to root profile if running as normal user if [ "$(whoami)" != "root" ]; then echo -e "\E[1;34m" params="" if [ "${SERVICE}" != "" ];then params+=" -s ${SERVICE}" fi if [ "${COMMAND}" != "" ];then params+=" -c ${COMMAND}" fi if [ "${VT}" != "" ];then params+=" -d ${VT}" fi if [ "${CHROOT_USR}" != "" ];then params+=" -u ${CHROOT_USR}" fi sudo -p "Enter root password for entering into chrooted environment : " -u root $0 ${params} echo -e "\033[0m" err=$? exit $err else ${SERVICE} err=0 fi # Run the chrooted environment, login to it as then run the on display if [ "$err" == "0" ];then if [ "$SERVICE" == "start" ];then echo -e "\E[1;31m[3] Entering to chroot environment...\033[0m" prepare_bashrc "${COMMAND}" "${VT}" linux32 chroot ${CHROOT_ENV_PATH} /bin/bash -c "echo -e 'Login as \E[1;35m${CHROOT_USR}\033[0m within \E[1;34mchroot-ed\033[0m environment...' && login ${CHROOT_USR}" echo -e "\E[1;32m[4] Exited from chroot environment.\033[0m" stop fi fi
Note: in the above script (1) should be your linux folder where you have installed the chrooted environment.
When you will run the above script it will ask you for root password (mount requires root authentification), will open automatically the 32-bit chroot-ed environment, will ask you the password for the
Usage : /usr/sbin/gentoo32 [OPTION]... Login to a chrooted environment asthen imediately run the command on the specified display. Mandatory arguments to long options are mandatory for short options too. -s, --service mount|unmount necessary folders and start|stop chroot-ed environment -c, --command run the command immediately after loging in the chroot-ed environment -d, --display the virtual terminal used to display the command -u, --user the user used to login in the chroot-ed environment Report bugs to
Examples:
- launch Xfce session in the chrooted environment:
gentoo32 --service=start --command="startxfce4"--":1" --user=myname
- launch Eclipse application without starting a separate 32-bit Xfce session, on the same display (eg: display 0) as the main Xfce 64-bit session:
gentoo32 --service=start --command="eclipse" -d 0 --user=myname
- launch Skype application without starting a separate 32-bit Xfce session, on the same display (eg: display 0) as the main Xfce 64-bit session:
gentoo32 --service=start --command="skype" -d 0 --user=myname
Now, if you think that this article was interesting don't forget to rate it. It shows me that you care and thus I will continue write about these things.
Eugen Mihailescu
Latest posts by Eugen Mihailescu (see all)
- Dual monitor setup in Xfce - January 9, 2019
- Gentoo AMD Ryzen stabilizator - April 29, 2018
- Symfony Compile Error Failed opening required Proxies - January 22, 2018