SlideShare ist ein Scribd-Unternehmen logo
1 von 46
DEVICE DRIVER
Introduction
• Defination :- Device driver or software driver is a
  computer program allowing higher-level computer
  programs to interact with a hardware device.

• A driver typically communicates with the device
  through the computer bus or communications
  subsystem to which the hardware connects.

• Drivers are hardware-dependent and operating-
  system-specific. They usually provide the interrupt
  handling required for any necessary asynchronous
  time-dependent hardware interface.
Why a Device Driver?
• A device driver is usually part of the OS kernel
   o Compiled with the OS
   o Dynamically loaded into the OS during execution.

• Each device driver handles
   o one device type (e.g., mouse)
   o one class of closely related devices (e.g., SCSI disk driver to handle
     multiple disks of different sizes and different speeds.).

• A device driver simplifies programming by acting as
  translator between a hardware device and the
  applications or operating systems that use it.

• Programmers can write the higher-level application
  code independently of whatever specific hardware
  device.
Location
Device Drivers in Linux
Processes in Linux
• When a user process executes a system call, it does
  not transfer control to another process,

• but changes its execution mode from user to kernel
  mode.

• In kernel mode, while executing the system call, the
  process has access to the kernel address space, and

• Through supporting functions it has access to the
  address space of the user executing the call.
Functions in Device Drivers
• Accept abstract read and write requests from the
  device-independent layer above.
• Initialize the device.
• Manage power requirements and log events.
• Check input parameters if they are valid.
• Translate valid input from abstract to concrete terms
   o e.g., convert linear block number into the head, track, sector and cylinder
     number for disk access.

• Check the device if it is in use (i.e., check the status bit).
• Control the device by issuing a sequence of commands.
  The driver determines what commands will be issued.
Loadable Kernel Module
• In computing, a loadable kernel module (or LKM) is an object
  file that contains code to extend the running kernel, or so-
  called base kernel, of an operating system.
• Most current Unix-like systems, and Microsoft Windows, support
  loadable kernel modules.
• Without loadable kernel modules, an operating system would
  have to have all possible anticipated functionality already
  compiled directly into the base kernel.
• Much of that functionality would reside in memory without
  being used, wasting memory, and would require that users
  rebuild and reboot the base kernel every time new
  functionality is desired.
• Most operating systems supporting loadable kernel modules
  will include modules to support most desired functionality.
Classes of Devices and Modules
• The Linux way of looking at devices distinguishes
  between three fundamental device types.

• Each module usually implements one of these types,
  and thus is classifiable as


           1.char module

           2.block module

           3.network module.
1. Character devices
• A character (char) device is one that can be
  accessed as a stream of bytes (like a file); a char
  driver is in charge of implementing this behavior.
• Such a driver usually implements at least the open,
  close, read, and write system calls.
• The text console (/dev/console) and the serial ports
  (/dev/ttyS0 and friends) are examples of char devices,
  as they are well represented by the stream
  abstraction.
• Char devices are accessed by means of filesystem
  nodes, such as /dev/tty1 and /dev/lp0.
• The only relevant difference between a char device
  and a regular file is that you can always move back
  and forth in the regular file, whereas most char
  devices are just data channels, which you can only
  access sequentially.
2.Block devices
• Like char devices, block devices are accessed by
  filesystem nodes in the /dev directory.
• A block device is a device (e.g., a disk) that can host a
  filesystem.
• In most Unix systems, a block device can only handle I/O
  operations that transfer one or more whole blocks, which
  are usually 512 bytes (or a larger power of two) bytes in
  length.
• Linux, instead, allows the application to read and write a
  block device like a char device—it permits the transfer of
  any number of bytes at a time.
• As a result, block and char devices differ only in the way
  data is managed internally by the kernel, and thus in the
  kernel/driver software interface.
• Like a char device, each block device is accessed
  through a filesystem node, and the difference between
  them is transparent to the user.
3. Network interfaces
• Any network transaction is made through an interface,
  that is, a device that is able to exchange data with other
  hosts.
• Usually, an interface is a hardware device, but it might
  also be a pure software device, like the loopback
  interface.
• A network interface is in charge of sending and receiving
  data packets, driven by the network subsystem of the
  kernel, without knowing how individual transactions map
  to the actual packets being transmitted.
• Many network connections (especially those using TCP)
  are stream-oriented, but network devices are, usually,
  designed around the transmission and receipt of packets.
• A network driver knows nothing about individual
  connections; it only handles packets.
Major Minor Numbers
• Major device numbers are used by the Linux system
  to map I/O requests to the driver code, thereby
  deciding which device driver to execute, when a
  user reads from or writes to the special file.

• The minor numbers are entirely under the control of
  the driver writer, and usually refer to sub-devices of
  the device.

• These sub-devices may be separate units attached
  to a controller. Thus, a disk device driver may, for
  example, communicate with a hardware controller
  (the device) which has several disk drives (sub-
  devices) attached.
Device Driver Protocol
o After driver knows which commands to issue, it
  starts to write them into controller's device
  registers .
o After writing each command, it checks to see if
  the controller accepted the command and is
  prepared to accept the next one.
o After commands have been issued, either (a) the
  device waits until the controller does some work
  and it blocks itself until interrupt comes to
  unblock it; or (b) the device doesn't wait
  because the command finished without any
  delay.
Applications
• Because of the diversity of modern hardware and operating
  systems, drivers operate in many different environments. Drivers
  may interface with:

•   Printers
•   video adapters
•   network cards
•   sound cards
•   local buses of various sorts — in particular, for bus mastering on
    modern systems
•   low-bandwidth I/O buses of various sorts (for pointing devices
    such as mice, keyboards, USB, etc.)
•   computer storage devices such as hard disk, CD-ROM and
    floppy disk buses (ATA, SATA, SCSI)
•   implementing support for different file systems
•   image scanners
•   digital cameras
Character Device Driver
• User Space and Kernel Space
• Loading and Removing the driver
  in user space
• Loading and Removing the driver
  in kernel space
• The complete driver “memory”
User space and kernel space
• When you write device drivers, it’s important to
  make the distinction between “user space” and
  “kernel space”.
