Compile 32bit kernel on 64bit machine

I'm trying to compile a kernel for a 32bit single-core Intel Atom machine. Needless to say, the compile is taking inordinate amounts of time. It's been going for 2 hours and it's still only halfway through the driver modules.

Compiling a kernel on my main desktop only takes 15 minutes but it's a 64bit machine. Can I cross compile to generate a 32bit kernel package from the better machine?


While the kernel can be cross-compiled, the easiest way is to create a 32bit (i386) chroot and build it in there.

Install ubuntu-dev-tools:

$ sudo apt-get install ubuntu-dev-tools

Create an i386 chroot:

$ mk-sbuild --arch=i386 precise

(You will probably have to run that twice. The first time, it installs schroot etc. and sets up mk-sbuild)

Then enter the chroot:

$ schroot -c precise-i386

And build the kernel, as you would, normally.


Afaik, in gcc, you can set -m32 flag to let it compile linux sources to 32bit executables. I don't have a wide knowledge about Makefiles, but you can tweak them.

edit: I wanted to add a question from stackoverflow here, in which it is told to set cflags:

export CFLAGS=-m32

And from the linux repository in Torvalds' github account, I found following section on the main makefile that you may find useful, as it tells that you can set a target architecture by setting an environment variable. Read the comments, currently, these lines are from this file, between lines 174-196:

# Cross compiling and selecting different set of gcc/bin-utils
# ---------------------------------------------------------------------------
#
# When performing cross compilation for other architectures ARCH shall be set
# to the target architecture. (See arch/* for the possibilities).
# ARCH can be set during invocation of make:
# make ARCH=ia64
# Another way is to have ARCH set in the environment.
# The default ARCH is the host where make is executed.

# CROSS_COMPILE specify the prefix used for all executables used
# during compilation. Only gcc and related bin-utils executables
# are prefixed with $(CROSS_COMPILE).
# CROSS_COMPILE can be set on the command line
# make CROSS_COMPILE=ia64-linux-
# Alternatively CROSS_COMPILE can be set in the environment.
# A third alternative is to store a setting in .config so that plain
# "make" in the configured kernel build directory always uses that.
# Default value for CROSS_COMPILE is not to prefix executables
# Note: Some architectures assign CROSS_COMPILE in their arch/*/Makefile
export KBUILD_BUILDHOST := $(SUBARCH)
ARCH        ?= $(SUBARCH)
CROSS_COMPILE   ?= $(CONFIG_CROSS_COMPILE:"%"=%)

# ...
# There are more architecture related stuff beyond this line