You are on page 1of 27

Open Source For You

December 1, 2010 132 comments

Device Drivers, Part 2: Writing Your First Linux Driver in the


Classroom

Share

Tweet

+1

Mail

This article, which is part of the series on Linux device drivers, deals with the concept of
dynamically loading drivers, first writing a Linux driver, before building and then loading it.
Shweta and Pugs reached their classroom late, to find their professor already in the middle
of a lecture. Shweta sheepishly asked for his permission to enter. An annoyed Professor
Gopi responded, Come on! You guys are late again; what is your excuse, today?

Pugs hurriedly replied that they had been discussing the very topic for that days class
device drivers in Linux. Pugs was more than happy when the professor said, Good! Then
explain about dynamic loading in Linux. If you get it right, the two of you are excused! Pugs
knew that one way to make his professor happy was to criticise Windows.
He explained, As we know, a typical driver installation on Windows needs a reboot for it to
get activated. That is really not acceptable; suppose we need to do it on a server? Thats
where Linux wins. In Linux, we can load or unload a driver on the fly, and it is active for use
instantly after loading. Also, it is instantly disabled when unloaded. This is called dynamic
loading and unloading of drivers in Linux.
This impressed the professor. Okay! Take your seats, but make sure you are not late
again. The professor continued to the class, Now you already know what is meant by
dynamic loading and unloading of drivers, so Ill show you how to do it, before we move on
to write our first Linux driver.

Dynamically loading drivers


These dynamically loadable drivers are more commonly called modules and built into
individual files with a .ko (kernel object) extension. Every Linux system has a standard
place under the root of the file system ( /) for all the pre-built modules. They are organised
similar to the kernel source tree structure, under /lib/modules/<kernel_version>/kernel,
where <kernel_version> would be the output of the command uname -ron the system, as
shown in Figure 1.

Figure 1: Linux pre-built modules

To dynamically load or unload a driver, use these commands, which reside in the /sbin
directory, and must be executed with root privileges:
lsmod

lists currently loaded modules

insmod <module_file>
modprobe <module>

inserts/loads the specified module file

inserts/loads the module, along with any

dependencies
rmmod <module>

removes/unloads the module

Lets look at the FAT filesystem-related drivers as an example. Figure 2 demonstrates this
complete process of experimentation. The module files would be fat.ko, vfat.ko, etc., in
the fat ( vfat for older kernels) directory under /lib/modules/`uname -r`/kernel/fs. If
they are in compressed .gz format, you need to uncompress them with gunzip, before
you can insmodthem.

Figure 2: Linux module operations

The vfat module depends on the fat module, so fat.ko needs to be loaded first. To
automatically perform decompression and dependency loading, use modprobe instead.
Note that you shouldnt specify the .ko extension to the modules name, when using the
modprobe command. rmmod is

used to unload the modules.

Our first Linux driver


Before we write our first driver, lets go over some concepts. A driver never runs by itself. It
is similar to a library that is loaded for its functions to be invoked by a running application.
It is written in C, but lacks a main() function. Moreover, it will be loaded/linked with the
kernel, so it needs to be compiled in a similar way to the kernel, and the header files you
can use are only those from the kernel sources, not from the standard /usr/include.
One interesting fact about the kernel is that it is an object-oriented implementation in C, as
we will observe even with our first driver. Any Linux driver has a constructor and a

destructor. The modules constructor is called when the module is successfully loaded into
the kernel, and the destructor when rmmod succeeds in unloading the module. These two
are like normal functions in the driver, except that they are specified as the init and exit
functions, respectively, by the macros module_init() and module_exit(), which are
defined in the kernel header module.h.
/* ofd.c Our First Driver code */
#include <linux/module.h>
#include <linux/version.h>
#include <linux/kernel.h>

static int __init ofd_init(void) /* Constructor */


{
printk(KERN_INFO "Namaskar: ofd registered");
return 0;
}

static void __exit ofd_exit(void) /* Destructor */


{
printk(KERN_INFO "Alvida: ofd unregistered");
}

