wiki:Linux/Ubuntu/Kernel/CustomBuildCrossArch

Build Custom Kernel for x86 32-bit

See also Custom Build

Note: You can reverse this process and use the same instructions to build x86_64 on x86. Where something is architecture-specific swap the terms.

If you usually build for x86_64 (64-bit) you might also need to be able to cross-compile for x86 (32-bit) to ensure pointer and data size issues don't affect functionality, or to debug those issues when you suspect them.

You could do the build inside a virtual machine but that could prove to be rather slower. Recent experiments with UML (User Mode Linux) had problems with a 32-bit UML built on 64-bit. Another option is to install a full set of cross compile tools but that can get complicated.

An easier option is to install a 32-bit chroot?. Once that is installed these are the additional steps needed to be able to build an x86 kernel.

Enter the chroot and adopt your usual user account:

export $CHROOT_X86="$(pwd)/gusty_x86"
sudo chroot $CHROOT_X86
su tj
# change to the kernel source directory
cd /home/all/SourceCode/linux/linux-2.6

To use menuconfig:

sudo apt-get install ncurses-dev

To be able to use xconfig (the Qt GUI configure tool):

sudo apt-get install libqt3-mt-dev qt3-dev-tools libqt3-headers

Set the distro you're building (this is a kernel.org build) and most importantly, the architecture since it controls what kernel config options the scripts set:

export DISTRO="linux-2.6-x86"
export ARCH="x86"

Create the build directory and copy the kernel config into it, and then set the LOCALVERSION string to "-32bit":

mkdir -p ../builds/$DISTRO
# use one of the collection of kernel configs stored in the parent directory
cp ../config-standard ../builds/$DISTRO/.config
echo 'CONFIG_LOCALVERSION=-32bit' >> ../builds/$DISTRO/.config

Then build as usual (Here I'm using my automated build/install script):

~/scripts/build-custom-kernel

Once that's finished check the files are created and then exit the chroot:

ls /boot
config-2.6.25-rc9-32bit  initrd.img-2.6.25-rc9-32bit  System.map-2.6.25-rc9-32bit  vmlinuz-2.6.25-rc9-32bit

ls /lib/modules
2.6.25-rc9-32bit

# escape user log-in
exit
# escape root chroot log-in
exit

and copy the kernel image from the chroot boot directory to the real boot directory. The CONFIG_LOCALVERSION will have ensured the x86 kernel doesn't overwrite existing x86_64 images:

sudo cp $CHROOT_X86/boot/* /boot/

Copy the 32-bit modules to a 32-bit distro installation (you can't run the x86_64 binaries on the x86 kernel):

# mount the partition containing the x86 32-bit distro
sudo mount /dev/sda7 /media/x86_distro
sudo cp -a $CHROOT_X86/lib/modules/* /media/x86_distro/lib/modules/

Lastly, add a stanza to the GRUB menu.lst to boot the 32-bit kernel or let GRUB do it for you:

sudo update-grub

Important: ensure the new kernel's root is set to the correct partition because GRUB will use the default, which will likely be the 64-bit distro.