• Kernel Space : Linux (which is a kernel) manages
  the machine's hardware in a simple and efficient
  manner, offering the user a simple and uniform
  programming interface.
• In the same way, the kernel, and in particular its
  device drivers, form a bridge or interface between
  the end-user/programmer and the hardware.
• Any subroutines or functions forming part of the
  kernel (modules and device drivers, for example)
  are considered to be part of kernel space.
• User space : End-user programs, like the UNIX shell
           or other GUI based applications (kpresenter for
           example), are part of the user space.
         • Obviously, these applications need to interact with
           the system's hardware . However, they don’t do so
           directly, but through the kernel supported
           functions.
Device driver events and their associated interfacing functions between kernel space and user space.
Events                        User functions             Kernel functions
Load module                   insmod                     module_init()
Open device                   fopen                      file_operations: open
Close device                  fread                      file_operations: read
Write device                  fwrite                     file_operations: write
Close device                  fclose                     file_operations: release
Remove module                 rmmod                      module_exit()



Device driver events and their associated functions between kernel space and the hardware device.
Events                                 Kernel functions
Read data                              inb
Write data                             outb
Loading and Removing the driver in user space
• To implement simple character device driver in user
  space make one file named “demo.c” and content of file
  is :
  #include <linux/module.h>
   MODULE_LICENSE("Dual BSD/GPL");

• Next, you need to generate a makefile. The makefile for
  this example, which should be named Makefile, will be:
  obj-m := demo.o

• Unlike with previous versions of the kernel, it’s now also
  necessary to compile the module using the same kernel
  that you’re going to load and use the module with. To
  compile it, you can type:
  make -C /usr/src/kernel-source-2.6.8 M=`pwd` modules
In user space, you can load the module as root by typing the following
into the command line:
# insmod demo.ko

The insmod command allows the installation of the module in the kernel.
However, this particular module isn’t of much use.

It is possible to check that the module has been installed correctly by
looking at all installed modules:
# lsmod

Finally, the module can be removed from the kernel using the command:
# rmmod demo

By issuing the lsmod command again, you can verify that the module is
no longer in the kernel.
Loading and Removing the driver in kernel space
 • When a module device driver is loaded into the
   kernel, some preliminary tasks are usually performed
   like resetting the device, reserving RAM, reserving
   interrupts, and reserving input/output ports, etc.
 • These tasks are performed, in kernel space, by two
   functions which need to be present (and explicitly
   declared): module_init and module_exit; they
   correspond to the user space commands insmod
   and rmmod , which are used when installing or
   removing a module.
 • To sum up, the user commands insmod and rmmod
   use the kernel space functions module_init and
   module_exit.
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
         printk("<1> Hello world!n");
         return 0;
}
static void hello_exit(void)
{
         printk("<1> Bye, cruelworldn");
}
module_init(hello_init);
module_exit(hello_exit);
• The actual functions hello_init and hello_exit can be
  given any name desired. However, in order for them to
  be identified as the corresponding loading and removing
  functions, they have to be passed as parameters to the
  functions module_init and module_exit.

• The printk function has also been introduced. It is very
  similar to the well known printf apart from the fact that it
  only works inside the kernel. The <1> symbol shows the
  high priority of the message (low number). In this way,
  besides getting the message in the kernel system log files,
  you should also receive this message in the system
  console.

• This module can be compiled using the same command
  as before, after adding its name into the Makefile and
  content of it is : “obj-m := demo.o hello.o”.
The complete driver “memory”: initial part of the driver
• I’ll now show how to build a complete device driver: memory.c.
  This device will allow a character to be read from or written into it.
  This device, while normally not very useful, provides a very
  illustrative example since it is a complete driver; it's also easy to
  implement,since it doesn’t interface to a real hardware device.

• After the #include files, the functions that will be defined later are
  declared.
• The common functions which are typically used to manipulate
  files are declared in the definition of the file_operations structure.
  These will also be explained in detail later. Next, the initialization
  and exit functions—used when loading and removing the
  module—are declared to the kernel.
• Finally, the global variables of the driver are declared: one of
  them is the major number of the driver, the other is a pointer to a
  region in memory, memory_buffer, which will be used as storage
  for the driver data.
/* Necessary includes for device drivers */
#include <linux/init.h>
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h> /* printk() */
#include <linux/slab.h> /* kmalloc() */
#include <linux/fs.h> /* everything... */
#include <linux/errno.h> /* error codes */
#include <linux/types.h> /* size_t */
#include <linux/proc_fs.h>
#include <linux/fcntl.h> /* O_ACCMODE */
#include <asm/system.h> /* cli(), *_flags */
#include <asm/uaccess.h> /* copy_from/to_user */

MODULE_LICENSE("Dual BSD/GPL");

/* Declaration of memory.c functions */
int memory_open(struct inode *inode, struct file *filp);
int memory_release(struct inode *inode, struct file *filp);
ssize_t memory_read(struct file *filp, char *buf, size_t      count,   loff_t
*f_pos);
ssize_t memory_write(struct file *filp, char *buf, size_t     count,   loff_t
*f_pos);
void memory_exit(void);
int memory_init(void);

/* Structure that declares the usual file */
/* access functions */
struct file_operations memory_fops = {
   read: memory_read,
   write: memory_write,
   open: memory_open,
   release: memory_release
};

/* Declaration of the init and exit functions */
module_init(memory_init);
module_exit(memory_exit);

/* Global variables of the driver */
/* Major number */
int memory_major = 60;
/* Buffer to store data */
char *memory_buffer;
The “memory” driver: connection of the device with its files
•   In UNIX and Linux, devices are accessed from user space in exactly the
    same way as files are accessed. These device files are normally
    subdirectories of the /dev directory.
•   To link normal files with a kernel module two numbers are used: major
    number and minor number. The major number is the one the kernel
    uses to link a file with its driver. The minor number is for internal use of the
    device and for simplicity it won’t be covered in this article.

•   To achieve this, a file (which will be used to access the device driver)
    must be created, by typing the following command as root:
•   # mknod /dev/memory c 60 0

•   In the above, c means that a char device is to be created, 60 is the
    major number and 0 is the minor number.
