Driver porting: compiling external modules
This article is part of the LWN Porting Drivers to 2.6 series. |
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.oIn 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 modulesWhere /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.
Posted Feb 6, 2003 6:05 UTC (Thu)
by rfunk (subscriber, #4054)
[Link] (5 responses)
I believe there was some minor controversy on the linux-kernel mailing list recently over which location is more appropriate.
Posted Feb 6, 2003 14:44 UTC (Thu)
by corbet (editor, #1)
[Link] (3 responses)
Posted Oct 27, 2004 8:25 UTC (Wed)
by rashminivarthy (guest, #25682)
[Link] (2 responses)
Posted Oct 27, 2004 10:17 UTC (Wed)
by rashminivarthy (guest, #25682)
[Link] (1 responses)
Posted Jul 18, 2005 11:38 UTC (Mon)
by kalou (guest, #31046)
[Link]
your kernel is not module enabled,
Sincere Regards,
Olivier
Posted Sep 14, 2005 23:45 UTC (Wed)
by mraviraj (guest, #32463)
[Link]
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),)
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 ..
Posted Feb 6, 2003 11:03 UTC (Thu)
by raarts (guest, #4184)
[Link]
Ron Arts
Posted Feb 6, 2003 18:35 UTC (Thu)
by sjmadsen (guest, #4035)
[Link] (6 responses)
Even if we were building on Linux, it's unlikely that the OS on the build machine is going to match the embedded environment.
Posted Feb 6, 2003 21:02 UTC (Thu)
by Peter (guest, #1127)
[Link]
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.
Posted Feb 7, 2003 15:50 UTC (Fri)
by dwmw2 (subscriber, #2063)
[Link] (4 responses)
Note also that the article is somewhat misleading -- the Makefile fragment > KERNELDIR = /usr/src/linux ... 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.
Posted Mar 3, 2005 10:48 UTC (Thu)
by mhb (guest, #28187)
[Link] (3 responses)
Posted Oct 14, 2005 0:02 UTC (Fri)
by msprauve (guest, #33084)
[Link] (1 responses)
Posted May 2, 2006 13:59 UTC (Tue)
by DeferX (guest, #37486)
[Link]
By
Posted Nov 10, 2005 22:02 UTC (Thu)
by urs (guest, #33777)
[Link]
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
Posted Feb 6, 2003 21:02 UTC (Thu)
by pradu (guest, #4323)
[Link] (5 responses)
Or I am missing something?
Posted Feb 8, 2003 0:28 UTC (Sat)
by Peter (guest, #1127)
[Link] (2 responses)
There are a few possibilities here:
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.
Posted Feb 13, 2003 22:53 UTC (Thu)
by mmarq (guest, #2332)
[Link] (1 responses)
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?????????
Posted Jul 22, 2005 16:55 UTC (Fri)
by qu1j0t3 (guest, #25786)
[Link]
Posted Feb 8, 2003 15:12 UTC (Sat)
by jschrod (subscriber, #1646)
[Link]
Cheers, Joachim
Posted Mar 30, 2004 15:46 UTC (Tue)
by linuxdev (guest, #20542)
[Link]
Posted Feb 13, 2003 0:17 UTC (Thu)
by pedretti (guest, #9593)
[Link] (1 responses)
Posted Apr 30, 2003 20:19 UTC (Wed)
by krobidea (guest, #10955)
[Link]
- 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?
Posted Feb 13, 2004 14:25 UTC (Fri)
by grisu1976 (guest, #19435)
[Link]
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
Posted Feb 19, 2004 20:13 UTC (Thu)
by jdeas (guest, #19608)
[Link]
Compiling using a standard make command and Makefile
Posted Mar 9, 2004 18:04 UTC (Tue)
by liangjz (guest, #20079)
[Link]
In the 2.4 driver, I simply had a build rule that said assembly_stuff.o: assembly_stuff.asm 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?
Posted Mar 10, 2004 21:53 UTC (Wed)
by madmax1984 (guest, #20101)
[Link]
after quite a bit of googleing i found the hope this is useful
Posted Jul 11, 2004 6:23 UTC (Sun)
by kcannon (guest, #4867)
[Link] (2 responses)
Cheers
Posted Jul 12, 2004 2:20 UTC (Mon)
by kcannon (guest, #4867)
[Link] (1 responses)
Posted Jul 31, 2005 20:42 UTC (Sun)
by qu1j0t3 (guest, #25786)
[Link]
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?
Posted Jul 12, 2004 13:54 UTC (Mon)
by corbet (editor, #1)
[Link] (1 responses)
Posted Aug 26, 2004 17:10 UTC (Thu)
by r2b2lewis (guest, #24285)
[Link]
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?
Posted Jul 15, 2004 6:12 UTC (Thu)
by Ryu_Tenchi (guest, #23057)
[Link] (2 responses)
int init_module(void){printk("<1>Hello, world\n"); return 0;} makefile: command entered: output: any help would be great, thanks^_^
Posted Jul 22, 2004 15:00 UTC (Thu)
by disq (guest, #23313)
[Link] (1 responses)
Posted Jul 23, 2004 23:54 UTC (Fri)
by Ryu_Tenchi (guest, #23057)
[Link]
Posted Jul 23, 2004 19:04 UTC (Fri)
by ajnicholson (guest, #23376)
[Link] (1 responses)
I made the following Makefile: yet when I compile it by running: It issues the following error: Any ideas? I thought the "module-objs" line was supposed to indicate which files comprise the complete module...
Posted Jul 25, 2004 17:09 UTC (Sun)
by amishdave (guest, #10005)
[Link]
Posted Jul 26, 2004 17:37 UTC (Mon)
by anikami1 (guest, #23453)
[Link]
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?
Posted Aug 9, 2004 21:22 UTC (Mon)
by cpp9999 (guest, #23889)
[Link] (2 responses)
sample main.c file
# make -C /usr/src/linux-2.6.7 SUBDIRS=$(PWD) modules
Obviously when I am in /usr/src/linux-2.6.7 I cannot see local.h.
Any ideas how to fix this? Thanks
Posted Oct 15, 2004 16:48 UTC (Fri)
by geoff_o (guest, #25424)
[Link] (1 responses)
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
Posted Oct 20, 2004 5:24 UTC (Wed)
by amcrae (guest, #25501)
[Link]
I needed to do the same thing. You can do this with the EXTRA_CFLAGS Makefile variable:
...
Cheers,
Posted Aug 24, 2004 18:05 UTC (Tue)
by cidis (guest, #24232)
[Link]
Posted Sep 2, 2004 20:30 UTC (Thu)
by klaus.hitschler@gmx.de (guest, #24472)
[Link]
make -C /usr/src/linux M=/home/klaus/work/peak/peak-linux-driver/driver V=0 modules
I wondered about the line
P.S. pcan.ko is generated and is works perfectly.
Klaus
Posted Nov 9, 2004 0:57 UTC (Tue)
by kabbalah (guest, #25930)
[Link] (3 responses)
//#include <linux/module.h>
//MODULE_LICENSE("Dual BSD/GPL");
static int module_init(void)
static void module_exit(void)
and that's the makefile
ifneq ($(KERNELRELEASE),)
else
default:
When I compile it I get these
any ideas why this happens ?
Posted Nov 9, 2004 10:16 UTC (Tue)
by madhavi_srinivas (guest, #25933)
[Link] (2 responses)
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>
MODULE_LICENSE("GPL");
static int hello_init(void)
static void hello_exit(void)
module_init(hello_init);
For this the make file is as follows.
KDIR:=/lib/modules/$(shell uname -r)/build
obj-m:=hello.o
default:
It was working fine under x86 machine with 2.6.5-7.71 kernel version with SuSE Linux.
Regards,
Posted Nov 9, 2004 21:25 UTC (Tue)
by kabbalah (guest, #25930)
[Link] (1 responses)
when i remove the #include <linux/modules.h> directive I get less errors but it still won't compile:
so that makes me pretty much desperate now :)
Posted Nov 26, 2004 9:44 UTC (Fri)
by wuyanmin2 (guest, #26262)
[Link]
Thanks
WU Yan-min
Posted Dec 9, 2004 14:25 UTC (Thu)
by meenaxi (guest, #26518)
[Link]
Posted Feb 3, 2005 3:28 UTC (Thu)
by fleetinglife (guest, #27641)
[Link] (1 responses)
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
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.
Posted Feb 3, 2005 9:30 UTC (Thu)
by fleetinglife (guest, #27641)
[Link]
Posted Feb 4, 2005 6:51 UTC (Fri)
by fleetinglife (guest, #27641)
[Link]
Who can tell me, where can I get docs about module format in kernel 2.6.0?
Posted Mar 22, 2005 17:40 UTC (Tue)
by krash (guest, #2689)
[Link]
In the example:
obj-m := module.o
It might be clearer for it to read something like this:
obj-m := name-of-module.o
to stress that in the original module-objs, module is in fact the name of the module.
Posted Mar 30, 2005 19:31 UTC (Wed)
by muraligadela (guest, #28875)
[Link]
Any help is appreciated.
Posted Dec 15, 2005 6:41 UTC (Thu)
by nusrath (guest, #34559)
[Link]
insmod: can't read 'test.ko': Stale NFS file handle
where test.c is my module name
Please help th an answer
Posted Jan 9, 2007 0:27 UTC (Tue)
by Linux_v (guest, #42654)
[Link]
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
I saw the following error:
[root@pgenlx11 platypus]# make -f mymakefile
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.
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).
3) case 1, "make -f mymakefile", will work fine if I add the following symbolic link:
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!
Posted Apr 13, 2007 22:04 UTC (Fri)
by ffo (guest, #44654)
[Link]
If your module is made of f1.c f2.c and f3.c then your Makefile should look like:
you will be able to load your module by insmod ./module.ko.
Now to take other names, misleading ones...
if your Makefile is
it will report a circular depdendency and not compile interceptor.c
or
obj-m:= interceptor.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!
Posted Apr 26, 2010 12:54 UTC (Mon)
by saurabh8189 (guest, #65637)
[Link]
Waiting for the reply!!
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/:Driver porting: compiling external modules
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
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
hello, Path to the kernel source
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
hello unable to use ksyms on 2.6 kernel
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
Hi rashminivarthy,unable to use ksyms on 2.6 kernel
obviously.
We have been using linux 2.4 for the development and recently started supporting 2.6.Driver porting: compiling external modules
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
Raviraj
Thanks for this article. Driver porting: compiling external modules
This is why I subscribe to LWN.
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.What about cross-compilation?
What about cross-compilation?
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.
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:@What about cross-compilation?
make KDIR=/local/arm-kernel CROSS_COMPILE=arm-linux-gnu-
> CFLAGS = -D__KERNEL__ -DMODULE -I$(KERNELDIR)/include -O
>
> all: module.o
I have tried this on the simple hello.c module. What about cross-compilation?
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]#
Did anyone develop a resolution to this problem?What about cross-compilation?
Tray thisWhat about cross-compilation?
make CROSS_COMPILE=ppc_6xx- ARCH=ppc
It's work
defer
You should callWhat about cross-compilation?
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.Hardware vendor supplied modules
Hardware vendor supplied modules
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.
>freeze the kernel/module interface, somehaw nullify or abstract away all differences...Hardware vendor supplied modules
IT'S YOUR IMAGINATIONHardware vendor supplied modules
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.Hardware vendor supplied modules
I have one moduel as test.c and i want to comiple and load into 2.6 kernelHow to compile linux driver as loadable module
I want to know options for comiling.
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
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:Driver porting: compiling external modules
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...Driver porting: compiling external modules
I am new to this.Driver porting: compiling external modules
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.
does not understand (can not find) 'obj-m' . Is my basic way of compiling
now wrong?
obj-m:=Mydriver.o give the above error
I'm trying to port a 2.4 driver to 2.6 and am having trouble getting the makefile to call nasm.Driver porting: compiling external modules
nasm $(NASM_FLAGS) assembly_stuff.asm
I tried doing the same thing with the 2.6 driver and added
i encountered the following problem when tryingproblem when compiling external modules
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.
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)
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.Driver porting: compiling external modules
-Kipp
Never mind... my mistake. You replace the default value of PWD with the result of $(shell pwd).
Driver porting: compiling external modules
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 :-)problem with $(CURDIR)
SUBDIRS= vs M=
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=
I am running on SuSE 9.1 (2.6.4-52-smp).SUBDIRS= vs M=
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...Driver porting: compiling external modules
code:
//main.c
#include <linux/module.h>
#include <linux/config.h>
#include <linux/init.h>
void cleanup_module(void) {printk("<1>Goodbye cruel world\n");}
objs-m := main.o
make -C /usr/src/linux M=`pwd` modules
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'
apparently it's "obj-m", not "objs-m"Driver porting: compiling external modules
*^^* thank you, i feel stupid now lol, but it works and I learned from it Driver porting: compiling external modules
so,thanks again^_^
I have an external module comprised of 3 .c files...Multi-file modules--help!
----------------------------------
obj-m := foo.o
module-objs := file1.c file2.c file3.c
-----------------------------------
make -C /usr/src/linux SUBDIRS=$PWD modules
make[2]: *** No rule to make target '/usr/src/foo.c', needed by '/usr/src/foo/foo.o'. Stop.
I think you need to replace module-objs with foo-objs...Multi-file modules--help!
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.Driver porting: compiling external modules
I'm having trouble compiling an external module under the following dir structureDriver porting: compiling external modules with local includes
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
#include "dirA/local.h"
main ()
{
/* some code */
}
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
I've also been searching for the answer to this question.Driver porting: compiling external modules with local includes
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.)Driver porting: compiling external modules with local includes
obj-m += file.o
EXTRA_CFLAGS += -I$(obj)/../include
AMc
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
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:Driver porting: compiling external 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'
"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?
hi thereDriver porting: compiling external modules
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/kernel.h>
#include <linux/init.h>
{
printk("<1>Hello world 1.\n");
return 0;
}
{
printk("Goodbye world 1.\n");
}
obj-m:= h.o
KDIR:= /lib/modules/$(shell uname -r)/build
PWD:= $(shell pwd)
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
endif
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
Dear Kabbalah,Driver porting: compiling external modules
#include <linux/module.h>
#include <linux/kernel.h>
{
printk("Hello World!\n");
return 0;
}
{
printk("Good bye!\n");
}
module_exit(hello_exit);
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(RM) .*.cmd *.o *.ko -r .tmp*
Srinivas G
thank you for your reply, I tried your code but when i compile it I still get plenty of errors:Driver porting: compiling external modules
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
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
I guess I will have to forget about LKMs till the next Linux I install...
anyhow 10x again :)
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??Driver porting: compiling external modules
hello, Driver porting: compiling external modules
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.
I am struggling to build my first linux driver module.Driver porting: compiling external modules
module-objs := file1.o file2.o file3.o file_mod.o
I see, The module-objs should be modified into file_mod-objs.Driver porting: compiling external modules
I built my driver successfully in kernel 2.6.0,Driver porting: compiling external modules
BUT when I insmod the .ko file, I got
"no module found in object
Error inserting 'name.ko' : -1 Invalid module format"
To save the uninitiated from pulling too much hair out:Driver porting: compiling external modules
module-objs := file1.o file2.o
name-of-module-objs := file1.o file2.o
HiUnable to compile external modules in 2.6-9.5 kernel
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.
When i load the module using insmod the following error is hownDriver porting: loading external modules
Hi,How to compile an external driver using a non-default makefile name?
$(MAKE) -C $(KDIR) M=$(PWD) modules
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
2) with this command
$(MAKE) -C $(KDIR) M=$(PWD) -f mymakefile modules
[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
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.
The information is misleading as far as I can judge by the number of posts. Here is my contribution.Driver porting: compiling external modules
obj-m:= module.o
module-objs := f1.o f2.o f3.o
Note that module.o is NOT associated to any .c, it is just the product name of the compilation.
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
obj-m:= interceptor.o
interceptpr-objs := interceptor.o frame.o packet.o
interceptor-objs := frame.o packet.o
Testing the usb-skeleton.c
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-...