FAQs on Building MADWiFI

I get 'No rule to make target /lib/modules/{kernel_version}/build/.config

/lib/modules/{kernel_version}/build should be a symlink to /usr/src/{kernel_version}. You’ll get this error if it isn’t. To correct the problem, first install your distro’s kernel sources (people with home rolled kernels don’t generally get this problem - for more or less obvious reasons), and then do:

# cd /lib/modules/{kernel_version}
# ln -s /usr/src/linux-{kernel_version} build
# and to check it worked:
# ls -al build

You should see something like this:

lrwxrwxrwx 1 root root 21 Sep 22 17:12 build -> /usr/src/linux-{kernel_version}

If you’ve just installed a RedHat kernel package, have all of the correct symlinks, and it still won’t work, then it could be because you don’t have a built/configured kernel. To fix this problem cd into your kernel tree and build it as normal. [Note: previous driver incarnations did not require a built kernel tree, however recent versions (post Dec 2003) have used kbuild in the Makefile, which need to use some parts of the built kernel.]

iwconfig reports: No wireless extensions.

You need to build a kernel with CONFIG_NET_RADIO and CONFIG_NET_WIRELESS enabled. Normally selecting the former in menuconfig automatically enables the latter too, but if you’re editing by hand, remember to set both, since its the WIRELESS bit that switches on /proc/wireless.

You can get the latest wireless extensions from: http://www.hpl.hp.com/personal/Jean_Tourrilhes/Linux/ although most recent kernels already have them.

According to Felipe Saint-Jean, you also need to ensure that your kernel is built with SMP (CONFIG_SMP) support off.

Jason Lewandowski also suggests restarting PCMCIA services, you may find this helps.

Why is the kernel source required to build Madwifi?

This answer is a mixture of mailing list discussion from Per Bjornsson and Greg Chesson.

The full kernel source code is _not_ required in order to build the MADWIFI drivers. However, you do need the particular makefiles, headers and some other stuff that is particular to the kernel that you’re compiling for; there’s simply no good way to get around this - Linux kernel modules _do_ need to be tailored specifically to the kernel in question, since interfaces may change and in particular the binary interface is actually not necessarily really the same for SMP and single-processor kernels.

Several Linux 2.6-based distributions no longer ship the necessary files as part of some running-kernel-customized source tree; instead they ship these files as part of the kernel package or possibly in a separate package. As an example, in Fedora Core 2, which I’m running, this is directly in the /lib/modules//build directory (for most Linux 2.4 distros this just used to be a symlink to the source code directory, which might or might not have been prepared correctly).

Of course, the proof of the pudding is in the tasting, and the tasting in this case is the fact that you can read this e-mail. I _do not_ have a kernel source package installed, yet I was able to build the MADWiFi drivers and it works perfectly. (Currently using the WPA branch, however the situation was the same for the HEAD branch.) No thanks to me either; all I did was type ‘make’ and then ‘make install’ with the kernel in question running. (Unfortunately both steps needed root access; the first step shouldn’t really, and that might have be fixed recently in the Makefile - haven’t updated recently, but in order to work without write access to the kernel ‘build’ directory one apparently needs to use a new syntax in the makefile that was introduced in 6 or so.)

And from Greg Chesson,

The driver needs the kernel header files for compilation. That much is obvious. In order to make the driver readily buildable for either 2.4 or 2.6 kernels, a decision was made to use the kernel Makefiles. So… minimum answer is that the .config file, headers, and Makefiles are needed.

You could argue that we should have retained the original build procedure with madwifi-specific makefiles in the driver. However, the rapid pace of change with kernel build procedures when 2.6 came along made this an intractable problem for us.

ath_hal.o does not exist.

You're using a revision older than 1535, you should upgrade. If you don't want to, you can still read this:

You need to install the sharutils for your distribution. If your distro doesn’t have such a package, it is uuencode and uudecode which you need.

I get 'uudecode : i386-elf.hal.o.uu : no end line'

You're using a revision older than 1535, you should upgrade. If you don't want to, you can still read this:

This entry was sent in by Jean Daniel Browne:

The HAL is a binary file encoded in ASCII for easy download (and because CVS doesn't like binaries). It is meant to be decoded with uudecode in the first steps of the building process.

It is likely that the problem does not come from your system nor from the code. What may be happening is that you retrieved the file with a non-unix software that converted the unix text file format to dos format. End of line are represented by the linefeed character in unix but represented with carriage return + linefeed in dos. uudecode is confused by the CR/LF at the end of the last line of the file because it only expects a LF character.

What you can do is select an option to download the file as is (with no conversion). Wincvs offers such an option (in “preferences” : “check out files with the unix LF”).

Or you can convert i386-elf.hal.o.uu back to unix style by deleting the carriage return character with any method you like (awk, sed, tr, vi, perl, dos2unix, emacs). The encoded HAL is in the madwifi/hal/linux/ directory. E.g.:

tr -d '\15' > i386-elf.hal.o.uu < hal.unix
mv -f hal.unix i386-elf.hal.o.uu

You should then be ready to build the module.

During compilation I see lots of warnings about undefined symbols, and loading the driver fails due to "unresolved symbols".

There are two seperate issues here, the most important one is the unresolved symbols errors. The warnings about undefined symbols are purely cosmetic.

First, make sure your kernel is configured correctly. See: UserDocs/KernelConfig.

Then, recompile the kernel if necessary and reboot with this new kernel. Remove old versions of the Madwifi modules if necessary, then recompile Madwifi. It should work now.

I get, 'Unresolved symbols in _IEEE(something)', help!

You must make sure that you build your kernel with CONFIG_MODVERSIONS=n, thanks to Joe Milbourn for (inadvertantly) testing this!

Also, Jon Bohlke points out that if you’ve patched the driver into your kernel source, you need your kernel to have IEEE.80211 in it’s config.

Compiling madwifi for 64bit x86 fails with a message saying something like "relocatable linking from elf32-i386 to elf64-x86-64 not supported". Help?!

The exact error message looks like this:

ld: Relocatable linking with relocations from format elf32-i386
(/path/to/madwifi/ath_hal/hal.o) to format elf64-x86-64
(/path/to/madwifi/ath_hal/ath_hal.o) is not supported

Let’s have a look on what happens when Madwifi is getting built. The first module that is built is ath_hal.o, which contains the binary HAL code and some platform-specific glue code (see here for further explanation). Make doesn’t know (yet) that you’re trying to build code for 64bit x86 and hence uses the precompiled HAL for 32bit x86, while the platform-specific glue code gets compiled for 64bit x86 by your C compiler. When the linker tries to throw both code pieces together it had to mix 32bit and 64bit code, which isn’t supported - et voila, that’s the meaning of the error message as mentioned above.

All you have to do is to tell make you’re planning to build madwifi for 64bit x86. The simplest way to do this is the following:

make TARGET=x86_64-elf

If you’re cross-compiling (for example you want to build 64bit code on a 32bit system) you most probably also need to specify TOOLPREFIX so that make is able to find the 64bit compiler suite. You can find more information on avaiable Makefile parameters in UserDocs/Makefile.

Compilation is aborted with a "pointer targets ... differ in signedness" error

The message usually looks like:

cc1: warnings being treated as errors
In file included from include/linux/if_ether.h:107,
                 from include/linux/netdevice.h:29,
                 from /home/prolag/madwifi/net80211/if_media.c:60:
include/linux/skbuff.h: In function 'skb_add_data':
include/linux/skbuff.h:1067: warning: pointer targets in passing argument 1 of 'csum_and_copy_from_user' differ in signedness

As you can see this problem is inside a kernel header, not MadWifi. It usually occurs when you compile MadWifi with gcc 4.x, and it's just a warning which, in this case, could be safely ignored. Now MadWifi uses an option that causes the compiler to treat warnings as errors and as a result the build process will be aborted even on harmless warnings.

There are several ways to get around this:

  1. Use a more recent kernel version, gcc-4 related issues will be fixed there.
  2. Remove -Werror from MadWifi's Makefile(s) so that warnings won't cause the build process to abort. This is a quick'n'dirty work-around and should be used with caution, as it probably hides other issues.
  3. Especially for (but not limited to) Ubuntu users: If you're running a pre-compiled kernel that comes with your distribution and you're about to compile MadWifi yourself for that kernel, make sure you use the same gcc version that the kernel was compiled with.
    Ubuntu, for example, compiles their kernels with gcc 3.x but installs only gcc 4.x for the users by default. If you compile MadWifi manually now, it will be compiled with gcc 4.x. This mismatch then results in problems once you're done with compiling and trying to load the MadWifi modules.

stdlib.h, stdio.h, string.h, etc do not exist

The errors look like

In file included from hostapd.c:16:
includes.h:25:20: warning: stdlib.h: No such file or directory
includes.h:26:19: warning: stdio.h: No such file or directory
includes.h:28:20: warning: string.h: No such file or directory
includes.h:30:20: warning: signal.h: No such file or directory

You have to install the libc6-dev package.