module_init(ofd_init);
module_exit(ofd_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Anil Kumar Pugalia <email_at_sarika-pugs_dot_com>");
MODULE_DESCRIPTION("Our First Driver");

Given above is the complete code for our first driver; lets call it ofd.c. Note that there is
no stdio.h (a user-space header); instead, we use the analogous kernel.h (a kernel
space header). printk() is the equivalent of printf(). Additionally, version.h is
included for the module version to be compatible with the kernel into which it is going to be
loaded. The MODULE_* macros populate module-related information, which acts like the
modules signature.

Building our first Linux driver


Once we have the C code, it is time to compile it and create the module file ofd.ko. We use
the kernel build system to do this. The following Makefile invokes the kernels build
system from the kernel source, and the kernels Makefile will, in turn, invoke our first
drivers Makefile to build our first driver.
To build a Linux driver, you need to have the kernel source (or, at least, the kernel headers)
installed on your system. The kernel source is assumed to be installed at /usr/src/linux.
If its at any other location on your system, specify the location in the KERNEL_SOURCE
variable in this Makefile.
# Makefile makefile of our first driver

# if KERNELRELEASE is defined, we've been invoked from the


# kernel build system and can use its language.
ifneq (${KERNELRELEASE},)
obj-m := ofd.o
# Otherwise we were called directly from the command line.
# Invoke the kernel build system.
else
KERNEL_SOURCE := /usr/src/linux
PWD := $(shell pwd)
default:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules

clean:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean
endif

With the C code ( ofd.c) and Makefile ready, all we need to do is invoke make to build our
first driver ( ofd.ko).
$ make
make -C /usr/src/linux SUBDIRS=... modules

make[1]: Entering directory `/usr/src/linux'


CC [M] .../ofd.o
Building modules, stage 2.
MODPOST 1 modules
CC

.../ofd.mod.o

LD [M] .../ofd.ko
make[1]: Leaving directory `/usr/src/linux'

Summing up
Once we have the ofd.ko file, perform the usual steps as the root user, or with sudo.
# su
# insmod ofd.ko
# lsmod | head -10

lsmod should

show you the ofd driver loaded.

While the students were trying their first module, the bell rang, marking the end of the
session. Professor Gopi concluded, Currently, you may not be able to observe anything
other than the lsmod listing showing the driver has loaded. Wheres the printk output
gone? Find that out for yourselves, in the lab session, and update me with your findings.
Also note that our first driver is a template for any driver you would write in Linux. Writing a
specialised driver is just a matter of what gets filled into its constructor and destructor. So,
our further learning will be to enhance this driver to achieve specific driver functionalities.

Related Posts:
Device Drivers, Part 17: Module Interactions
Jumpstart Linux Kernel Module Programming
A Simple guide to building your own Linux Kernel
Whats Up in Linux Graphicstopia Lately
The Semester Project-IV File Systems: Formatting a Pen

Previous Post
Kernel Tracing With Ftrace, Part 2

Next Post
Secure Upload Methods In PHP

montuviky
Away-some post will love to read all (and more :) )
anil_pugalia
Thanks for the appreciation. Go ahead & read all 24 are out in hard form.
vivek
when I run make command, i got the following error
make: Nothing to be done for `default.
I guess it could be the problem because of KERNEL_SOURCE. In my make file i have set
KERNEL_SOURCE as follows:
KERNEL_SOURCE := /usr/src/linux-headers-2.6.38-10
the_summer
I had the same problem.
For me the problem was copy and pasting the Makefile.
Make sure that in front of the ${MAKE} commands is an tab and not multiple spaces.
After replacing spaces with tabs it worked for me.
avik
thanks for the solution
the_summer
Just noticed:
I dont know if you use *buntu. But KERNEL_SOURCE := /usr/src/linux-headers-2.6.38-10
produces some errors.
KERNEL_SOURCE := /usr/src/linux-headers-2.6.38-10-generic seems to work.
Raghu
# Use this file as your Makefile
obj-m +=ofd.o
ofd-objs := ofd.o
all:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules


clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Raghu
add #include in ofd.c and remove 2nd line from above
Makefile and compile..
montuviky
I also had the same problem.
So i manually complied it.
make was like
obj-m := ofd.o
and compilation was :
make -C /usr/src/linux-headers-2.6.38-10 SUBDIRS=$PWD modules.
Teja
Thanx bro
akash
hey frnd what does this modules word signify in above make command .
do we need to put module path replacing this or directly run above cmmnd as it is reply pls
http://twitter.com/anil_pugalia Anil Pugalia
Its directly the above command as is.
Rakesh Babu
Rakesh babu
Dynamically load or unload a driver means..
http://twitter.com/anil_pugalia Anil Pugalia
Read the previous article http://www.opensourceforu.com/2010/11/understanding-linuxdevice-drivers/
Curious_Furious
Where should the C program be placed? In which directory?

In your Makefile, what will be the pwd?


anil_pugalia
In any folder of its own.
PeterHiggs
i liked it :) thanks pugs
http://www.facebook.com/anil.pugalia Anil Pugalia
You are welcome
PeterHiggs
hi pugs, all is well. But I need to know a little more about the Makefile syntax and how it
works line by line I cant digest some code which is alien to me. I would be grateful if you
can throw some light on this.
khamar
wats answer to ur auestion?
http://www.facebook.com/anil.pugalia Anil Pugalia
Try to read up info make
explorer
when ubuntu is installed on desktop
what does /usr/src/ dir contains ? i.e kerner source OR kernel headers?
in my pc linux-headers-2.6.38-10-generic and linux-headers-2.6.38-10 directories are there.
what are they.? they dont have any c source . if they are headers why there are two
directories i.e what is generic means?
anil_pugalia
They are headers. Sources can also be installed in the same folder using apt-get install linuxsources. Two headers are just the two variants created by the particular distro ubuntu here
calixto
its apt-get linux-source
calixto
sorry apt-get install linux-source

anil_pugalia
Thanks for the correction. I also corrected it.
akash
how to check kernel location
http://twitter.com/anil_pugalia Anil Pugalia
I understand you mean the kernel source location. Typically, it would be under /usr/src (linux
or build or ). Also, it may not be installed by default. So, you may have to install it first.
akash
root@ubuntu:/usr/src# make -C /usr/src/linux-headers-3.2.0-29 SUBDIRS=$PWD modules.
I run above command & found this error pls help as soon as possible .. pls
make: Entering directory `/usr/src/linux-headers-3.2.0-29
ERROR: Kernel configuration is invalid.
include/generated/autoconf.h or include/config/auto.conf are missing.
Run make oldconfig && make prepare on kernel src to fix it.
akash
pls reply m waiting
http://twitter.com/anil_pugalia Anil Pugalia
So, as it is mentioned in the above error, do make oldconfig after going into the linuxheaders-3.2.0.29 folder.
akash
i was trying to build my driver i got this error :root@ubuntu:/home/ayush/device# make -C /usr/src/linux-headers-3.2.0-29-generic-pae
SUBDIRS=$PWD modules
make: Entering directory `/usr/src/linux-headers-3.2.0-29-generic-pae
Building modules, stage 2.
MODPOST 0 modules
make: Leaving directory `/usr/src/linux-headers-3.2.0-29-generic-pae
Pls reply any solution thnx in advance :)
http://twitter.com/anil_pugalia Anil Pugalia

