Our first Linux driver
Our first Linux driver
Before we write our first driver, let’s 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 amain()
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 module’s 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
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
| /* 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" ); |
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 module’s “signature”.Building our first Linux driver
Once we have the C code, it is time to compile it and create the module fileofd.ko
. We use the kernel build system to do this. The following Makefile
invokes the kernel’s build system from the kernel source, and the kernel’s Makefile
will, in turn, invoke our first driver’s 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 it’s at any other location on your system, specify the location in the KERNEL_SOURCE
variable in this Makefile
.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # 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 |
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 theofd.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. Where’s 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.”
Comments
Post a Comment