|
|
Subscribe / Log in / New account

Driver porting: compiling external modules

This article is part of the LWN Porting Drivers to 2.6 series.
The 2.5 development series saw extensive changes to the kernel build mechanism and the complete replacement of the module loading code. One result of these changes is that compiling loadable modules has gotten a bit more complicated. In the 2.4 days, a makefile for an external module could be put together in just about any old way; typically a form like the following was used:

    KERNELDIR = /usr/src/linux
    CFLAGS = -D__KERNEL__ -DMODULE -I$(KERNELDIR)/include -O

    all: module.o

Real-world makefiles, of course, tended to be a bit more complicated, but the job of creating a loadable module was handled in a single, simple compilation step. All you really needed was a handy set of kernel headers to compile against.

With the 2.6 kernel, you still need those headers. You also, however, need a configured kernel source tree and a set of makefile rules describing how modules are built. There's a few reasons for this:

  • The new module loader needs to have some extra symbols defined at compilation time. Among other things, it needs to have the KBUILD_BASENAME and KBUILD_MODNAME symbols defined.

  • All loadable modules now need to go through a linking step - even those which are built from a single source file. The link brings in init/vermagic.o from the kernel source tree; this object creates a special section in the loadable module describing the environment in which it was built. It includes the compiler version used, whether the kernel was built for SMP, whether kernel preemption is enabled, the architecture which was compiled for, and, of course, the kernel version. A difference in any of these parameters can render a module incompatible with a given running kernel; rather than fail in mysterious ways, the new module loader opts to detect these compatibilities and refuse to load the module.

    As of this writing (2.5.59), the "vermagic" scheme is fallible in that it assumes a match between the kernel's vermagic.o file and the way the module is being built. That will normally be the case, but people who change compiler versions or perform some sort of compilation trickery could get burned.

  • The new symbol versioning scheme ("modversions") requires a separate post-compile processing step and yet another linkable object to hold the symbol checksums.

One could certainly, with some effort, write a new, standalone makefile which would handle the above issues. But that solution, along with being a pain, is also brittle; as soon as the module build process changes again, the makefile will break. Eventually that process will stabilize, but, for a while, further changes are almost guaranteed.

So, now that you are convinced that you want to use the kernel build system for external modules, how is that to be done? The first step is to learn how kernel makefiles work in general; makefiles.txt from a recent kernel's Documentation/kbuild directory is recommended reading. The makefile magic needed for a simple kernel module is minimal, however. In fact, for a single-file module, a single-line makefile will suffice:

	obj-m := module.o
(where module is replaced with the actual name of the resulting module, of course). The kernel build system, on seeing that declaration, will compile module.o from module.c, link it with vermagic.o, and leave the result in module.ko, which can then be loaded into the kernel.

A multi-file module is almost as easy:

	obj-m := module.o
	module-objs := file1.o file2.o 
In this case, file1.c and file2.c will be compiled, then linked into module.ko.

Of course, all this assumes that you can get the kernel build system to read and deal with your makefile. The magic command to make that happen is something like the following:

    make -C /path/to/source SUBDIRS=$PWD modules
Where /path/to/source is the path to the source directory for the (configured and built) target kernel. This command causes make to head over to the kernel source to find the top-level makefile; it then moves back to the original directory to build the module of interest.

Of course, typing that command could get tiresome after a while. A trick posted by Gerd Knorr can make things a little easier, though. By looking for a symbol defined by the kernel build process, a makefile can determine whether it has been read directly, or by way of the kernel build system. So the following will build a module against the source for the currently running kernel:

    ifneq ($(KERNELRELEASE),)
    obj-m	:= module.o

    else
    KDIR	:= /lib/modules/$(shell uname -r)/build
    PWD		:= $(shell pwd)

    default:
	$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
    endif

Now a simple "make" will suffice. The makefile will be read twice; the first time it will simply invoke the kernel build system, while the actual work will get done in the second pass. A makefile written in this way is simple, and it should be robust with regard to kernel build changes.


to post comments

Driver porting: compiling external modules