I believe you current directory /home/ayush/device contains the C files which you are trying
to build. And your current kernel configuration is set to build & use drivers, i.e. grep
CONFIG_MODULE /usr/src/linux-headers-3.2.0-29-generic-pae/.config should not be not set
or empty.
janakiram
I am also facing same problem as mentioned.. its showing
CONFIG_MODULES=y
# CONFIG_MODULE_FORCE_LOAD is not set
CONFIG_MODULE_UNLOAD=y
# CONFIG_MODULE_FORCE_UNLOAD is not set
CONFIG_MODULE_SRCVERSION_ALL=y
http://twitter.com/anil_pugalia Anil Pugalia
Use a makefile as suggested in the article. Basically you need the obj-m line for a module
to be built, i.e. obj-m := ofd.o. So, just giving make on command line may not work.
satheesaran
Great example to start with. Thanks for the article :) Motivates to read more
http://twitter.com/anil_pugalia Anil Pugalia
Those words are really inspiring for me.
yogesh
why every function in the device driver is named as static. As static fuction are not visible
outside of the file scope. Then, How these driver function gets called by user space
application..
anil_pugalia
You are correct that when static, functions are not visible outside of the file scope, but only
by their names. Note that, they could be still accessed anywhere by their addresses, and
thats what we do with all these driver functions populate their addresses into the struct
file_operations and make it available to VFS & hence userspace, through the struct cdev.
manoj
device drivers and its sources of Linux
tushar
when i do make this error comes
please tell solution