•   Within the driver, in order to link it with its corresponding /dev file in
    kernel space, the register_chrdev function is used. It is called with three
    arguments: major number, a string of characters showing the module
    name, and a file_operations structure which links the call with the file
    functions it defines. It is invoked, when installing the module, in this way:
•   Also, note the use of the kmalloc function. This function is used for
    memory allocation of the buffer in the device driver which resides in
    kernel space. Its use is very similar to the well known malloc function.
    Finally, if registering the major number or allocating the memory fails,
    the module acts accordingly.
int memory_init(void) {
  int result;

    /* Registering device */
    result = register_chrdev(memory_major, "memory", &memory_fops);
    if (result < 0) {
      printk(
        "<1>memory: cannot obtain major number %dn", memory_major);
      return result;
    }

    /* Allocating memory for the buffer */
    memory_buffer = kmalloc(1, GFP_KERNEL);
    if (!memory_buffer) {
      result = -ENOMEM;
      goto fail;
    }
    memset(memory_buffer, 0, 1);

    printk("<1>Inserting memory modulen");
    return 0;

    fail:
      memory_exit();
      return result;

}
The “memory” driver: removing the driver
• In order to remove the module inside the memory_exit
  function, the function unregsiter_chrdev needs to be present.
  This will free the major number for the kernel.

• The buffer memory is also freed in this function, in order to
  leave a clean kernel when removing the device driver.


  void memory_exit(void) {
    /* Freeing the major number */
    unregister_chrdev(memory_major, "memory");

      /* Freeing buffer memory */
      if (memory_buffer) {
        kfree(memory_buffer);
      }

      printk("<1>Removing memory modulen");

  }
The “memory” driver: opening the device as a file
•    The kernel space function, which corresponds to opening a file in
     user space (fopen), is the member open: of the file_operations
     structure in the call to register_chrdev. In this case, it is the
     memory_open function. It takes as arguments: an inode structure,
     which sends information to the kernel regarding the major number
     and minor number; and a file structure with information relative to
     the different operations that can be performed on a file. Neither of
     these functions will be covered in depth within this article.
•    When a file is opened, it’s normally necessary to initialize driver
     variables or reset the device. In this simple example, though, these
     operations are not performed.
•    The memory_open function can be seen below:

     int memory_open(struct inode *inode, struct file *filp)
          {
                /* Success */ return 0;
          }
The “memory” driver: closing the device as a file
• The corresponding function for closing a file in user space
  (fclose) is the release: member of the file_operations structure
  in the call to register_chrdev. In this particular case, it is the
  function memory_release, which has as arguments an inode
  structure and a file structure, just like before.
• When a file is closed, it’s usually necessary to free the used
  memory and any variables related to the opening of the
  device. But, once again, due to the simplicity of this example,
  none of these operations are performed.
• The memory_release function is shown below:
   int memory_release(struct inode *inode, struct file *filp)
   {
        /* Success */ return 0;
   }
The “memory” driver: reading the device
• To read a device with the user function fread or
  similar, the member read: of the file_operations
  structure is used in the call to register_chrdev. This
  time, it is the function memory_read. Its arguments
  are: a type file structure; a buffer (buf), from which
  the user space function (fread) will read; a counter
  with the number of bytes to transfer (count), which
  has the same value as the usual counter in the user
  space function (fread); and finally, the position of
  where to start reading the file (f_pos).

• In this simple case, the memory_read function
  transfers a single byte from the driver buffer
  (memory_buffer) to user space with the function
  copy_to_user:
ssize_t memory_read(struct file *filp, char *buf,
                    size_t count, loff_t *f_pos) {

    /* Transfering data to user space */
    copy_to_user(buf,memory_buffer,1);

    /* Changing reading position as best suits */
    if (*f_pos == 0) {
      *f_pos+=1;
      return 1;
    } else {
      return 0;
    }
}




    • The reading position in the file (f_pos) is also changed. If
      the position is at the beginning of the file, it is increased
      by one and the number of bytes that have been
      properly read is given as a return value, 1. If not at the
      beginning of the file, an end of file (0) is returned since
      the file only stores one byte.
The “memory” driver: writing to a device
    • To write to a device with the user function fwrite or similar, the
      member write: of the file_operations structure is used in the
      call to register_chrdev.
    • It is the function memory_write, in this particular example,
      which has the following as arguments: a type file structure;
      buf, a buffer in which the user space function (fwrite) will write;
      count, a counter with the number of bytes to transfer, which
      has the same values as the usual counter in the user space
      function (fwrite); and finally, f_pos, the position of where to
      start writing in the file.


ssize_t memory_write( struct file *filp, char *buf,
                      size_t count, loff_t *f_pos) {

    char *tmp;

    tmp=buf+count-1;
    copy_from_user(memory_buffer,tmp,1);
    return 1;
}
The complete “memory” driver
•    By joining all of the previously shown code, the complete driver is achieved:
    <memory.c> =

       <memory   initial>
       <memory   init module>
       <memory   exit module>
       <memory   open>
       <memory   release>
       <memory   read>

       <memory write>
•    Before this module can be used, you will need to compile it in the same way as with
     previous modules. The module can then be loaded with:
•    # insmod memory.ko
•    It’s also convenient to unprotect the device:
•    # chmod 666 /dev/memory
•    If everything went well, you will have a device /dev/memory to which you can write
     a string of characters and it will store the last one of them. You can perform the
     operation like this:
•    $ echo -n abcdef >/dev/memory
•    To check the content of the device you can use a simple cat:
•    $ cat /dev/memory
•    The stored character will not change until it is overwritten or the module is removed.
USB Drivers
• The universal serial bus (USB) is a connection
  between a host computer and a number of
  peripheral devices.
• It was originally created to replace a wide range of
  slow and different buses—the parallel, serial, and
  keyboard connections—with a single bus type that
  all devices could connect to.
• USB has grown beyond these slow connections and
  now supports almost every type of device that can
  be connected to a PC.
• The latest revision of the USB specification added
  high-speed connections with a theoretical speed
  limit of 480 MBps.
• Topologically, a USB subsystem is not laid out as a
  bus; it is rather a tree built out of several point-to-point
  links. The links are four-wire cables (ground, power,
  and two signal wires) that connect a device and a
  hub, just like twisted-pair Ethernet.
