b43 wireless driver in Kubuntu 7.10 (Gutsy)

After installing Kubuntu 7.10 (Gutsy) on a HP Pavilion dv9600 series laptop (dv9625 to be exact), I was able to reboot and have everything work properly except for the wireless driver. The wireless device is a Broadcom BCM4312, which unfortunately doesn't work with the bcm43xx driver that is available under Gutsy. The only other option is to use ndiswrapper, which I prefer to avoid if given the choice.

The newer b43 driver supports the BCM4312 driver, but it will only be available in the 2.6.24 series of kernels that will be released with Ubuntu 8.04 (Hardy Heron). Since I didn't want to wait 4 months to get wireless working on the laptop, I had to compile the b43 driver myself. Luckily, there is a wireless compatibility package for 2.6.22 kernels available at linuxwireless.org. I'll outline below the steps I took to get it to working under K/Ubuntu 7.10.

1. I needed to compile a custom kernel as per the instructions found here, so the first step was to set up the kernel sources in /usr/src:

$ sudo apt-get source linux-source-2.6.22
$ cd /usr/src
$ sudo tar xjf linux-source-2.6.22.tar.bz2

2. Since I needed the nvidia driver too, I had to get the nvidia sources and extract them to /usr/src/modules:

$ sudo apt-get install nvidia-new-kernel-source
$ cd /usr/src
$ sudo tar zxf nvidia-new-kernel-source.tar.gz

3. I needed to configure the kernel using the Ubuntu .config of my stock 2.6.22 Ubuntu kernel, so I just needed to copy the config file from /boot. Note: I was missing the "snd-hda-intel" driver, and had to enable it myself using menuconfig:

$ cd /usr/src/linux-2.6.22
$ cat /boot/config-2.6.22-14-386 > .config
$ sudo make oldconfig
$ sudo make menuconfig (enable snd-hda-intel, and change any other options).

4. Now I was ready to compile the kernel. The first time I did it the "Ubuntu way", I used the "--append-to-version" option, which caused problems later with the b43 and nvidia drivers. So, to avoid problems, I built my kernel and nvidia driver with the following command without using the "apped-to-version" option:

$ cd /usr/src
$  make-kpkg --initrd kernel_image kernel_headers modules_image

5. In the last command, the "modules_image" option will build everything that is in /usr/src/modules; in this case the nvidia drivers. When all is done, you should have 3 .deb files in /usr/src:

$ ls /usr/src/*.deb
linux-headers-2.6.22.9_2.6.22.9-10.00.Custom_i386.deb
linux-image-2.6.22.9_2.6.22.9-10.00.Custom_i386.deb
nvidia-kernel-2.6.22.9_100.14.23-0ubuntu3+2.6.22.9-10.00.Custom_i386.deb

A simple "dpkg -i "*.deb" was all that was needed to get things installed. Now, reboot and cross your fingers that the nvidia driver works (this seems like a 50/50 proposition to me, as I've had many failures in the past on Debian/Ubuntu machines). If you have problems, I suggest trying Envy, which has a good chance of working.

6. install the b43-fwcutter package from Hardy Heron (Ubuntu 8.04). There are no dependencies, so a simple download using wget and installing with "dpkg -i" will work without problems.

7. Assuming you custom kernel build went well, you should now be able to build and install the b43 driver yourself. Download the wireless compatibility sources and follow the "building for external kernels" insructions. Namely

$ cd /usr/src
$ sudo wget http://linuxwireless.org/download/compat-wireless-2.6/compat-wireless-2....
$ sudo tar xjf compat-wireless-2.6.tar.bz2
$ cd compat-wireless-2.6
$ sudo make KLIB=/usr/src/linux-2.6.22 KLIB_BUILD=/usr/src/linux-2.6.22
$ sudo make KLIB=/usr/src/linux-2.6.22 KLIB_BUILD=/usr/src/linux-2.6.22 install load
The b43 module should now be loaded; you can confirm that it's working using "iwconfig". In my case, KNetworkManger automatically detected my access point and I was connected and surfing.

Comments

Why the custom kernel?

Out of curiosity, what was the reason for building a custom kernel for this? I managed to use step 7 to build a working driver against the stock gutsy kernel.

I tried it with the stock

I tried it with the stock kernel and modprobe was giving errors when trying to load the driver. The only way I could get it to load properly was to go through the whole custom build process.