sai@ubuntu:~/tushar$ make
make -C /usr/src/linux-headers-3.5.0-17 SUBDIRS=/home/sai/tushar modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17
ERROR: Kernel configuration is invalid.
include/generated/autoconf.h or include/config/auto.conf are missing.
Run make oldconfig && make prepare on kernel src to fix it.
WARNING: Symbol version dump /usr/src/linux-headers-3.5.0-17/Module.symvers
is missing;
modules will have no dependencies and modversions.
Building modules, stage 2.
/usr/src/linux-headers-3.5.0-17/scripts/Makefile.modpost:42:
include/config/auto.conf: No such file or directory
make[2]: *** No rule to make target `include/config/auto.conf. Stop.
make[1]: *** [modules]
Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17
make: *** [default] Error 2
tushar
please reply i am waiting
http://twitter.com/anil_pugalia Anil Pugalia
Do as the message says: make oldconfig
And then, make modules_prepare
Both in the linux-headers folder.
And then retry.
tushar
1> when i do make oldconfig in linux-headers-3.5..0-17 folder i got this error
HOSTCC scripts/basic/fixdep
scripts/basic/fixdep.c:433:1: fatal error: opening dependency file scripts/basic/.fixdep.d:

Permission denied
compilation terminated.
make[1]: *** [scripts/basic/fixdep] Error 1
make: *** [scripts_basic] Error 2
tushar@Sai:/usr/src/linux-headers-3.5.0-17$
2> and after that if i do make modules_prepare i got this error
HOSTCC scripts/basic/fixdep
scripts/basic/fixdep.c:433:1: fatal error: opening dependency file scripts/basic/.fixdep.d:
Permission denied
compilation terminated.
make[2]: *** [scripts/basic/fixdep] Error 1
make[1]: *** [scripts_basic] Error 2
make: *** No rule to make target `modules_prepare. Stop.
tushar@Sai:/usr/src/linux-headers-3.5.0-17$
i am using ubuntu 12.10
kernel version 3.5.0-17-generic
PLZ PROVIDE SOLUTION SIR
tushar
plz reply
http://twitter.com/anil_pugalia Anil Pugalia
Use sudo, yaar.
sudo make oldconfig
tushar
1)when i do sudo make oldconfig then it is fine
2) but when i do sudo make modules_prepare i got fooliowing error
tushar@Sai:/usr/src/linux-headers-3.5.0-17$ sudo make modules_prepare
scripts/kconfig/conf silentoldconfig Kconfig
make[1]: *** No rule to make target `/usr/src/linux-headers-3.5.0-

17/arch/x86/syscalls/syscall_32.tbl, needed by
`arch/x86/syscalls/../include/generated/asm/unistd_32.h. Stop.
make: *** [archheaders] Error 2
tushar@Sai:/usr/src/linux-headers-3.5.0-17$
pls tell solution sir
http://twitter.com/anil_pugalia Anil Pugalia
How about sudo make prepare?
If not, then some issue with the headers package installation.
Sunil S
hi.. i am facing the same problem Tushar was facing and got exact same error. I desperately
want to move forward to next tutorial but can get rid of this compile issue
I know u said about headers package. But can you please point out exact issue..
Here is my system info:
Linux sunilshahu 3.5.0-17-generic #28-Ubuntu SMP Tue Oct 9 19:32:08 UTC 2012 i686
athlon i686 GNU/Linux
and after doing what you suggested here is the error log i got:
root@sunilshahu:/usr/src/linux-headers-3.5.0-17# make oldconfig
HOSTCC scripts/basic/fixdep
HOSTCC scripts/kconfig/conf.o
SHIPPED scripts/kconfig/zconf.tab.c
SHIPPED scripts/kconfig/zconf.lex.c
SHIPPED scripts/kconfig/zconf.hash.c
HOSTCC scripts/kconfig/zconf.tab.o
HOSTLD scripts/kconfig/conf
scripts/kconfig/conf oldconfig Kconfig
#
# using defaults found in /boot/config-3.5.0-17-generic
#
#
# configuration written to .config
#
root@sunilshahu:/usr/src/linux-headers-3.5.0-17#
root@sunilshahu:/usr/src/linux-headers-3.5.0-17#
root@sunilshahu:/usr/src/linux-headers-3.5.0-17# make prepare
scripts/kconfig/conf silentoldconfig Kconfig
make[1]: *** No rule to make target `/usr/src/linux-headers-3.5.017/arch/x86/syscalls/syscall_32.tbl, needed by
`arch/x86/syscalls/../include/generated/asm/unistd_32.h. Stop.

make: *** [archheaders] Error 2


root@sunilshahu:/usr/src/linux-headers-3.5.0-17# make prepare
make[1]: *** No rule to make target `/usr/src/linux-headers-3.5.017/arch/x86/syscalls/syscall_32.tbl, needed by
`arch/x86/syscalls/../include/generated/asm/unistd_32.h. Stop.
make: *** [archheaders] Error 2
Thanks(it will we while(1){thanks;} if anybody will help to sort this out)
Sunil.
anil_pugalia
Does make modules_prepare also give the same problem? If yes, then as I said earlier, you
also have the some issue with the headers package installation. Try reinstalling the linuxheaders package using apt-get.
Sunil S
ok. I did what Ajey said int the above discussion and changed make file as below
KERNEL_SOURCE := /lib/modules/3.5.0-17-generic/build
And it worked.. It compiled the ofd.c and i loaded and unloaded it successfully on my ubuntu
12.10.
So, does it means my linux sources or headers are at above directory and not at
/usr/src/linux-headers-3.5.0-17-generic and /usr/src/linux-source-3.5.0 , because i tried both
earlier?
anil_pugalia
Typically /lib/modules//build is a link to the corresponding source, these modules are built
from making it work with high probability. Please check the link and post here what does it
point to. That would definitely give insight into this common problem.
Sunil S
hi, i have to change the system after above comment and missed to see the link on that
system.
now i am using
Linux sunils 3.2.0-23-generic #36-Ubuntu SMP Tue Apr 10 20:39:51 UTC 2012 x86_64
x86_64 x86_64 GNU/Linux
my code compiled with this with make file
obj-m += ofd.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:

make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean


and when looking at the lib/modules//buld i find as below. but source link
(/build/buildd/linux-3.2.0) was red colored(dont know why) and when looking what it points
to i found that there is no such directory(but still i got my module compiled)
total 1088
drwxr-xr-x 7 root root 4096 Jul 2 13:54 ./
drwxr-xr-x 5 root root 4096 Jun 26 16:05 ../
drwxr-xr-x 3 root root 4096 Apr 25 2012 arch/
lrwxrwxrwx 1 root root 31 May 31 16:57 block -> ../linux-headers-3.2.0-23/block/
-rw-rr 1 root root 140241 Jul 2 13:53 .config
-rw-rr 1 root root 140241 Jul 2 12:25 .config.old
lrwxrwxrwx 1 root root 32 May 31 16:57 crypto -> ../linux-headers-3.2.0-23/crypto/
lrwxrwxrwx 1 root root 39 May 31 16:57 Documentation -> ../linux-headers-3.2.023/Documentation/
lrwxrwxrwx 1 root root 33 May 31 16:57 drivers -> ../linux-headers-3.2.0-23/drivers/
lrwxrwxrwx 1 root root 34 May 31 16:57 firmware -> ../linux-headers-3.2.0-23/firmware/
lrwxrwxrwx 1 root root 28 May 31 16:57 fs -> ../linux-headers-3.2.0-23/fs/
drwxr-xr-x 5 root root 4096 Apr 25 2012 include/
lrwxrwxrwx 1 root root 30 May 31 16:57 init -> ../linux-headers-3.2.0-23/init/
lrwxrwxrwx 1 root root 29 May 31 16:57 ipc -> ../linux-headers-3.2.0-23/ipc/
lrwxrwxrwx 1 root root 32 May 31 16:57 Kbuild -> ../linux-headers-3.2.0-23/Kbuild
lrwxrwxrwx 1 root root 33 May 31 16:57 Kconfig -> ../linux-headers-3.2.0-23/Kconfig
drwxr-xr-x 2 root root 4096 Jul 2 12:27 kernel/
lrwxrwxrwx 1 root root 29 May 31 16:57 lib -> ../linux-headers-3.2.0-23/lib/
lrwxrwxrwx 1 root root 34 May 31 16:57 Makefile -> ../linux-headers-3.2.0-23/Makefile
-rw-rr 1 root root 608 Apr 11 2012 .missing-syscalls.d
lrwxrwxrwx 1 root root 28 May 31 16:57 mm -> ../linux-headers-3.2.0-23/mm/
-rw-rr 1 root root 0 Jul 2 11:21 modules.order

-rw-rr 1 root root 791023 Apr 11 2012 Module.symvers


lrwxrwxrwx 1 root root 29 May 31 16:57 net -> ../linux-headers-3.2.0-23/net/
lrwxrwxrwx 1 root root 33 May 31 16:57 samples -> ../linux-headers-3.2.0-23/samples/
drwxr-xr-x 7 root root 4096 Apr 25 2012 scripts/
lrwxrwxrwx 1 root root 34 May 31 16:57 security -> ../linux-headers-3.2.0-23/security/
lrwxrwxrwx 1 root root 31 May 31 16:57 sound -> ../linux-headers-3.2.0-23/sound/
lrwxrwxrwx 1 root root 25 May 31 16:57 source -> /build/buildd/linux-3.2.0
drwxr-xr-x 2 root root 4096 Apr 11 2012 .tmp_versions/
lrwxrwxrwx 1 root root 31 May 31 16:57 tools -> ../linux-headers-3.2.0-23/tools/
lrwxrwxrwx 1 root root 32 May 31 16:57 ubuntu -> ../linux-headers-3.2.0-23/ubuntu/
lrwxrwxrwx 1 root root 29 May 31 16:57 usr -> ../linux-headers-3.2.0-23/usr/
lrwxrwxrwx 1 root root 30 May 31 16:57 virt -> ../linux-headers-3.2.0-23/virt/
anil_pugalia
What output have you sent? Please send the output of:
ls -l /lib/modules/`uname -r`/
Sunil S
Here is the output:
root@sunils:~# ls -l /lib/modules/`uname -r`/
total 4276
lrwxrwxrwx 1 root root 39 May 31 16:56 build -> /usr/src/linux-headers-3.2.0-23-generic
drwxr-xr-x 2 root root 4096 Apr 25 2012 initrd
drwxr-xr-x 10 root root 4096 Apr 25 2012 kernel
-rw-rr 1 root root 685840 Apr 25 2012 modules.alias
-rw-rr 1 root root 667167 Apr 25 2012 modules.alias.bin
-rw-rr 1 root root 5724 Apr 11 2012 modules.builtin
-rw-rr 1 root root 7132 Apr 25 2012 modules.builtin.bin
-rw-rr 1 root root 69 Apr 25 2012 modules.ccwmap

