Sunday, September 4, 2011

Linux Device Driver

Reference
[Anil Kumar Pugalia]

A device driver is a piece of software that drives a device.

Device - Device Controller - Bus - CPU
Devices are connected to device controller.
Device controllers are typically connected to the CPU through their respectively named buses (IDE, PCI, USB, SPI, I2C...).

Two types of drivers:
        1. Device driver
        2. Bus driver

1. Device Driver
Fig: Linux device driver partition
A device driver has two parts:
    1. Device specific  [Understand & decode device datasheet]
    2. Operating System(OS) specific [Tightly coupled with the OS mechanisms of user interface]

A device driver provides a 'systemcall', interface to the user; this is called the boundary line between the so called kernel space and user space of Linux.

In Linux a driver is broadly classified into three verticals:
Fig: Device Driver Classification
Network Vertical
     1. Network protocol stack
     2. Network interface card device drivers

Storage Vertical
  1. File System drivers   [ To decode various formats on different partitions]
  2. Block device drivers.[ For various h/w storage protocols like IDE,SCSI,MTD]

2. Bus Driver

In Linux, Bus drivers (or the horizontals) are often split into two parts:
          1. A device controller specific
          2. An abstraction layer over that for the verticals to interface, commonly
              called cores.
              [e.g.:   1. USB controller drivers - ohci, ehci etc,
                         2. USB abstraction - usbcore 
              ]


Dynamic Loading in Linux
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.

* Linux kernel is an object oriented implementation in C.

Commands: insmod, lsmod, rmmod, modprobe, modinfo

Simple kernel module/driver
/* simple driver code
 * Author: Vinod Sasidharan
 */

#include
#include
#include

static int __init hello_init(void)
{
    printk(KERN_INFO "Hai: Hello connected");
    return 0;
}

static void __exit hello_exit(void)
{
    printk(KERN_INFO "Bye: Hello disconnected");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Vinod Sasidharan");
MODULE_DESCRIPTION("Simple kernel module");

Makefile [Use this for all kernel modules; do change the name(hello.o)]

obj-m+=hello.o
all:
    make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules
clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) clean
install:
    make -C /lib/modules/$(shell uname -r)/build M=$(shell pwd) modules_install
Commands
$ sudo su
$ make
$ insmod hello.ko
$ lsmod | grep hello
$ dmesg | tail -10
$ rmmod hello
$ dmesg | tail -10
$ objdump -d hello.ko
$ nm hello.ko

Tested on: Ubuntu 11.04 - the Natty Narwhal



 printk n kernel c
  • Floating point is not supported in Linux kernel.
  • When programming for the kernel, we don't bother about the float formats %f, %lf.
  • All printk calls put their output into the (log) ring buffer of the kernel. Then the syslog daemon running in the user-space picks them up for final processing and re-direction to various devices as configure in the configuration file /etc/syslog.conf [Ubuntu: /etc/sysctl.conf]
  • Typical destination: /var/log/messages
  • A user space utility 'dmesg' is provided to directly parse the kernel ring buffer, and dump it to standard output.
  • Kernel C is just standard C with some additional extensions from the C compiler.
  • All functions with __init are supposed to be executed only once during boot up. So after their execution, kernel frees up RAM by removing them.
  • Functions in the exit section are supposed to be called during system shut down.

Character Drivers

Fig: Character driver

If we write drivers for byte-oriented operations (or character oriented operations) then we refer to them as character drivers.

4 entities
  1.     Application
  2.     Character device file
  3.     Character device driver
  4.     Character device
  • Character driver usage is done by the user space application through the character device file linked to it through the virtual file system (VFS).
  • An application does the usual file operations on the character device file.
  • Those operations are translated to the corresponding functions in the linked character device driver by the VFS.
  • Those functions then do the final low-level access to the actual device to achieve the desired results.












No comments: