16k kernel stacks on Ubuntu Feisty

My Compaq nw9440 laptop has a Conexant HSF soft modem. To make a long story short, the only way to get it to work on Linux (that I know of, anyway) is to use the commercial Linuxant drivers. Conexant paid them to sell drivers, and they're twenty bucks. It's not a bad deal compared to 3com, which does not and may never have Linux support for Winmodems (especially older ones.)

Unfortunately the driver code is Windows-centric and as such may not run properly with the default Linux stack size. Linux has 8k stacks by default and the Linux world is moving towards 4k stacks; the Conexant wifi driver loader ("Driverloader", of course) requires 16k stacks and there are reports (although Linuxant disagrees with them) that the modem driver may work better with them as well. To that end, you must install a kernel patch from linuxant to support these larger stacks. They also provide kernels for some distributions, but mostly redhat, which does the 4k stacks by default and which is least likely to work with their drivers/loaders.

Regardless of the reason you want the larger stack size (which, mind you, may compromise performance slightly!) the following is, in broad outlines, the method for building the kernel. As a note, I just did a sudo bash and ran it all as root. Otherwise, you're going to be typing sudo before practically everything. It's up to you.

Install the Kernel Source

Ubuntu provides kernel-source packages for Linux. If you want the latest source, install the linux-source package, it's just that simple. If you're keeping an updated system, this is what you want.

Make sure you have other required packages installed

Aside from linux-headers and the whole build-essential package, you should also install the kernel-package and fakeroot package. This includes the tools you will need to actually build the kernel package, which lets you install it and manage your custom kernel as you would any other package.

Apply patches

I'm using kernel 2.6.20, so all I had to do was change directory to /usr/src/linux-2.6.20, and run the following command:

patch -p1 < linux-2.6.20-16kstacks.patch

This example assumes you copied the patch file to your linux source directory, otherwise specify the path. If you fear the patch might not apply properly you can specify the --dry-run flag to patch, which attempts to apply patches without changing files. If there are errors, you can catch them here. This way you won't get into situations of reinstalling source code or trying to remove patches (it is possible, but it can be complicated with patches which failed to install.) In fact, in this way it is possible to turn a linux kernel source tree into an older version - to turn kernel 2.6.20 into 2.6.19, for example, you would remove the 2.6.20 patch from 2.6.20! If you are on a slow connection this can occasionally save you a lot of bandwidth.

Configure the kernel

First, start with the current kernel config. Regardless of which distribution you are using, this is the intelligent thing to do. Ubuntu provides a fully-patched source tree (sans the option we're adding right now) so your current config file will work with the new kernel. Copy /boot/config-`uname -r (in my case, /boot/config-2.6.20-16-lowlatency to ./.config in order to do this.

It is necessary to activate the 16k stacks option. Run make menuconfig and select "Load an Alternate Config File". The default is .config, so just load it. Now go into the kernel hacking/debugging options. Turn on the option to use 16k stacks (don't turn on the 4k stacks option too!) Finally, exit and elect to save. You are now done patching and enabling the option.

Build the actual kernel packages

You need a whopping two commands to do the actual build. As per How To Compile A Kernel - The Ubuntu Way by Falko Timme, here they are:

make-kpkg clean
fakeroot make-kpkg --initrd --append-to-version=-custom kernel_image kernel_headers

You can leave out the --append-to-version=-custom option if you don't want your kernel to be noticably customized. It must begin with the dash character, but after that it should be able to be anything alphanumeric. You could use the name of the machine you intend it for, or the name of a domain if you plan to use it anywhere. Be creative, but keep it short because otherwise it will annoy you later.

If you have a multicore system, run the actual build command like so:

CONCURRENCY_LEVEL=n fakeroot make-kpkg --initrd --append-to-version=-custom kernel_image kernel_headers

Most guides suggest setting this at the number of physical CPUs plus 1. Even on a single-core system you might want to specify 2 (but I don't.) I did use 3 for my dual-core. It can take an amazingly long time to build kernels and you want all the help you can get. If you have many machines to work with you should look into distcc and if you compile the same kernel a lot (for example, if you expect to have problems compiling) you should consider ccache.

Installing

The kernel packages will end up in your /usr/src directory, or at least mine did. I started with a config from a -lowlatency kernel, so in theory I have low latency enabled etc etc. Here's the names of my packages:

linux-headers-2.6.20.3-ubuntu1-hyperlogos_2.6.20.3-ubuntu1-hyperlogos-10.00.Custom_i386.deb
linux-image-2.6.20.3-ubuntu1-hyperlogos_2.6.20.3-ubuntu1-hyperlogos-10.00.Custom_i386.deb

Quite unwieldy, but that's not so important. Install each one with dpkg -i, kernel first:

dpkg -i linux-image-2.6.20.3-ubuntu1-hyperlogos_2.6.20.3-ubuntu1-hyperlogos-10.00.Custom_i386.deb
dpkg -i linux-headers-2.6.20.3-ubuntu1-hyperlogos_2.6.20.3-ubuntu1-hyperlogos-10.00.Custom_i386.deb

Your filenames will almost certainly be different but these commands correspond to the packages I made. Enter commands accordingly.

That's it! If you reboot the system should come up with the new kernel. You will likely have to rebuild the nvidia kernel module and the vmware kernel modules if you use such things. I manage both of these pieces of software manually, which requires intervention (but no additional reboot!) for each kernel upgrade.

Closing

Ideally you would purchase a laptop where you know all hardware is supported. When this is not possible, means like this may be necessary. I could make this guide a little more user-friendly but building the kernel is inherently not a friendly activity and if you are not already familiar with it, this guide may well fail you. Please do not ask me for additional assistance - there are numerous places to get help with Linux, and building kernels - and ultimately, the idea of most modern distributions is to avoid ever actually having to do so. If it weren't for my wonky modem, I'd be running on a stock kernel right now.

Add new comment