The reasoning is simple:
- If you have 32-bit chroot environment with a compiler, you can just compile the 32-bit kernel there in the usual fashion.
- If you have the right cross-compiler, you can use the standard kernel cross-compilation procedure.
But if you're on x86_64, you can install the multilib version of gcc that adds support for building 32-bit binaries with a simple "-m32" option.
Then I found this hint:
$ (echo ‘#! /bin/sh’; echo ‘exec gcc -m32 “$@”‘) >~/bin/i486-linux-gnu-gcc
$ chmod +x ~/bin/i486-linux-gnu-gcc
$ for i in ar ld nm objcopy strip; do
$ ln -s `which $i` ~/bin/i486-linux-gnu-$i
This basically creates a "fake" i486-linux-gnu cross-toolchain out of the multilib x86_64/x86 toolchain. Then it can be used with kernel Makefile like this:
make ARCH=i386 CROSS_COMPILE=i486-linux-gnu- <target>
That's a way I've been using for some time. But as I was preparing this post, I fired up google once again and discovered this very brief answer:
make CROSS-COMPILE=i686-pc-linux-gnu- ARCH=i386 <target>
And that command works despite me having neither real nor "fake" i686-pc-linux-gnu- cross-toolchain installed. Experimenting further reveals that all that is needed is:
make ARCH=i386 <target>
Just don't forget you need to keep that ARCH=i386 parameter throughout the make invocations (modules_install doesn't seem to need them), e.g.:
make ARCH=i386 menuconfig
make ARCH=i386 bzImage modules
In this case of building the kernel on a different machine than the one it's supposed to run on, you certainly don't want to install the built modules into /lib/modules, so invoke the make like this:
make INSTALL_MOD_PATH=prefix modules_install
Also, don't do any of the steps as root. -- There's no need to. If you build the kernel as root, you risk accidentally overwriting your host modules or causing some other damage.