• The USB host controller is in charge of asking every
  USB device if it has any data to send.
• Because of this topology, a USB device can never
  start sending data without first being asked to by the
  host controller.
• This configuration allows for a very easy plugand-play
  type of system, whereby devices can be
  automatically configured by the host computer.
• The USB protocol specifications define a set of
  standards that any device of a specific type can
  follow.
• If a device follows that standard, then a special
  driver for that device is not necessary.
• These different types are called classes and consist
  of things like storage devices, keyboards, mice,
  joysticks, network devices, and modems.
• Other types of devices that do not fit into these
  classes require a special vendor-specific driver to be
  written for that specific device.
• Video devices and USB-to-serial devices are a good
  example where there is no defined standard, and a
  driver is needed for every different device from
  different manufacturers.
USB Device Basics
• A USB device is a very complex thing, as described
  in the official USB documentation (available at
  http://www.usb.org).
• Fortunately, the Linux kernel provides a subsystem
  called the USB core to handle most of the
  complexity. This chapter describes the interaction
  between a driver and the USB core.
• USB devices consist of configurations, interfaces,
  and endpoints and how USB drivers bind to USB
  interfaces, not the entire USB device.
1. Endpoints
• The most basic form of USB communication is through
  something called an endpoint.
• A USB endpoint can carry data in only one direction,
  either from the host computer to the device (called an
  OUT endpoint) or from the device to the host computer
  (called an IN endpoint).
• Endpoints can be thought of as unidirectional pipes.
• A USB endpoint can be one of four different types that
  describe how the data is transmitted:
• CONTROL:
• Control endpoints are used to allow access to different
  parts of the USB device.
• They are commonly used for configuring the device,
  retrieving information about the device, sending
  commands to the device, or retrieving status reports
  about the device. These endpoints are usually small in size.
• Every USB device has a control endpoint called “endpoint
  0” that is used by the USB core to configure the device at
  insertion time.
• These transfers are guaranteed by the USB protocol to
  always have enough reserved bandwidth to make it
  through to the device.
• INTERRUPT:
• Interrupt endpoints transfer small amounts of data at a
  fixed rate every time the USB host asks the device for data.
• These endpoints are the primary transport method for USB
  keyboards and mice.
• They are also commonly used to send data to USB devices
  to control the device, but are not generally used to transfer
  large amounts of data.
• These transfers are guaranteed by the USB protocol to
  always have enough reserved bandwidth to make it
  through.
• BULK:
• Bulk endpoints transfer large amounts of data. These endpoints
  are usually much larger (they can hold more characters at once)
  than interrupt endpoints.
• They are common for devices that need to transfer any data that
  must get through with no data loss.
• These transfers are not guaranteed by the USB protocol to always
  make it through in a specific amount of time.
• If there is not enough room on the bus to send the whole BULK
  packet, it is split up across multiple transfers to or from the device.
  These endpoints are common on printers, storage, and network
  devices.
• ISOCHRONOUS:
• Isochronous endpoints also transfer large amounts of data, but
  the data is not always guaranteed to make it through.
• These endpoints are used in devices that can handle loss of data,
  and rely more on keepinga constant stream of data flowing.
• Real-time data collections, such as audio and video devices,
  almost always use these endpoints.
2. Interfaces
• USB endpoints are bundled up into interfaces. USB
  interfaces handle only one type of a USB logical
  connection, such as a mouse, a keyboard, or a
  audio stream.
• Some USB devices have multiple interfaces, such as
  a USB speaker that might consist of two interfaces: a
  USB keyboard for the buttons and a USB audio
  stream.
• Because a USB interface represents basic
  functionality, each USB driver controls an interface;
  so, for the speaker example, Linux needs two
  different drivers for one hardware device.
3. Configurations
• USB interfaces are themselves bundled up into
  configurations.
• A USB device can have multiple configurations and
  might switch between them in order to change the
  state of the device.
• For example, some devices that allow firmware to be
  downloaded to them contain multiple configurations
  to accomplish this.
• A single configuration can be enabled only at one
  point in time.
• Linux does not handle multiple configuration USB
  devices very well, but, thankfully, they are rare.
• USB devices are quite complex and are made up of
  lots of different logical units.
• The relationships among these units can be simply
  described as follows:
A. Devices usually have one or more configurations.
B. Configurations often have one or more interfaces.
C. Interfaces usually have one or more settings.
D. Interfaces have zero or more endpoints.
References
• Websites
  o www.en.wikipedia.org
  o www.slideshare.in

• Books
  o Linux Device Driver
      • By Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman
Thank You!!!

Weitere ähnliche Inhalte

Was ist angesagt?

Computer hardware troubleshooting
Computer hardware troubleshootingComputer hardware troubleshooting
Computer hardware troubleshooting
Jerome Luison
 
Presentation on Operating System & its Components
Presentation on Operating System & its ComponentsPresentation on Operating System & its Components
Presentation on Operating System & its Components
Mahmuda Rahman
 
Linux architecture
Linux architectureLinux architecture
Linux architecture
mcganesh
 
Process management in os
Process management in osProcess management in os
Process management in os
Miong Lazaro
 

Was ist angesagt? (20)

History of Operating system
History of Operating systemHistory of Operating system
History of Operating system
 
Installing driver
Installing driverInstalling driver
Installing driver
 
Boot process
Boot processBoot process
Boot process
 
Linux operating system - Overview
Linux operating system - OverviewLinux operating system - Overview
Linux operating system - Overview
 
Introduction to Operating Systems
Introduction to Operating SystemsIntroduction to Operating Systems
Introduction to Operating Systems
 
Computer hardware troubleshooting
Computer hardware troubleshootingComputer hardware troubleshooting
Computer hardware troubleshooting
 
Presentation on Operating System & its Components
Presentation on Operating System & its ComponentsPresentation on Operating System & its Components
Presentation on Operating System & its Components
 
OS - Process Concepts
OS - Process ConceptsOS - Process Concepts
OS - Process Concepts
 
Motherboard, It's Functions and It's Components
Motherboard, It's Functions and It's ComponentsMotherboard, It's Functions and It's Components
Motherboard, It's Functions and It's Components
 
Bios vs uefi
Bios vs uefiBios vs uefi
Bios vs uefi
 
Linux kernel
Linux kernelLinux kernel
Linux kernel
 
Computer peripheral or Peripheral Devices
Computer peripheral or Peripheral Devices Computer peripheral or Peripheral Devices
Computer peripheral or Peripheral Devices
 
Installing windows 10 and creating a bootable usb
Installing windows 10 and creating a bootable usbInstalling windows 10 and creating a bootable usb
Installing windows 10 and creating a bootable usb
 
Linux architecture
Linux architectureLinux architecture
Linux architecture
 
System software
System softwareSystem software
System software
 
Bios
BiosBios
Bios
 
Disassembling a PC
Disassembling a PCDisassembling a PC
Disassembling a PC
 
Process management in os
Process management in osProcess management in os
Process management in os
 
Linux operating system ppt
Linux operating system pptLinux operating system ppt
Linux operating system ppt
 
Installing Windows-10
Installing Windows-10Installing Windows-10
Installing Windows-10
 

Ähnlich wie Device Drivers

Ähnlich wie Device Drivers (20)

Linux Device Driver,LDD,
Linux Device Driver,LDD,Linux Device Driver,LDD,
Linux Device Driver,LDD,
 
linux device driver
linux device driverlinux device driver
linux device driver
 
Device Drivers and Running Modules
Device Drivers and Running ModulesDevice Drivers and Running Modules
Device Drivers and Running Modules
 
Linux device drivers
Linux device driversLinux device drivers
Linux device drivers
 
Driver Programming Report
Driver Programming ReportDriver Programming Report
Driver Programming Report
 
Course 102: Lecture 25: Devices and Device Drivers
Course 102: Lecture 25: Devices and Device Drivers Course 102: Lecture 25: Devices and Device Drivers
Course 102: Lecture 25: Devices and Device Drivers
 
Linux for embedded_systems
Linux for embedded_systemsLinux for embedded_systems
Linux for embedded_systems
 
Introduction to char device driver
Introduction to char device driverIntroduction to char device driver
Introduction to char device driver
 
Operating System Concepts Presentation
Operating System Concepts PresentationOperating System Concepts Presentation
Operating System Concepts Presentation
 
Distributive operating system
Distributive operating systemDistributive operating system
Distributive operating system
 
Device drivers tsp
Device drivers tspDevice drivers tsp
Device drivers tsp
 
Unit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B Kute
Unit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B KuteUnit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B Kute
Unit 6 Operating System TEIT Savitribai Phule Pune University by Tushar B Kute
 
Os concepts
Os conceptsOs concepts
Os concepts
 
Linux io
Linux ioLinux io
Linux io
 
Part 02 Linux Kernel Module Programming
Part 02 Linux Kernel Module ProgrammingPart 02 Linux Kernel Module Programming
Part 02 Linux Kernel Module Programming
 
Walking around linux kernel
Walking around linux kernelWalking around linux kernel
Walking around linux kernel
 
Linux-Internals-and-Networking
Linux-Internals-and-NetworkingLinux-Internals-and-Networking
Linux-Internals-and-Networking
 
Embedded linux
Embedded linuxEmbedded linux
Embedded linux
 
Lecture 4
Lecture 4Lecture 4
Lecture 4
 
Operating systems (For CBSE School Students)
Operating systems (For CBSE School Students)Operating systems (For CBSE School Students)
Operating systems (For CBSE School Students)
 

Device Drivers

  • 2. Introduction • Defination :- Device driver or software driver is a computer program allowing higher-level computer programs to interact with a hardware device. • A driver typically communicates with the device through the computer bus or communications subsystem to which the hardware connects. • Drivers are hardware-dependent and operating- system-specific. They usually provide the interrupt handling required for any necessary asynchronous time-dependent hardware interface.
  • 3. Why a Device Driver? • A device driver is usually part of the OS kernel o Compiled with the OS o Dynamically loaded into the OS during execution. • Each device driver handles o one device type (e.g., mouse) o one class of closely related devices (e.g., SCSI disk driver to handle multiple disks of different sizes and different speeds.). • A device driver simplifies programming by acting as translator between a hardware device and the applications or operating systems that use it. • Programmers can write the higher-level application code independently of whatever specific hardware device.
  • 6. Processes in Linux • When a user process executes a system call, it does not transfer control to another process, • but changes its execution mode from user to kernel mode. • In kernel mode, while executing the system call, the process has access to the kernel address space, and • Through supporting functions it has access to the address space of the user executing the call.
  • 7. Functions in Device Drivers • Accept abstract read and write requests from the device-independent layer above. • Initialize the device. • Manage power requirements and log events. • Check input parameters if they are valid. • Translate valid input from abstract to concrete terms o e.g., convert linear block number into the head, track, sector and cylinder number for disk access. • Check the device if it is in use (i.e., check the status bit). • Control the device by issuing a sequence of commands. The driver determines what commands will be issued.
  • 8. Loadable Kernel Module • In computing, a loadable kernel module (or LKM) is an object file that contains code to extend the running kernel, or so- called base kernel, of an operating system. • Most current Unix-like systems, and Microsoft Windows, support loadable kernel modules. • Without loadable kernel modules, an operating system would have to have all possible anticipated functionality already compiled directly into the base kernel. • Much of that functionality would reside in memory without being used, wasting memory, and would require that users rebuild and reboot the base kernel every time new functionality is desired. • Most operating systems supporting loadable kernel modules will include modules to support most desired functionality.
  • 9. Classes of Devices and Modules • The Linux way of looking at devices distinguishes between three fundamental device types. • Each module usually implements one of these types, and thus is classifiable as 1.char module 2.block module 3.network module.
  • 10. 1. Character devices • A character (char) device is one that can be accessed as a stream of bytes (like a file); a char driver is in charge of implementing this behavior. • Such a driver usually implements at least the open, close, read, and write system calls. • The text console (/dev/console) and the serial ports (/dev/ttyS0 and friends) are examples of char devices, as they are well represented by the stream abstraction. • Char devices are accessed by means of filesystem nodes, such as /dev/tty1 and /dev/lp0. • The only relevant difference between a char device and a regular file is that you can always move back and forth in the regular file, whereas most char devices are just data channels, which you can only access sequentially.
  • 11. 2.Block devices • Like char devices, block devices are accessed by filesystem nodes in the /dev directory. • A block device is a device (e.g., a disk) that can host a filesystem. • In most Unix systems, a block device can only handle I/O operations that transfer one or more whole blocks, which are usually 512 bytes (or a larger power of two) bytes in length. • Linux, instead, allows the application to read and write a block device like a char device—it permits the transfer of any number of bytes at a time. • As a result, block and char devices differ only in the way data is managed internally by the kernel, and thus in the kernel/driver software interface. • Like a char device, each block device is accessed through a filesystem node, and the difference between them is transparent to the user.
  • 12. 3. Network interfaces • Any network transaction is made through an interface, that is, a device that is able to exchange data with other hosts. • Usually, an interface is a hardware device, but it might also be a pure software device, like the loopback interface. • A network interface is in charge of sending and receiving data packets, driven by the network subsystem of the kernel, without knowing how individual transactions map to the actual packets being transmitted. • Many network connections (especially those using TCP) are stream-oriented, but network devices are, usually, designed around the transmission and receipt of packets. • A network driver knows nothing about individual connections; it only handles packets.
  • 13. Major Minor Numbers • Major device numbers are used by the Linux system to map I/O requests to the driver code, thereby deciding which device driver to execute, when a user reads from or writes to the special file. • The minor numbers are entirely under the control of the driver writer, and usually refer to sub-devices of the device. • These sub-devices may be separate units attached to a controller. Thus, a disk device driver may, for example, communicate with a hardware controller (the device) which has several disk drives (sub- devices) attached.
  • 14. Device Driver Protocol o After driver knows which commands to issue, it starts to write them into controller's device registers . o After writing each command, it checks to see if the controller accepted the command and is prepared to accept the next one. o After commands have been issued, either (a) the device waits until the controller does some work and it blocks itself until interrupt comes to unblock it; or (b) the device doesn't wait because the command finished without any delay.
  • 15. Applications • Because of the diversity of modern hardware and operating systems, drivers operate in many different environments. Drivers may interface with: • Printers • video adapters • network cards • sound cards • local buses of various sorts — in particular, for bus mastering on modern systems • low-bandwidth I/O buses of various sorts (for pointing devices such as mice, keyboards, USB, etc.) • computer storage devices such as hard disk, CD-ROM and floppy disk buses (ATA, SATA, SCSI) • implementing support for different file systems • image scanners • digital cameras
  • 16. Character Device Driver • User Space and Kernel Space • Loading and Removing the driver in user space • Loading and Removing the driver in kernel space • The complete driver “memory”
  • 17. User space and kernel space • When you write device drivers, it’s important to make the distinction between “user space” and “kernel space”. • Kernel Space : Linux (which is a kernel) manages the machine's hardware in a simple and efficient manner, offering the user a simple and uniform programming interface. • In the same way, the kernel, and in particular its device drivers, form a bridge or interface between the end-user/programmer and the hardware. • Any subroutines or functions forming part of the kernel (modules and device drivers, for example) are considered to be part of kernel space.
  • 18. • User space : End-user programs, like the UNIX shell or other GUI based applications (kpresenter for example), are part of the user space. • Obviously, these applications need to interact with the system's hardware . However, they don’t do so directly, but through the kernel supported functions. Device driver events and their associated interfacing functions between kernel space and user space. Events User functions Kernel functions Load module insmod module_init() Open device fopen file_operations: open Close device fread file_operations: read Write device fwrite file_operations: write Close device fclose file_operations: release Remove module rmmod module_exit() Device driver events and their associated functions between kernel space and the hardware device. Events Kernel functions Read data inb Write data outb
  • 19. Loading and Removing the driver in user space • To implement simple character device driver in user space make one file named “demo.c” and content of file is : #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); • Next, you need to generate a makefile. The makefile for this example, which should be named Makefile, will be: obj-m := demo.o • Unlike with previous versions of the kernel, it’s now also necessary to compile the module using the same kernel that you’re going to load and use the module with. To compile it, you can type: make -C /usr/src/kernel-source-2.6.8 M=`pwd` modules
  • 20. In user space, you can load the module as root by typing the following into the command line: # insmod demo.ko The insmod command allows the installation of the module in the kernel. However, this particular module isn’t of much use. It is possible to check that the module has been installed correctly by looking at all installed modules: # lsmod Finally, the module can be removed from the kernel using the command: # rmmod demo By issuing the lsmod command again, you can verify that the module is no longer in the kernel.
  • 21. Loading and Removing the driver in kernel space • When a module device driver is loaded into the kernel, some preliminary tasks are usually performed like resetting the device, reserving RAM, reserving interrupts, and reserving input/output ports, etc. • These tasks are performed, in kernel space, by two functions which need to be present (and explicitly declared): module_init and module_exit; they correspond to the user space commands insmod and rmmod , which are used when installing or removing a module. • To sum up, the user commands insmod and rmmod use the kernel space functions module_init and module_exit.
  • 22. #include <linux/init.h> #include <linux/module.h> #include <linux/kernel.h> MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk("<1> Hello world!n"); return 0; } static void hello_exit(void) { printk("<1> Bye, cruelworldn"); } module_init(hello_init); module_exit(hello_exit);
  • 23. • The actual functions hello_init and hello_exit can be given any name desired. However, in order for them to be identified as the corresponding loading and removing functions, they have to be passed as parameters to the functions module_init and module_exit. • The printk function has also been introduced. It is very similar to the well known printf apart from the fact that it only works inside the kernel. The <1> symbol shows the high priority of the message (low number). In this way, besides getting the message in the kernel system log files, you should also receive this message in the system console. • This module can be compiled using the same command as before, after adding its name into the Makefile and content of it is : “obj-m := demo.o hello.o”.
  • 24. The complete driver “memory”: initial part of the driver • I’ll now show how to build a complete device driver: memory.c. This device will allow a character to be read from or written into it. This device, while normally not very useful, provides a very illustrative example since it is a complete driver; it's also easy to implement,since it doesn’t interface to a real hardware device. • After the #include files, the functions that will be defined later are declared. • The common functions which are typically used to manipulate files are declared in the definition of the file_operations structure. These will also be explained in detail later. Next, the initialization and exit functions—used when loading and removing the module—are declared to the kernel. • Finally, the global variables of the driver are declared: one of them is the major number of the driver, the other is a pointer to a region in memory, memory_buffer, which will be used as storage for the driver data.
  • 25. /* Necessary includes for device drivers */ #include <linux/init.h> #include <linux/config.h> #include <linux/module.h> #include <linux/kernel.h> /* printk() */ #include <linux/slab.h> /* kmalloc() */ #include <linux/fs.h> /* everything... */ #include <linux/errno.h> /* error codes */ #include <linux/types.h> /* size_t */ #include <linux/proc_fs.h> #include <linux/fcntl.h> /* O_ACCMODE */ #include <asm/system.h> /* cli(), *_flags */ #include <asm/uaccess.h> /* copy_from/to_user */ MODULE_LICENSE("Dual BSD/GPL"); /* Declaration of memory.c functions */ int memory_open(struct inode *inode, struct file *filp); int memory_release(struct inode *inode, struct file *filp); ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos); ssize_t memory_write(struct file *filp, char *buf, size_t count, loff_t *f_pos); void memory_exit(void); int memory_init(void); /* Structure that declares the usual file */ /* access functions */ struct file_operations memory_fops = { read: memory_read, write: memory_write, open: memory_open, release: memory_release }; /* Declaration of the init and exit functions */ module_init(memory_init); module_exit(memory_exit); /* Global variables of the driver */ /* Major number */ int memory_major = 60; /* Buffer to store data */ char *memory_buffer;
  • 26. The “memory” driver: connection of the device with its files • In UNIX and Linux, devices are accessed from user space in exactly the same way as files are accessed. These device files are normally subdirectories of the /dev directory. • To link normal files with a kernel module two numbers are used: major number and minor number. The major number is the one the kernel uses to link a file with its driver. The minor number is for internal use of the device and for simplicity it won’t be covered in this article. • To achieve this, a file (which will be used to access the device driver) must be created, by typing the following command as root: • # mknod /dev/memory c 60 0 • In the above, c means that a char device is to be created, 60 is the major number and 0 is the minor number. • Within the driver, in order to link it with its corresponding /dev file in kernel space, the register_chrdev function is used. It is called with three arguments: major number, a string of characters showing the module name, and a file_operations structure which links the call with the file functions it defines. It is invoked, when installing the module, in this way: • Also, note the use of the kmalloc function. This function is used for memory allocation of the buffer in the device driver which resides in kernel space. Its use is very similar to the well known malloc function. Finally, if registering the major number or allocating the memory fails, the module acts accordingly.
  • 27. int memory_init(void) { int result; /* Registering device */ result = register_chrdev(memory_major, "memory", &memory_fops); if (result < 0) { printk( "<1>memory: cannot obtain major number %dn", memory_major); return result; } /* Allocating memory for the buffer */ memory_buffer = kmalloc(1, GFP_KERNEL); if (!memory_buffer) { result = -ENOMEM; goto fail; } memset(memory_buffer, 0, 1); printk("<1>Inserting memory modulen"); return 0; fail: memory_exit(); return result; }
  • 28. The “memory” driver: removing the driver • In order to remove the module inside the memory_exit function, the function unregsiter_chrdev needs to be present. This will free the major number for the kernel. • The buffer memory is also freed in this function, in order to leave a clean kernel when removing the device driver. void memory_exit(void) { /* Freeing the major number */ unregister_chrdev(memory_major, "memory"); /* Freeing buffer memory */ if (memory_buffer) { kfree(memory_buffer); } printk("<1>Removing memory modulen"); }
  • 29. The “memory” driver: opening the device as a file • The kernel space function, which corresponds to opening a file in user space (fopen), is the member open: of the file_operations structure in the call to register_chrdev. In this case, it is the memory_open function. It takes as arguments: an inode structure, which sends information to the kernel regarding the major number and minor number; and a file structure with information relative to the different operations that can be performed on a file. Neither of these functions will be covered in depth within this article. • When a file is opened, it’s normally necessary to initialize driver variables or reset the device. In this simple example, though, these operations are not performed. • The memory_open function can be seen below: int memory_open(struct inode *inode, struct file *filp) { /* Success */ return 0; }
  • 30. The “memory” driver: closing the device as a file • The corresponding function for closing a file in user space (fclose) is the release: member of the file_operations structure in the call to register_chrdev. In this particular case, it is the function memory_release, which has as arguments an inode structure and a file structure, just like before. • When a file is closed, it’s usually necessary to free the used memory and any variables related to the opening of the device. But, once again, due to the simplicity of this example, none of these operations are performed. • The memory_release function is shown below: int memory_release(struct inode *inode, struct file *filp) { /* Success */ return 0; }
  • 31. The “memory” driver: reading the device • To read a device with the user function fread or similar, the member read: of the file_operations structure is used in the call to register_chrdev. This time, it is the function memory_read. Its arguments are: a type file structure; a buffer (buf), from which the user space function (fread) will read; a counter with the number of bytes to transfer (count), which has the same value as the usual counter in the user space function (fread); and finally, the position of where to start reading the file (f_pos). • In this simple case, the memory_read function transfers a single byte from the driver buffer (memory_buffer) to user space with the function copy_to_user:
  • 32. ssize_t memory_read(struct file *filp, char *buf, size_t count, loff_t *f_pos) { /* Transfering data to user space */ copy_to_user(buf,memory_buffer,1); /* Changing reading position as best suits */ if (*f_pos == 0) { *f_pos+=1; return 1; } else { return 0; } } • The reading position in the file (f_pos) is also changed. If the position is at the beginning of the file, it is increased by one and the number of bytes that have been properly read is given as a return value, 1. If not at the beginning of the file, an end of file (0) is returned since the file only stores one byte.
  • 33. The “memory” driver: writing to a device • To write to a device with the user function fwrite or similar, the member write: of the file_operations structure is used in the call to register_chrdev. • It is the function memory_write, in this particular example, which has the following as arguments: a type file structure; buf, a buffer in which the user space function (fwrite) will write; count, a counter with the number of bytes to transfer, which has the same values as the usual counter in the user space function (fwrite); and finally, f_pos, the position of where to start writing in the file. ssize_t memory_write( struct file *filp, char *buf, size_t count, loff_t *f_pos) { char *tmp; tmp=buf+count-1; copy_from_user(memory_buffer,tmp,1); return 1; }
  • 34. The complete “memory” driver • By joining all of the previously shown code, the complete driver is achieved: <memory.c> = <memory initial> <memory init module> <memory exit module> <memory open> <memory release> <memory read> <memory write> • Before this module can be used, you will need to compile it in the same way as with previous modules. The module can then be loaded with: • # insmod memory.ko • It’s also convenient to unprotect the device: • # chmod 666 /dev/memory • If everything went well, you will have a device /dev/memory to which you can write a string of characters and it will store the last one of them. You can perform the operation like this: • $ echo -n abcdef >/dev/memory • To check the content of the device you can use a simple cat: • $ cat /dev/memory • The stored character will not change until it is overwritten or the module is removed.
  • 35. USB Drivers • The universal serial bus (USB) is a connection between a host computer and a number of peripheral devices. • It was originally created to replace a wide range of slow and different buses—the parallel, serial, and keyboard connections—with a single bus type that all devices could connect to. • USB has grown beyond these slow connections and now supports almost every type of device that can be connected to a PC. • The latest revision of the USB specification added high-speed connections with a theoretical speed limit of 480 MBps.
  • 36. • Topologically, a USB subsystem is not laid out as a bus; it is rather a tree built out of several point-to-point links. The links are four-wire cables (ground, power, and two signal wires) that connect a device and a hub, just like twisted-pair Ethernet. • The USB host controller is in charge of asking every USB device if it has any data to send. • Because of this topology, a USB device can never start sending data without first being asked to by the host controller. • This configuration allows for a very easy plugand-play type of system, whereby devices can be automatically configured by the host computer.
  • 37. • The USB protocol specifications define a set of standards that any device of a specific type can follow. • If a device follows that standard, then a special driver for that device is not necessary. • These different types are called classes and consist of things like storage devices, keyboards, mice, joysticks, network devices, and modems. • Other types of devices that do not fit into these classes require a special vendor-specific driver to be written for that specific device. • Video devices and USB-to-serial devices are a good example where there is no defined standard, and a driver is needed for every different device from different manufacturers.
  • 38. USB Device Basics • A USB device is a very complex thing, as described in the official USB documentation (available at http://www.usb.org). • Fortunately, the Linux kernel provides a subsystem called the USB core to handle most of the complexity. This chapter describes the interaction between a driver and the USB core. • USB devices consist of configurations, interfaces, and endpoints and how USB drivers bind to USB interfaces, not the entire USB device.
  • 39. 1. Endpoints • The most basic form of USB communication is through something called an endpoint. • A USB endpoint can carry data in only one direction, either from the host computer to the device (called an OUT endpoint) or from the device to the host computer (called an IN endpoint). • Endpoints can be thought of as unidirectional pipes. • A USB endpoint can be one of four different types that describe how the data is transmitted: • CONTROL: • Control endpoints are used to allow access to different parts of the USB device. • They are commonly used for configuring the device, retrieving information about the device, sending commands to the device, or retrieving status reports about the device. These endpoints are usually small in size.
  • 40. • Every USB device has a control endpoint called “endpoint 0” that is used by the USB core to configure the device at insertion time. • These transfers are guaranteed by the USB protocol to always have enough reserved bandwidth to make it through to the device. • INTERRUPT: • Interrupt endpoints transfer small amounts of data at a fixed rate every time the USB host asks the device for data. • These endpoints are the primary transport method for USB keyboards and mice. • They are also commonly used to send data to USB devices to control the device, but are not generally used to transfer large amounts of data. • These transfers are guaranteed by the USB protocol to always have enough reserved bandwidth to make it through.
  • 41. • BULK: • Bulk endpoints transfer large amounts of data. These endpoints are usually much larger (they can hold more characters at once) than interrupt endpoints. • They are common for devices that need to transfer any data that must get through with no data loss. • These transfers are not guaranteed by the USB protocol to always make it through in a specific amount of time. • If there is not enough room on the bus to send the whole BULK packet, it is split up across multiple transfers to or from the device. These endpoints are common on printers, storage, and network devices. • ISOCHRONOUS: • Isochronous endpoints also transfer large amounts of data, but the data is not always guaranteed to make it through. • These endpoints are used in devices that can handle loss of data, and rely more on keepinga constant stream of data flowing. • Real-time data collections, such as audio and video devices, almost always use these endpoints.
  • 42. 2. Interfaces • USB endpoints are bundled up into interfaces. USB interfaces handle only one type of a USB logical connection, such as a mouse, a keyboard, or a audio stream. • Some USB devices have multiple interfaces, such as a USB speaker that might consist of two interfaces: a USB keyboard for the buttons and a USB audio stream. • Because a USB interface represents basic functionality, each USB driver controls an interface; so, for the speaker example, Linux needs two different drivers for one hardware device.
  • 43. 3. Configurations • USB interfaces are themselves bundled up into configurations. • A USB device can have multiple configurations and might switch between them in order to change the state of the device. • For example, some devices that allow firmware to be downloaded to them contain multiple configurations to accomplish this. • A single configuration can be enabled only at one point in time. • Linux does not handle multiple configuration USB devices very well, but, thankfully, they are rare.
  • 44. • USB devices are quite complex and are made up of lots of different logical units. • The relationships among these units can be simply described as follows: A. Devices usually have one or more configurations. B. Configurations often have one or more interfaces. C. Interfaces usually have one or more settings. D. Interfaces have zero or more endpoints.
  • 45. References • Websites o www.en.wikipedia.org o www.slideshare.in • Books o Linux Device Driver • By Jonathan Corbet, Alessandro Rubini, and Greg Kroah-Hartman