-rw-rr 1 root root 314947 Apr 25 2012 modules.dep


-rw-rr 1 root root 463653 Apr 25 2012 modules.dep.bin
-rw-rr 1 root root 186 Apr 25 2012 modules.devname
-rw-rr 1 root root 889 Apr 25 2012 modules.ieee1394map
-rw-rr 1 root root 295 Apr 25 2012 modules.inputmap
-rw-rr 1 root root 4624 Apr 25 2012 modules.isapnpmap
-rw-rr 1 root root 1421 Apr 25 2012 modules.ofmap
-rw-rr 1 root root 128682 Apr 11 2012 modules.order
-rw-rr 1 root root 451186 Apr 25 2012 modules.pcimap
-rw-rr 1 root root 2815 Apr 25 2012 modules.seriomap
-rw-rr 1 root root 131 Apr 25 2012 modules.softdep
-rw-rr 1 root root 260900 Apr 25 2012 modules.symbols
-rw-rr 1 root root 330555 Apr 25 2012 modules.symbols.bin
-rw-rr 1 root root 998947 Apr 25 2012 modules.usbmap
anil_pugalia
I hope that clarifies all the doubts. The link is correctly pointing to the headers, which are
working for you. Pasting it here for reference:
lrwxrwxrwx 1 root root 39 May 31 16:56 build -> /usr/src/linux-headers-3.2.0-23-generic
darcy.diao@gmail.com
I use your code and compile successfully.
But when insmod by sudo insmod ofd.ko, error prompt- insmod: error inserting ofd.ko': -1
Invalid module format.
Can you tell me why?
Thx.
http://twitter.com/anil_pugalia Anil Pugalia
Make sure that the kernel headers you used to compile the driver has the same version as
the running kernel.
darcy.diao@gmail.com
I change the KERNEL_SOURCE to /lib/module/$(shell uname -r)/build.
It is ok right now.

tushraj
I use your code and compile by make command then i got following error
tushar@tushar-SVE14112ENW:~/devdrv$ make
make -C /usr/src/linux-headers-3.5.0-17 SUBDIRS=/home/tushar/devdrv modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17
WARNING: Symbol version dump /usr/src/linux-headers-3.5.0-17/Module.symvers is
missing;
modules will have no dependencies and modversions.
Building modules, stage 2.
MODPOST 0 modules
/bin/sh: 1: scripts/mod/modpost: not found
make[2]: *** [__modpost] Error 127
make[1]: *** [modules] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17
make: *** [default] Error 2
http://twitter.com/anil_pugalia Anil Pugalia
Check out the comments below for the solution to the same problem.
enigma
obj-m := ofd.o should be obj-m += ofd.o ?
http://twitter.com/anil_pugalia Anil Pugalia
In this particular case, even := is fine as, we are limiting the build to the drivers directory and
more to our driver, alone.
janakiram
I use your code and compile by make command then i got following errors
make -C /usr/src/linux-headers-3.2.0-29 SUBDIRS=/home/shivaram/jani modules
make[1]: Entering directory `/usr/src/linux-headers-3.2.0-29
ERROR: Kernel configuration is invalid.
include/generated/autoconf.h or include/config/auto.conf are missing.
Run make oldconfig && make prepare on kernel src to fix it.
WARNING: Symbol version dump /usr/src/linux-headers-3.2.0-29/Module.symvers
is missing; modules will have no dependencies and modversions.

Building modules, stage 2.


/usr/src/linux-headers-3.2.0-29/scripts/Makefile.modpost:42: include/config/auto.conf: No
such file or directory
make[2]: *** No rule to make target `include/config/auto.conf. Stop.
make[1]: *** [modules] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.2.0-29
make: *** [default] Error 2s
And also i tried with make oldconfig&&make prepare then i got problem like
make: *** No rule to make target `oldconfig. Stop.
i installed ubuntu through vmware. one of my friend said its the problem u should install
normal way..
http://twitter.com/anil_pugalia Anil Pugalia
Check out the discussion threads below.
uday
sir,i have created a makefile and added obj-m := ofd.o in it.
After saving and exiting the terminal,i have given command like this
make -C /usr/src/linux-headers-generic-pae-3.2.0-12 SUBDIRS=$PWD modules
but it is showing no rule to makepls help me.
regards,
uday.
http://twitter.com/anil_pugalia Anil Pugalia
Make sure that you use *only tabs* to indent your makefile. You get such errors, if you have
used spaces instead.
Ajey
Namaste, When I used Kernel_Source as KERNEL_SOURCE := /usr/src/linux-header-3.5.0-30generic > I get an error No such file or directory and when I change Kernel_Source as
KERNEL_SOURCE := /lib/modules/3.5.0-30-generic/build (this was recommended in one of
comments below), then I get following error. Not able to proceed beyond this .
make -C /lib/modules/3.5.0-30-generic/build SUBDIRS=/ modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-30-generic
scripts/Makefile.build:128: kbuild: Makefile.build is included improperly
make[2]: *** No rule to make target `kernel/bounds.c, needed by `kernel/bounds.s. Stop.
make[1]: *** [_module_] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-30-generic
make: *** [default] Error 2

anil_pugalia
Seems like, there is some problem with the installation of the kernel headers with this
version of the distro you are using.
xpress_embedo
I too got this error, the problem was that I had created a folder Linux Device Driver and under
this HelloWorld, When i remove Space and Change Folder name as LinuxDeviceDriver,
everything works fine, Hoping you too had done same thing.
Hope this help.
Very Nice Tutorial:-)
anil_pugalia
Oh! Thats great input. Hey guys, please fix your problems, if you are having the same
problem.
Ajey
After I upgraded to Ubuntu 13.04, the problem got rectified, only thing is, in the sample
Makefile, I had to change Kernel_Source := /lib/modules//3.8.0-23-generic/build. Thanks for
this article.
anil_pugalia
You are welcome.
nandan
Thanks sir ..you have done a great job.
anil_pugalia
Thanks for reading & appreciating.
nbtsos
hi sir, i can compile on ubuntu version 8, but when i use ubuntu 12.04 lts, i tried every way to
compile but still cannot compile:
user@ubuntu:~/Study$ make
make: Nothing to be done for `default.
Then i add default: ofd.o to our Makefile but it raise another error:
cc -c -o ofd.o ofd.c
ofd.c:2:26: fatal error: linux/module.h: No such file or directory compilation terminated.
Later, i must use command (type manually to terminal) like this to compile :
make -C /lib/modules/3.5.0-37-generic/build SUBDIRS=/home/user/Study modules

And the result is OK:


make: Entering directory `/usr/src/linux-headers-3.5.0-37-generic
CC [M] /home/nobita/Study/ofd.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/nobita/Study/ofd.mod.o
LD [M] /home/nobita/Study/ofd.ko
make: Leaving directory `/usr/src/linux-headers-3.5.0-37-generic
Could you help me how to handle this, and why cant i use Makefile??
Thanks in advance!
nbtsos
And there is a slight problem here, when using Ubuntu 8.x (kernel 2.6x) with your Makefile,
everything ok. When insmod -> dmesg -> get line Namaskar: ofcd registered, when rmmod > dmesg -> get line Alvida: ofcd unregistered. But with ubuntu 12.04 LTS (kernel 3.5x),
compile with method state above, when When insmod -> dmesg -> nothing, but when rmmod
-> dmesg -> get 2 line Namaskar and Alvida <= confuse?? line Namaskar must be appear
after insmod, right?
When trying you example in part 5 (still compile like above), everything's gone smoothly
apart from when dmesg, all line involve in open, close appear correctly but still 2 line
"Namaskar and Alvida" appear only when i rmmod. I dont know why, the code is exactly
the same like you.
Another problem: with example in part 5, when using Ubuntu 8.x (actually i use virtual
machine to run this OS), compile ok, but when insmod got error: Segmentation fault, .
address 0x00000., i tried to debug it (still not familiar with it) and i figured problem involving
in device_create, so i cant get mynull. But with Ubuntu 12 (installed in my laptop by wubi)
everything work well except the problem about message line i mentioned before.
anil_pugalia
Hardware access through virtual box is not recommended and you have the segfault kind of
issues, as mentioned by you.
Regarding the dmesg output, its a delayed buffer flush issue. Put a n at the end of each of
the strings, and things should work fine.
anil_pugalia
Change the KERNEL_SOURCE variable in the Makefile to /lib/modules/3.5.0-37-generic/build
and you should be able to use your Makefile it just that the kernel source path is different
on your system.
why bother
Thank you very much for this simple example! Comment section helped a lot too! Great to be
doing Linux device drivers!