Posted Feb 6, 2003 6:05 UTC (Thu) by rfunk (subscriber, #4054) [Link] (5 responses)

For the make trickery in the latter part of this article, it's important to note that the original make command assumes the kernel source is in /usr/src/linux/:
make -C /usr/src/linux SUBDIRS=$PWD modules
While the makefile that allows a shorter command line assumes the kernel source is in a directory like /lib/modules/2.5.59/build/, due to the following line:
KDIR := /lib/modules/$(shell uname -r)/build

I believe there was some minor controversy on the linux-kernel mailing list recently over which location is more appropriate.

Path to the kernel source

Posted Feb 6, 2003 14:44 UTC (Thu) by corbet (editor, #1) [Link] (3 responses)

Actually, /usr/src/linux is pretty much deprecated by the Prime Penguin himself; you're supposed to keep your kernel sources somewhere else. I got lazy and used it in the example, mostly because it's shorter to type than the /lib/modules path. The latter is the better way to go, however, especially in scripts or makefiles - it "automatically" points to the right source tree, unless you move your trees around.

Path to the kernel source

Posted Oct 27, 2004 8:25 UTC (Wed) by rashminivarthy (guest, #25682) [Link] (2 responses)

hello,
i was trying to compile a simple helloworld module on linux-2.6
kernel (Fedoracore-2)i'm geting this error while using this
makefile
---------------
|MakeFile |
----------------
ifneq ($(KERNELRELEASE),)
obj-m := hello.o
else
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
endif
---------------
|ERROR MESSAGE|
----------------
cc hello.c -o hello
hello.c:1:26: linux/module.h: No such file or directory
hello.c:2:27: linux/kernel.h: No such file or directory
hello.c:3:24: linux/init.h: No such file or directory
make: *** [hello] Error 1

unable to use ksyms on 2.6 kernel

Posted Oct 27, 2004 10:17 UTC (Wed) by rashminivarthy (guest, #25682) [Link] (1 responses)

hello
i tried using ksyms on 2.6 kernel to view all the exported kernel
symbols .It gave an error-
ksyms: QM_MODULES: Function not implemented

plz any 1 reply back

unable to use ksyms on 2.6 kernel

Posted Jul 18, 2005 11:38 UTC (Mon) by kalou (guest, #31046) [Link]

Hi rashminivarthy,

your kernel is not module enabled,
obviously.

Sincere Regards,

Olivier

Driver porting: compiling external modules

Posted Sep 14, 2005 23:45 UTC (Wed) by mraviraj (guest, #32463) [Link]

We have been using linux 2.4 for the development and recently started supporting 2.6.

I need to port our existing makefiles to work with 2.4 and 2.6.

while i am trying to use following syntax for 2.4, it is just doing 'make clean' job in linux kernel directory.

ifeq ($(KERNELRELEASE),)
obj-m := foo.o
else
KDIR := /linux/kernel/src/v2.4/linux-2.4.31
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
endif

foo-objs := foo1.o foo2.o

Can someone please share their experience in compiling the same source code for 2.4 and 2.6 ?

thanks ..
Raviraj

Driver porting: compiling external modules

Posted Feb 6, 2003 11:03 UTC (Thu) by raarts (guest, #4184) [Link]

Thanks for this article.
This is why I subscribe to LWN.

Ron Arts

What about cross-compilation?

Posted Feb 6, 2003 18:35 UTC (Thu) by sjmadsen (guest, #4035) [Link] (6 responses)

The Makefile trickery at the end isn't going to work in cross-compiler enviornments. My company is building a product that uses Linux as the embedded OS, but builds typically take place on Solaris.

Even if we were building on Linux, it's unlikely that the OS on the build machine is going to match the embedded environment.

What about cross-compilation?

Posted Feb 6, 2003 21:02 UTC (Thu) by Peter (guest, #1127) [Link]

The Makefile trickery at the end isn't going to work in cross-compiler enviornments. My company is building a product that uses Linux as the embedded OS, but builds typically take place on Solaris.

True enough. In fact, there is no automated way for the computer to read your mind and know, for a specific module build, where the matching kernel tree resides. If you don't give the computer any more information, one reasonable guess is "wherever the currently-running kernel was built, assuming it was built on this machine". In fact, I can't think of a better default guess. But if this turns out to be wrong - for various reasons, including cross-compilation - you are going to have to specify the source location.

Putting that location in the Makefile as a special macro like KERNELDIR makes it possible to override on the command line: 'make KERNELDIR=...'. The other option, of course, is to work to get your module integrated into the official kernel tree, at which time you are rid of this headache once and for all.

What about cross-compilation?

Posted Feb 7, 2003 15:50 UTC (Fri) by dwmw2 (subscriber, #2063) [Link] (4 responses)

It works perfectly for cross-compilation for me. If you override CROSS_COMPILE (or have it set in your kernel's top-level Makefile) that works just as it always did:@
make KDIR=/local/arm-kernel CROSS_COMPILE=arm-linux-gnu-

Note also that the article is somewhat misleading -- the Makefile fragment

> KERNELDIR = /usr/src/linux
> CFLAGS = -D__KERNEL__ -DMODULE -I$(KERNELDIR)/include -O
>
> all: module.o

... was _always_ broken and nonportable -- building using the kernel makefiles was the only way to get it working portably since about the 2.0 kernel. It doesn't kernel+arch-specific CFLAGS like -mregparm= -mno-gp-opt -mno-implicit-fp right.

What about cross-compilation?

Posted Mar 3, 2005 10:48 UTC (Thu) by mhb (guest, #28187) [Link] (3 responses)

I have tried this on the simple hello.c module.
I use the ELDK cross compiler to generate code for
a ppc 440 from an X86 based machine. It fails
with some emulation mode problems, any ideas ?

[root@basher ebonymnt]# export CROSS_COMPILE=ppc_4xx-
[root@basher ebonymnt]# make -C /home/simon/ebonymnt/linux-2.6.10 M=`pwd`
make: Entering directory `/home/simon/ebonymnt/linux-2.6.10'
LD /home/simon/ebonymnt/built-in.o
CC [M] /home/simon/ebonymnt/hello.o
Building modules, stage 2.
MODPOST
CC /home/simon/ebonymnt/hello.mod.o
LD [M] /home/simon/ebonymnt/hello.ko
ppc_4xx-ld: unrecognised emulation mode: elf_i386
Supported emulations: elf32ppclinux elf32ppc elf32ppcsim
make[1]: *** [/home/simon/ebonymnt/hello.ko] Error 1
make: *** [modules] Error 2
make: Leaving directory `/home/simon/ebonymnt/linux-2.6.10'
[root@basher ebonymnt]#


What about cross-compilation?

Posted Oct 14, 2005 0:02 UTC (Fri) by msprauve (guest, #33084) [Link] (1 responses)

Did anyone develop a resolution to this problem?

What about cross-compilation?

Posted May 2, 2006 13:59 UTC (Tue) by DeferX (guest, #37486) [Link]

Tray this
make CROSS_COMPILE=ppc_6xx- ARCH=ppc
It's work

By
defer

What about cross-compilation?

Posted Nov 10, 2005 22:02 UTC (Thu) by urs (guest, #33777) [Link]

You should call

make CROSS_COMPILE=ppc_4xx- -C ...

instead of your command

CROSS_COMPILE=ppc_4xx- make -C ...

which handles make variables differently. See the make manual for details.

urs

Hardware vendor supplied modules

Posted Feb 6, 2003 21:02 UTC (Thu) by pradu (guest, #4323) [Link] (5 responses)

I see a problem with hardware (and software) vendors modules that are supplied in source code (see for instance VMWare kernel modules). If you can't compile a kernel module without the kernel source tree and on a different machine (maybe with different compiler/processor and whatnot) from the distibutor kernel, you can't use such modules.

Or I am missing something?

Hardware vendor supplied modules

Posted Feb 8, 2003 0:28 UTC (Sat) by Peter (guest, #1127) [Link] (2 responses)

I see a problem with hardware (and software) vendors modules that are supplied in source code (see for instance VMWare kernel modules). If you can't compile a kernel module without the kernel source tree and on a different machine (maybe with different compiler/processor and whatnot) from the distibutor kernel, you can't use such modules.

There are a few possibilities here:

  • completely disallow external modules - then, VMWare and co. would have to provide a patch to integrate their modules with the kernel source proper, and each customer would have to apply this patch and rebuild the kernel. (Or, alternatively, VMWare could ship with a custom kernel, but then they'd have to follow the GPL and open-source their module.)
  • have VMWare and their ilk each track all the major vendor kernels and release modules to go with each one. Many proprietary module vendors do this today. It's a horrible hack but it does work for some people.
  • freeze the kernel/module interface, somehow nullify or abstract away all differences that affect it, and maintain this situation for a given length of time (say, a stable series). That would include gcc 2.95 vs. gcc 3.2, preemptible vs. non-preemptible, UP vs. SMP, 386 vs. 586 vs. K7, highmem vs. non-highmem, and a few other details, on the x86 platform. This is the Microsoft / commercial Unix solution, and the Linux people refuse to bother with it. If you think this is the way to go, please be prepared to present your patch which does all this without affecting efficiency or maintainability of the source base. Alternately, Google for 'UDI unix linux' and see what happened the last time this was proposed.
  • take some sort of snapshot of the state of the build environment when you build a kernel, and make this snapshot available somehow for when you want to build an external module. This snapshot would consist of kernel headers, .config file, exact compiler and its flags, and some sort of glue to plug the external module in to all this.

At present, we have the latter option, in the form of a live source tree. Note that if you can locate the live source tree you wish to build against, and the compiler you used to build the kernel, and any other variables you passed in when you built the kernel (like a CROSS_COMPILE variable), you can use this method just fine.

If you don't know this information, unfortunately there is no way for the computer to divine it for you. What if I build 10 different kernels on my box, destined for 10 different machines, then I try to build an external module? How is the system supposed to know which of my 10 kernels the module is for? Barring a direct DWIM neural interface (for which Linux drivers are still sadly lacking), I'm gonna have to point my module at the proper kernel tree, and re-set-up any custom variables I set the first time.

Hardware vendor supplied modules

Posted Feb 13, 2003 22:53 UTC (Thu) by mmarq (guest, #2332) [Link] (1 responses)

>freeze the kernel/module interface, somehaw nullify or abstract away all differences...

IN OTHER WORDS, BUILD A IN KERNEL API/ABI (like in LSB)!!!

THE PROBLEM WHIT "UDI" WAS NOT THE IDEA IN ITSELF, BUT "HOW AND WHO" WAS IN CONTROL...IN THE BEGINING LINUS WAS A PROMOTER OF IT...

YOU ALREADY HAVE A "ABSTRACT INTERFACE" IN KERNEL IN THE FORM OF I2O...THE PROBLEM IS THAT YOU NEED "SPECIAL HARDWARE" TO GET ALONG WITH IT...

The current "state of the art" is, as specified in your explanation, there is no simple answer to any question... be it cross-compilation, be it building external modules, or whatever related to hardware. There's almost 100% certainty now that you run against "gcc 2.95 vs. gcc 3.2, preemptible vs. non-preemptible, UP vs. SMP, 386 vs. 586 vs. K7, highmem vs. non-highmem"....

BUILDING GOOD AND COMPLETE WIDE SUPPORTE FOR A PIECE OF HARDWARE IN EXTERNAL MODULES, "IS FOR SURE NOW" ONLY FOR A SKILLED AND WELL DOCUMENTED "COMERCIAL" TEAM...(how about that????)

If you have to have a good and extensive support of hardware in the form of in kernel loadable modules, it would mean that the source of the kernel could easely be 10 times of current size, cutting out those that dont have broadband( more than half of the world), or...

...LINUS GETS FIRED FROM TRANSMETA OR DIES OF EXAUSTION!...OR FOR STABLE KERNEL 2.8/3.0 YOU HAVE A "DEVELOPMENT CICLE OF 4 YEARS",...OR WORST THAN EVERYTHING ELSE BEFORE!!!...YOU SEE THE KERNEL HIGHJACKED IN THE FORM OF NVIDEA-KERNEL, ATI-KERNEL, OR MORE COMPLET HP/COMPAQ-KERNEL, DELL_KERNEL, GATEWAY-KERNEL, LIVING IN THE DUST THE LESS COMPLIENT RH-KERNEL, MANDRAKE_KERNEL, SUSE_KERNEL, VMWARE_KERNEL!!!!...

IS THE LINUX KERNEL HEADING FOR A "ABISM", OR IS MY IMAGINATION?????????

Hardware vendor supplied modules

Posted Jul 22, 2005 16:55 UTC (Fri) by qu1j0t3 (guest, #25786) [Link]

IT'S YOUR IMAGINATION

Hardware vendor supplied modules

Posted Feb 8, 2003 15:12 UTC (Sat) by jschrod (subscriber, #1646) [Link]

Is there any vendor who doesn't distribute source code and config/{autoconf,version}.h to its kernel? I always thought, on different machine, one installs said kernel source code, adds the config files, and there you go. At least, this worked for me all the time.

Cheers, Joachim

How to compile linux driver as loadable module

Posted Mar 30, 2004 15:46 UTC (Tue) by linuxdev (guest, #20542) [Link]

I have one moduel as test.c and i want to comiple and load into 2.6 kernel
I want to know options for comiling.

Driver porting: compiling external modules

Posted Feb 13, 2003 0:17 UTC (Thu) by pedretti (guest, #9593) [Link] (1 responses)

This is probably a dumb question, but what is the module that you insmod? When I compile the hello_world I get a hello_world.o and a hello_world.ko. Both of these can be insmod'ed but the hello_world.o give an error "no version magic, tainting kernel" -- so I assume the hello_world.ko is the one I want to use?

Driver porting: compiling external modules

Posted Apr 30, 2003 20:19 UTC (Wed) by krobidea (guest, #10955) [Link]

It seems that this 2.5 method of compiling external modules does not work on older kernel versions. I tried the example .c and Makefile, and got the following results:

- RedHat 7.3 out of the box (2.4.18-3 w/.config or any .o files). Compilation fails, thinking that module support is not compiled in.

- Version 2.4.20 I built and installed. Compilation failed, *** No rule to make target `modules'. This happens when make changed back to my working directory and did a make xxx modules. The kernel source base Makefile appears to be different in the 2.5.x versions.

So, will external modules require that the source be present, built and running? I don't believe any RedHat distributions will work.

What about the 2.4 or 2.2 target modules issue?

Driver porting: compiling external modules

Posted Feb 13, 2004 14:25 UTC (Fri) by grisu1976 (guest, #19435) [Link]

What about compiling a module that is composed of multiple files? Especially if you use global variables across all files using the extern storage specifiers referencing the global variable definition in one file? I do this and getting a "is COMMON symbol" warning for that variable and at module loading (the .ko file) a "Invalid module format" error. If i use the static storage specifier in all files (for the source definition and the extern references), module loading works fine, but the nm command shows that there are as many symbols as files...

Is there a compiler parameter to achieve global variables across multiple files of a module? It's strange, because in kernel 2.4 my module worked properly

Driver porting: compiling external modules

Posted Feb 19, 2004 20:13 UTC (Thu) by jdeas (guest, #19608) [Link]

I am new to this.
I have a custom driver I want to port to 2.6
The interrupt and work queue info seems good but
I am having trouble with the make file.

Compiling using a standard make command and Makefile
does not understand (can not find) 'obj-m' . Is my basic way of compiling
now wrong?
obj-m:=Mydriver.o give the above error

Driver porting: compiling external modules

Posted Mar 9, 2004 18:04 UTC (Tue) by liangjz (guest, #20079) [Link]

I'm trying to port a 2.4 driver to 2.6 and am having trouble getting the makefile to call nasm.

In the 2.4 driver, I simply had a build rule that said

assembly_stuff.o: assembly_stuff.asm
nasm $(NASM_FLAGS) assembly_stuff.asm


I tried doing the same thing with the 2.6 driver and added

my_driver-objs := assembly_stuff.o

The problem is that the makefile insists that it needs a assembly_stuff.s, presumably to send through GAS.

How can I get around this?

problem when compiling external modules

Posted Mar 10, 2004 21:53 UTC (Wed) by madmax1984 (guest, #20101) [Link]

i encountered the following problem when trying
to compile a hello.o type module for 2.6.1:
after the initial setbacks of having to figure
out about init_module, cleanup_module, SUBDIRS
thingie and all it still wouldn't work:
insmod hello.ko would return -1: invalid format;
insmod hello.o would work warning/error free
(really odd) but i would get a seg fault when
trying to rmmod hello.

after quite a bit of googleing i found the
solution: recompile the kernel with the running
config (the last kernel i had built was for my
gateway and used no modules, had no module
support - which might have been the problem -
although my running kernel had module support)

hope this is useful

Driver porting: compiling external modules

Posted Jul 11, 2004 6:23 UTC (Sun) by kcannon (guest, #4867) [Link] (2 responses)

It's probably better to use $(CURDIR) in the Makefile rather than $(PWD). $(PWD) is set to the directory from which the original make command was issued, while $(CURDIR) is set to the current working directory (eg. as modified by recursive use of make -C). If the driver modules are distributed in a subdirectory of a larger software package, and the user is intended to issue a make command from the top-level directory, using $(PWD) in the driver Makefile will pick up the wrong path.

Cheers
-Kipp

Driver porting: compiling external modules

Posted Jul 12, 2004 2:20 UTC (Mon) by kcannon (guest, #4867) [Link] (1 responses)

Never mind... my mistake. You replace the default value of PWD with the result of $(shell pwd).

problem with $(CURDIR)

Posted Jul 31, 2005 20:42 UTC (Sun) by qu1j0t3 (guest, #25786) [Link]

The GNU make docs say that $(CURDIR), when used with -C, will be the 'new' directory, not the module directory, which would make it incorrect in this situation anyway... I think :-)

SUBDIRS= vs M=

Posted Jul 12, 2004 2:26 UTC (Mon) by kcannon (guest, #4867) [Link] (2 responses)

The 2.6.7 Makefiles say that an external module should be compiled by setting the variable M to the directory in which the module resides, rather than by setting SUBDIRS.  The command line is

$ make -C /path/to/kernel/source M=/path/to/your/module modules

I've confirmed that this does work.  What is the reason for choosing one over the other?  Are they synonyms?

SUBDIRS= vs M=

Posted Jul 12, 2004 13:54 UTC (Mon) by corbet (editor, #1) [Link] (1 responses)

You found the current way of doing things; the article is mildly out of date. I'll fix it, but, since the old scheme continues to work, it's not been my top priority...

SUBDIRS= vs M=

Posted Aug 26, 2004 17:10 UTC (Thu) by r2b2lewis (guest, #24285) [Link]

I am running on SuSE 9.1 (2.6.4-52-smp).

When I ran the make file using the line:

$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules

the make ran quickly without error.

However, when I changed that line to:

$(MAKE) -C $(KDIR) M=$(PWD) modules

I seem to be making the entire kernel again.

What's up with that?

Driver porting: compiling external modules

Posted Jul 15, 2004 6:12 UTC (Thu) by Ryu_Tenchi (guest, #23057) [Link] (2 responses)

i'm a little lose so sorry for this, but i'm trying to figure this stuff out but it never actually make the module...
code:
//main.c
#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>

int init_module(void){printk("<1>Hello, world\n"); return 0;}
void cleanup_module(void) {printk("<1>Goodbye cruel world\n");}

makefile:
objs-m := main.o

command entered:
make -C /usr/src/linux M=`pwd` modules

output:
make: Entering directory `/usr/src/linux-2.6.7-gentoo-r11'
Building modules, stage 2.
MODPOST
make: Leaving directory `/usr/src/linux-2.6.7-gentoo-r11'

any help would be great, thanks^_^

Driver porting: compiling external modules

Posted Jul 22, 2004 15:00 UTC (Thu) by disq (guest, #23313) [Link] (1 responses)

apparently it's "obj-m", not "objs-m"

Driver porting: compiling external modules

Posted Jul 23, 2004 23:54 UTC (Fri) by Ryu_Tenchi (guest, #23057) [Link]

*^^* thank you, i feel stupid now lol, but it works and I learned from it
so,thanks again^_^

Multi-file modules--help!

Posted Jul 23, 2004 19:04 UTC (Fri) by ajnicholson (guest, #23376) [Link] (1 responses)

I have an external module comprised of 3 .c files...

I made the following Makefile:
----------------------------------
obj-m := foo.o
module-objs := file1.c file2.c file3.c
-----------------------------------

yet when I compile it by running:
make -C /usr/src/linux SUBDIRS=$PWD modules

It issues the following error:
make[2]: *** No rule to make target '/usr/src/foo.c', needed by '/usr/src/foo/foo.o'. Stop.

Any ideas? I thought the "module-objs" line was supposed to indicate which files comprise the complete module...

Multi-file modules--help!

Posted Jul 25, 2004 17:09 UTC (Sun) by amishdave (guest, #10005) [Link]

I think you need to replace module-objs with foo-objs...

Driver porting: compiling external modules

Posted Jul 26, 2004 17:37 UTC (Mon) by anikami1 (guest, #23453) [Link]

I have the following problem with a device driver. It will load in my machine, but if I try to load it under a different kernel version, or on another machine with a different kernel version, I get "invalid module format" errors. I am pretty sure this has to do with the "version magic" feature of the 2.6.X kernels.

My question is, do I need to compile the module/driver under EACH kernel version out there? Is there a way to compile the module so that it loads on any machine with a 2.6.X kernel?

Driver porting: compiling external modules with local includes

Posted Aug 9, 2004 21:22 UTC (Mon) by cpp9999 (guest, #23889) [Link] (2 responses)

I'm having trouble compiling an external module under the following dir structure
A local header file sits in a directory other than the one that contains the main file
See below:
home_dir/dirA/local.h
home_dir/dirB/main.c

sample main.c file
#include "dirA/local.h"
main ()
{
/* some code */
}

# make -C /usr/src/linux-2.6.7 SUBDIRS=$(PWD) modules
When I try to compile I get the following error messages
Entering directory /usr/src/linux-2.6.7
CC [M] /home_dir/dirB/main.c:15:32: dirA/local.h: No such file or directory

Obviously when I am in /usr/src/linux-2.6.7 I cannot see local.h.

Any ideas how to fix this? Thanks

Driver porting: compiling external modules with local includes

Posted Oct 15, 2004 16:48 UTC (Fri) by geoff_o (guest, #25424) [Link] (1 responses)

I've also been searching for the answer to this question.

What I'd like to be able to do is set a couple of extra 'include' paths. (I note from earlier articles that setting 'CFLAGS' is .. umm.. discouraged.)

I hope there's a work around, otherwise it makes it difficult to develop modules outside the kernel tree that depend on each other.

Does there exist a solution?

Thanks,

Geoff

Driver porting: compiling external modules with local includes

Posted Oct 20, 2004 5:24 UTC (Wed) by amcrae (guest, #25501) [Link]

What I'd like to be able to do is set a couple of extra 'include' paths. (I note from earlier articles that setting 'CFLAGS' is .. umm.. discouraged.)

I needed to do the same thing. You can do this with the EXTRA_CFLAGS Makefile variable:

...
obj-m += file.o
EXTRA_CFLAGS += -I$(obj)/../include

Cheers,
AMc

Driver porting: compiling external modules

Posted Aug 24, 2004 18:05 UTC (Tue) by cidis (guest, #24232) [Link]

I'm porting driver for Pent@value card, but I dont have all sources. Some modules are already compiled. Can I link all together? How?

Driver porting: compiling external modules

Posted Sep 2, 2004 20:30 UTC (Thu) by klaus.hitschler@gmx.de (guest, #24472) [Link]

I've ported my CAN driver to Kernel 2.6.5 and I'm using the M=$(PWD) switch for making this external module. Now I got this output:

make -C /usr/src/linux M=/home/klaus/work/peak/peak-linux-driver/driver V=0 modules
make[1]: Entering directory `/usr/src/linux-2.6.5-7.108'
CC [M] /home/klaus/work/peak/peak-linux-driver/driver/src/pcan_main.o
.... a lot more ...
CC [M] /home/klaus/work/peak/peak-linux-driver/driver/src/pcan_usb.o
LD [M] /home/klaus/work/peak/peak-linux-driver/driver/pcan.o
Building modules, stage 2.
MODPOST
Warning: could not find versions for .tmp_versions/pcan.mod
CC /home/klaus/work/peak/peak-linux-driver/driver/pcan.mod.o
LD [M] /home/klaus/work/peak/peak-linux-driver/driver/pcan.ko
make[1]: Leaving directory `/usr/src/linux-2.6.5-7.108'

I wondered about the line
"Warning: could not find versions for .tmp_versions/pcan.mod".
Some investigation shows that in my $(PWD) a directory .tmp_versions was created and the pcan.mod was stored in that directory. For any strange reason a part of modpost "sumversions.c" is looking for .tmp_versions/pcan.mod located at the base of the kernel source tree. The same happens with the SUBDIRS=$(PWD) syntax.

Does anyone have an idea what' wrong?

P.S. pcan.ko is generated and is works perfectly.

Klaus

Driver porting: compiling external modules

Posted Nov 9, 2004 0:57 UTC (Tue) by kabbalah (guest, #25930) [Link] (3 responses)

hi there
I installed SuSe 9.1 with 2.6.4-52-default kernel and I'm having some problems writing modules for it.
I've read these articles and still can't find the answer....
that's my module

//#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>

//MODULE_LICENSE("Dual BSD/GPL");

static int module_init(void)
{
printk("<1>Hello world 1.\n");
return 0;
}

static void module_exit(void)
{
printk("Goodbye world 1.\n");
}

and that's the makefile

ifneq ($(KERNELRELEASE),)
obj-m:= h.o

else
KDIR:= /lib/modules/$(shell uname -r)/build
PWD:= $(shell pwd)

default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
endif

When I compile it I get these
h.c:10: error: parse error before "__initcall_void"
h.c:10: error: parse error before "void"
h.c:19: error: parse error before "__exitcall_void"
h.c:19: error: redefinition of `__attribute_used__'
h.c:10: error: `__attribute_used__' previously defined here
h.c:19: error: parse error before "void"
make: *** [h] Error 1

any ideas why this happens ?

Driver porting: compiling external modules

Posted Nov 9, 2004 10:16 UTC (Tue) by madhavi_srinivas (guest, #25933) [Link] (2 responses)

Dear Kabbalah,

I am using SuSE 9.1 with 2.6.5-7.71 kernel. I have written small hello.c program here. It was working fine on my x86 machine.

#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>

MODULE_LICENSE("GPL");

static int hello_init(void)
{
printk("Hello World!\n");
return 0;
}

static void hello_exit(void)
{
printk("Good bye!\n");
}

module_init(hello_init);
module_exit(hello_exit);

For this the make file is as follows.

KDIR:=/lib/modules/$(shell uname -r)/build

obj-m:=hello.o

default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(RM) .*.cmd *.o *.ko -r .tmp*

It was working fine under x86 machine with 2.6.5-7.71 kernel version with SuSE Linux.

Regards,
Srinivas G

Driver porting: compiling external modules

Posted Nov 9, 2004 21:25 UTC (Tue) by kabbalah (guest, #25930) [Link] (1 responses)

thank you for your reply, I tried your code but when i compile it I still get plenty of errors:
cc hello.c -o hello
In file included from /usr/include/linux/sched.h:12,
from /usr/include/linux/module.h:9,
from hello.c:2:
/usr/include/linux/jiffies.h:16: error: parse error before "jiffies_64"
/usr/include/linux/jiffies.h:20: error: parse error before "get_jiffies_64"
In file included from /usr/include/linux/sched.h:21,
from /usr/include/linux/module.h:9,
from hello.c:2:
/usr/include/asm/mmu.h:13: error: field `sem' has incomplete type
In file included from /usr/include/linux/signal.h:4,
from /usr/include/linux/sched.h:25,
from /usr/include/linux/module.h:9,
from hello.c:2:
/usr/include/linux/list.h:604:2: warning: #warning "don't include kernel headers in userspace"
In file included from /usr/include/asm/siginfo.h:4,
from /usr/include/linux/signal.h:7,
from /usr/include/linux/sched.h:25,
from /usr/include/linux/module.h:9,
from hello.c:2:
/usr/include/asm-generic/siginfo.h:53: error: size of array `_pad' is too large
In file included from /usr/include/linux/sched.h:27,
from /usr/include/linux/module.h:9,
from hello.c:2:
/usr/include/linux/fs_struct.h:9: error: parse error before "rwlock_t"
/usr/include/linux/fs_struct.h:13: error: parse error before '}' token
In file included from /usr/include/linux/sched.h:29,
from /usr/include/linux/module.h:9,
from hello.c:2:
/usr/include/linux/completion.h:15: error: parse error before "wait_queue_head_t"
/usr/include/linux/completion.h: In function `init_completion':
/usr/include/linux/completion.h:26: error: dereferencing pointer to incomplete type
/usr/include/linux/completion.h:27: error: dereferencing pointer to incomplete type
In file included from /usr/include/linux/sched.h:30,
from /usr/include/linux/module.h:9,
from hello.c:2:
/usr/include/linux/pid.h: At top level:
/usr/include/linux/pid.h:18: error: field `task_list' has incomplete type
/usr/include/linux/pid.h:19: error: field `hash_chain' has incomplete type
/usr/include/linux/pid.h:24: error: field `pid_chain' has incomplete type
In file included from /usr/include/linux/module.h:9,
from hello.c:2:
/usr/include/linux/sched.h:93: error: parse error before "process_counts"
In file included from /usr/include/linux/sched.h:102,
from /usr/include/linux/module.h:9,
from hello.c:2:
/usr/include/linux/timer.h:10: error: field `entry' has incomplete type
hello.c:22: error: parse error before "__attribute_used__"
hello.c:22: warning: initialization makes integer from pointer without a cast
hello.c:22: warning: data definition has no type or storage class
hello.c:23: error: parse error before "__attribute_used__"
hello.c:23: error: redefinition of `__attribute_used__'
hello.c:22: error: `__attribute_used__' previously defined here
hello.c:23: warning: initialization makes integer from pointer without a cast
hello.c:23: warning: data definition has no type or storage class
hello.c:23:25: warning: no newline at end of file
make: *** [hello] Error 1

when i remove the #include <linux/modules.h> directive I get less errors but it still won't compile:
cc hello.c -o hello
hello.c:6: error: parse error before string constant
hello.c:6: warning: data definition has no type or storage class
hello.c:22: error: parse error before "__attribute_used__"
hello.c:22: warning: initialization makes integer from pointer without a cast
hello.c:22: warning: data definition has no type or storage class
hello.c:23: error: parse error before "__attribute_used__"
hello.c:23: error: redefinition of `__attribute_used__'
hello.c:22: error: `__attribute_used__' previously defined here
hello.c:23: warning: initialization makes integer from pointer without a cast
hello.c:23: warning: data definition has no type or storage class
make: *** [hello] Error 1

so that makes me pretty much desperate now :)
I guess I will have to forget about LKMs till the next Linux I install...
anyhow 10x again :)

Driver porting: compiling external modules

Posted Nov 26, 2004 9:44 UTC (Fri) by wuyanmin2 (guest, #26262) [Link]

My kernel version is 2.6.5, I complied a "Hello world" module,it's very simple but the size is more than 100K, however, most of the kernel modules in /lib/modules/ are less than 50K . What's the matter? How can I complie a smaller module??

Thanks

WU Yan-min

Driver porting: compiling external modules

Posted Dec 9, 2004 14:25 UTC (Thu) by meenaxi (guest, #26518) [Link]

hello,

First I would like to say Thanks for this article, it was very helpful!!
but unfortunately I am still facing some problems.

I am running Suse-9.1 Linux kernel and I want to write a loadable module.
I tried the helloworld program and it is working just fine, but then i
started with a simple character device driver program which is given as
example in Linux Module programming guide-2.6. but when i run the make
for this the whole make is running without error(there are a few
warnings) but the chardev.ko or chardev.o is not formed. i have no idea
why???.....any help would be appreciated!!

Thanks a dozen
meenaxi.

Driver porting: compiling external modules

Posted Feb 3, 2005 3:28 UTC (Thu) by fleetinglife (guest, #27641) [Link] (1 responses)

I am struggling to build my first linux driver module.

I have four .c files in my source directroy, the file file_mod.c is the one contains the main code of module. I use the Makefile as following:

obj-m := file_mod.o
module-objs := file1.o file2.o file3.o file_mod.o

and type make command as following:

make -C /usr/src/linux-2.6.0 SUBDIRS=$PWD modules

It can build the file_mod.ko successfully, but I got a list of warning messages, said some functions called in file_mod.ko UNDEFINED! These functions are defined in file1.c, file2.c, file3.c.

How to solve this problem? Any suggestion will be appreciated.

Driver porting: compiling external modules

Posted Feb 3, 2005 9:30 UTC (Thu) by fleetinglife (guest, #27641) [Link]

I see, The module-objs should be modified into file_mod-objs.

Driver porting: compiling external modules

Posted Feb 4, 2005 6:51 UTC (Fri) by fleetinglife (guest, #27641) [Link]

I built my driver successfully in kernel 2.6.0,
BUT when I insmod the .ko file, I got
"no module found in object
Error inserting 'name.ko' : -1 Invalid module format"

Who can tell me, where can I get docs about module format in kernel 2.6.0?

Driver porting: compiling external modules

Posted Mar 22, 2005 17:40 UTC (Tue) by krash (guest, #2689) [Link]

To save the uninitiated from pulling too much hair out:

In the example:

obj-m := module.o
module-objs := file1.o file2.o

It might be clearer for it to read something like this:

obj-m := name-of-module.o
name-of-module-objs := file1.o file2.o

to stress that in the original module-objs, module is in fact the name of the module.

Unable to compile external modules in 2.6-9.5 kernel

Posted Mar 30, 2005 19:31 UTC (Wed) by muraligadela (guest, #28875) [Link]

Hi
I am porting simple device driver from 2.4 kernel to 2.6.9-5. I followed the instructions in the "compiling external modules" articles posted in the lwn.net. I am still unable to compile and the compiler errror received is
awk: cmd. line:2 fatal: cannot open file `test.h` for reading (no such file or directory). I have added the location of test.h to CFLAGS varaible and also to EXTRA_CFLAGS in the makefile.

Any help is appreciated.

Driver porting: loading external modules

Posted Dec 15, 2005 6:41 UTC (Thu) by nusrath (guest, #34559) [Link]

When i load the module using insmod the following error is hown

insmod: can't read 'test.ko': Stale NFS file handle

where test.c is my module name

Please help th an answer

How to compile an external driver using a non-default makefile name?

Posted Jan 9, 2007 0:27 UTC (Tue) by Linux_v (guest, #42654) [Link]

Hi,

I used to be able to compile an external device driver using the command in 2.4 kernel:

make -f mymakefile

But in 2.6 kernel, the command doesn't work.

1) With this command
$(MAKE) -C $(KDIR) M=$(PWD) modules

I saw the following error:

[root@pgenlx11 platypus]# make -f mymakefile
make -C /lib/modules/2.6.11.1/build M=/my-correct-ldd-dir modules
make[1]: Entering directory `/usr/src/kernels/linux-2.6.11.1'
scripts/Makefile.build:13: /my-correct-ldd-dir/Makefile: No such file or directory
make[2]: *** No rule to make target `/my-correct-ldd-dir/Makefile'. Stop.
make[1]: *** [_module_/my-correct-ldd-dir] Error 2
make[1]: Leaving directory `/usr/src/kernels/linux-2.6.11.1'
make: *** [all] Error 2

From reading the porting article, I've learnt that the 2.6 kernel build process goes through two passes for building an external device driver. The second pass is where it does the building job. But it looks like it was looking for a default makefile, named Makefile, even though, "-f mymakefile" is given at the make command.

2) with this command
$(MAKE) -C $(KDIR) M=$(PWD) -f mymakefile modules

I saw this the following error: basically, the build process try to look for mymakefile in the linux source tree, instead of the the dir defined by M=$(PWD).

[root@pgenlx11 platypus]# make -f mymakefile
make -C /lib/modules/2.6.11.1/build M=/my-correct-ldd-path modules -f mymakefile
make[1]: Entering directory `/usr/src/kernels/linux-2.6.11.1'
make[1]: mymakefile: No such file or directory
make[1]: *** No rule to make target `mymakefile'. Stop.
make[1]: Leaving directory `/usr/src/kernels/linux-2.6.11.1'
make: *** [all] Error 2

3) case 1, "make -f mymakefile", will work fine if I add the following symbolic link:
ln -s mymakefile Makefile

I tried this just to test if there is other problem for the make. It's not a solution for me.

I saw the linux build script uses "make -f " in some case. it look like it should work in 2.6 as well. What have I missed?

Thanks in advance!

Driver porting: compiling external modules

Posted Apr 13, 2007 22:04 UTC (Fri) by ffo (guest, #44654) [Link]

The information is misleading as far as I can judge by the number of posts. Here is my contribution.

If your module is made of f1.c f2.c and f3.c then your Makefile should look like:
obj-m:= module.o
module-objs := f1.o f2.o f3.o

you will be able to load your module by insmod ./module.ko.
Note that module.o is NOT associated to any .c, it is just the product name of the compilation.

Now to take other names, misleading ones...
If your module is made of interceptor.c frame.c and packet.c then your Makefile should look like:
obj-m:= module.o
module-objs := interceptor.o frame.o packet.o
or
obj-m:= interceptor_module.o
interceptor_module-objs := interceptor.o frame.o packet.o

if your Makefile is
obj-m:= interceptor.o
interceptpr-objs := interceptor.o frame.o packet.o

it will report a circular depdendency and not compile interceptor.c

or

obj-m:= interceptor.o
interceptor-objs := frame.o packet.o

it will NOT compile interceptor.c, produce an interceptor.ko (bad), emit some warnings about undefined references. Trying to load it by insmod will produce errors about unresolved stuff.

Again, the name after obj-m does NOT correspond to any .c but to the name of the .ko you want to obtain from make. The fact that it is named with a .o extension is very misleading... it should have been .ko IHMO.

This may sound obvious for the kernel development community, but for newbies like me, this is way different!

Testing the usb-skeleton.c

Posted Apr 26, 2010 12:54 UTC (Mon) by saurabh8189 (guest, #65637) [Link]

Thanks for the article I have been following your book for a long time. I am working on usb-skeleton.c driver for the pen(say usb flash drive :)) drive on kernel 2.6.32.
I am able to load usb-skeleton module to kernel using insmod but every time I plug-in my pen drive it takes usb-storage module.
Due to this I am not able to test my first driver.
I asked various forums but got no results now you are the one who guided and can guide
Here is a link to my question
http://www.linuxforums.org/forum/linux-kernel/161862-how-...

Waiting for the reply!!


Copyright © 2003, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds