Building external modules is well documented,
but I found the info for rebuilding a single distro kernel module quite disjoint,
I guess because it spans both distribution and kernel specific info.
Now rebuilding your whole distro kernel is going to take ages due to the
number of modules enabled, so the instructions below show how to quickly
rebuild and install the minimum required. Note these instructions are based
on rpm using distros but should be easily translatable to ones using dpkg.
The specific examples below are to patch the snd_intel8x0 driver to get sound working on Fedora 11, and enabling experimental write support on the ufs module which I used to unbrick the FreeBSD based m0n0wall router in the office.
Get kernel versions and paths for automation
kernver=$(uname -r) kernbase=$(echo $kernver | sed 's/\([0-9]*\.[0-9]*\.[0-9]*\).*/\1/') rpmarch=$(rpm -q --qf="%{ARCH}\n" kernel | head -n1) rpmbase=$(rpm -q kernel | sed -n "\$s/\.$rpmarch$//p") kernextraver=$(echo $kernver | sed "s/$kernbase\(.*\)/\1/") arch=$(uname -m)
Install and prepare kernel source
Note the kernel-devel package only contains files required to build external modules against the kernel, not the full source.cd /usr/src/kernels #optional yum install yum-utils sudo yum-builddep kernel yumdownloader --source kernel-$kernver rpm -ivh $rpmbase.src.rpm rm $rpmbase.src.rpm #optional rpmbuild_base=~/rpmbuild #use /usr/src/redhat for older systems rpmbuild -bp $rpmbuild_base/SPECS/kernel.spec --target=$rpmarch kernsrc=$rpmbuild_base/BUILD/kernel-$kernbase/linux-$kernbase.$rpmarch
Rebuild a single kernel module
config preparation
cd $kernsrc #copy existing distro config cp /boot/config-$kernver .configNote if building a large module, you may want to disable debugging info by unsetting CONFIG_DEBUG_INFO in .config at this stage.
apply changes
#make config changes sed -i 's/# CONFIG_UFS_FS_WRITE is not set/CONFIG_UFS_FS_WRITE=y/' .config
#or make code changes $ patch -p1 < ~/alsa-fix.diff
build preparation
Note ignore the Module.symvers warning as that file should be present from the existing kernel buildsed -i "s/EXTRAVERSION =.*/EXTRAVERSION = $kernextraver/" Makefile make oldconfig make prepare make modules_prepare make SUBDIRS=scripts/mod
rebuild the module directory
Note I don't know how to build a particular module.ko within a dir, but no directory has too many modules, so the build should complete in a reasonable amount of time.make SUBDIRS=fs/ufs/ modules
make SUBDIRS=sound/pci modules
Install and use the new module
#don't install, just use once rmmod ufs insmod fs/ufs/ufs.ko mount -t ufs -o ufstype=44bsd /dev/sdb4 mnt_monowall
sudo install -m 744 snd-intel8x0.ko /lib/modules/$(uname -r)/kernel/sound/pci killall pulseaudio rmmod snd_intel8x0; modprobe snd_intel8x0 #relogin to start pulseaudio. Don't know how to otherwise?Note if the module is needed in early boot it will be part of the initrd which is these days in initramfs format. To update the one in /boot manually, one can do:
mkdir tmp cd tmp gzip -dc /boot/initramfs-$kernver.img | cpio -i --make-directories # copy in the new module rm -f lib/modules/$kernver/*.bin # in case not updated by current depmod depmod -b $PWD $(basename lib/modules/[23]*) find . | cpio -H newc -o | gzip > /boot/initramfs-$kernver.imgAlternatively you could try the more standard
mkinitrd --force /boot/initramfs-$kernver.img $kernver
rebuild the main image
If you want to update the main kernel image rather than a module, then just build it as follows and copy it to /bootmake bzImage
optional cleanup
rm -Rf $rpmbuild_base/BUILD/kernel-$kernbase/
© Aug 18 2009