anil_pugalia
Thanks for your appreciation, as well.
Ajay
Hi sir,
I am getting there error plz help me out
ajay@ubuntu:~/module$ make
make -C /usr/src/linux-headers-3.5.0-17-generic SUBDIRS-/home/ajay/module module
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic
HOSTCC scripts/basic/fixdep
scripts/basic/fixdep.c:433:1: fatal error: opening dependency file scripts/basic/.fixdep.d:
Permission denied
compilation terminated.
make[3]: *** [scripts/basic/fixdep] Error 1
make[2]: *** [scripts_basic] Error 2
make[1]: *** No rule to make target `SUBDIRS-/home/ajay/module. Stop.
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic
make: *** [all] Error 2
anil_pugalia
I hope pjms comment as mentioned above, has solved your problem.
Ajay
Hi sir,
I am getting there error plz help me out
ajay@ubuntu:~/module$ make
make -C /usr/src/linux-headers-3.5.0-17-generic SUBDIRS-/home/ajay/module module
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic
HOSTCC scripts/basic/fixdep
scripts/basic/fixdep.c:433:1: fatal error: opening dependency file scripts/basic/.fixdep.d:
Permission denied
compilation terminated.
make[3]: *** [scripts/basic/fixdep] Error 1
make[2]: *** [scripts_basic] Error 2
make[1]: *** No rule to make target `SUBDIRS-/home/ajay/module. Stop.
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic
make: *** [all] Error 2
pjmpjm
peter@Ubuntu2:~$
peter@Ubuntu2:~$ rm ofd.mod.o
peter@Ubuntu2:~$ rm ofd.ko

peter@Ubuntu2:~$
peter@Ubuntu2:~$ make -f makefile
make: Nothing to be done for `default.
peter@Ubuntu2:~$ make -f Makefile
make -C /usr/src/linux-headers-3.2.0-56-generic SUBDIRS=/home/peter modules
make[1]: Entering directory `/usr/src/linux-headers-3.2.0-56-generic
Building modules, stage 2.
MODPOST 1 modules
CC /home/peter/ofd.mod.o
LD [M] /home/peter/ofd.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.2.0-56-generic
peter@Ubuntu2:~$
makefile( indented lines have 4 leading spaces using cut&paste from this article)
ifneq (${KERNELRELEASE},)
obj-m := ofd.o
# Otherwise we were called directly from the command line.
# Invoke the kernel build system.
else
KERNEL_SOURCE := /usr/src/linux-headers-3.2.0-56-generic
PWD := $(shell pwd)
default:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
clean:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean
endif
Makefile ( indented lines have 1 leading tab after editing)
ifneq (${KERNELRELEASE},)
obj-m := ofd.o
# Otherwise we were called directly from the command line.
# Invoke the kernel build system.
else
KERNEL_SOURCE := /usr/src/linux-headers-3.2.0-56-generic
PWD := $(shell pwd)
default:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} modules
clean:
${MAKE} -C ${KERNEL_SOURCE} SUBDIRS=${PWD} clean
endif
Sooooooo if you cut and paste from this tutorial to create your makefile edit it so that the
leading white space is one Tab this is with Ububtu 12.04
hope this helps

nice work Anil


pjm
anil_pugalia
Thanks pjm.
Sham
Hello,
I am trying to compile USB driver code, but getting following
warnings:
root@ubuntu:/opt/linux-cortexm-1.4.1/projects/developer/app/driver#
make
make -C /opt/linux-cortexm-1.4.1/linux M=`pwd` modules CFLAGS=
LDFLAGS=
make[1]: Entering directory `/opt/linux-cortexm-1.4.1/linux
CC [M] /opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.o
Building modules, stage 2.
MODPOST 1 modules
WARNING: usb_register_driver
[/opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.ko]
undefined!
WARNING: usb_register_dev
[/opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.ko]
undefined!
WARNING: usb_get_dev
[/opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.ko]
undefined!
WARNING: usb_put_dev
[/opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.ko]
undefined!
WARNING: usb_deregister_dev
[/opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.ko]
undefined!
WARNING: usb_find_interface
[/opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.ko]
undefined!
WARNING: usb_bulk_msg
[/opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.ko]
undefined!
WARNING: usb_deregister
[/opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.ko]
undefined!
CC /opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.mod.o
LD [M]

/opt/linux-cortexm-1.4.1/projects/developer/app/driver/vcom.ko
make[1]: Leaving directory `/