Device drivers cs423 fall 2007
Download
1 / 31

Device Drivers cs423, Fall 2007 - PowerPoint PPT Presentation


  • 135 Views
  • Updated On :

Device Drivers cs423, Fall 2007. Klara Nahrstedt/Sam King. I/O Software. Layers of the I/O system and the main functions of each layer. I/O Software Layer: Principle. Interrupts are facts of life, but should be hidden away, so that as little of the OS as possible knows about them.

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'Device Drivers cs423, Fall 2007' - elinor


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
Device drivers cs423 fall 2007 l.jpg

Device Driverscs423, Fall 2007

Klara Nahrstedt/Sam King


I o software l.jpg
I/O Software

Layers of the I/O system and the main functions of each layer


I o software layer principle l.jpg
I/O Software Layer: Principle

  • Interrupts are facts of life, but should be hidden away, so that as little of the OS as possible knows about them.

  • The best way to hide interrupts is to have the driver starting an IO operation block until IO has completed and the interrupt occurs.

  • When interrupt happens, the interrupt handler handles the interrupt.

  • Once the handling of interrupt is done, the interrupt handler unblocks the device driver that started it.

  • This model works if drivers are structures as kernel processes with their own states, stacks and program counters.


Device drivers l.jpg
Device Drivers

  • Device-specific code to control an IO device, is usually written by device's manufacturer

  • A device driver is usually part of the OS kernel

    • Compiled with the OS

    • Dynamically loaded into the OS during execution

  • Each device driver handles

    • one device type (e.g., mouse)

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

  • Categories:

    • Block devices

    • Character devices


Functions in device drivers l.jpg
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

    • 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.


Device driver protocol l.jpg
Device Driver Protocol

  • After driver knows which commands to issue, it starts to write them into controller's device registers

  • After writing each command, it checks to see if the controller accepted the command and is prepared to accept the next one.

  • 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.


Device driver discussion l.jpg
Device Driver Discussion

  • Protocol – simple model, estimation of reality

  • Code is much more complicated, e.g.,

    • I/O device completes while a driver is running, interrupting the driver; causing driver to run before the first call has finished

    • Consider network driver: which network driver is processing incoming packet, a new packet arrives; hence the driver code must be reentrant, i.e., running driver must expect that it will be called a second time before the first call has completed.

  • Code needs to handle pluggable devices

    • If driver is busy reading from some device, and the user removed suddenly the device from the system, driver must

      • Abort the current I/O transfer without damaging any kernel data structures

      • Remove gracefully from the system any pending requests for the now-vanished device, and give their callers the bad news

      • Handle unexpected addition of new devices which may cause the kernel to juggle resources

  • Drivers are not allowed to make system calls, but they may call kernel procedures

    • Example:

      • Allocate and de-allocate hardwired pages of memory for use of buffers

      • Manage MMU, timers, DMA controller, interrupt controller, etc.


Linux device driver l.jpg
Linux Device Driver

  • Structure of Linux Device Driver Support

  • Special Files

  • Virtual File System Switch

  • Appendix:

    • Support Functions

    • Installing the Device Driver



Processes in linux l.jpg
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.



Special files l.jpg
Special Files

  • All devices look like files on a Linux system.

  • The user-level interface to a device is called a special file.

  • These special files (often called device nodes) reside in the /dev directory.

  • For example, invoking the command ls -l /dev/lp* can be used to yield the following status information:

    crw-rw-rw 1 root root 6, 0 April 23 1994 /dev/lp0

  • This example indicates that: lp0 is a character type device (the first letter of the file mode field is c), the major number is 6, and minor device number 0 is assigned to the device.


Major minor numbers l.jpg
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 features l.jpg
Device Driver Features

  • A set of routines that communicate with a hardware device and provide a uniform interface to the operating system kernel.

  • A self-contained component that can be added to, or removed from, the operating system dynamically.

  • Management of data flow and control between user programs and a peripheral device.

  • A user-defined section of the kernel that allows a program or a peripheral device to appear as a /dev device to the rest of the system's software.


Operation l.jpg
Operation

  • One way that processes can coordinate their actions with events is through sleep() and wakeup() system calls.

  • When a process goes to sleep, it specifies an event that must occur, that is, wakeup, before it can continue its task. For example:

    interruptible_sleep_on(&dev_wait_queue)

  • causes the process to sleep and adds the process number to the list of processes sleeping on dev_wait_queue .

  • When the device is ready, it posts an interrupt, causing the interrupt service routine in the driver to be activated.

  • The routine services the device and issue a corresponding wakeup call, for example,

    wake_up_interruptible(&dev_wait_queue),

  • which wakes up the process sleeping on dev_wait_queue .


Critical sections l.jpg
Critical Sections

  • Interrupts are disabled by cli() while the process is operating in the critical section and re-enabled by sti() upon exit from the critical section, as in:

    cli()

    Critical Section Operations

    sti()



Registering file system ops l.jpg
Registering File System Ops

struct file_operations xxx_fops = {

NULL, /* lseek() */

xxx_read, /* read() */

xxx_write, /* write() */

NULL, /* readdir() */

NULL, /* select() */

xxx_ioctl, /* ioctl() */

NULL, /* mmap() */

xxx_open, /* open() */

xxx_close /* close() */ };

long xxx_init(long kmem_start) {

printk("Sample Device Driver Initialization\n");

if (register_chrdev(22, "xxx", &xxx_fops))

printk("error--cannot register to major device 22!\n");

/* detect hardware and initialize it */

return kmem_start;

}


Names l.jpg
Names

  • The name of the driver should be a short string.

  • For instance, the parallel (printer) device is the ``lp'' device, the floppies are the ``fd'' devices, and the SCSI disks are the ``sd'' devices.

  • To avoid name space confusion, the entry point names are formed by concatenating this unique driver prefix with a generic name that describes the routine. For instance, xxx_open() is the ``open'' routine for the ``xxx'' driver.


Data transfer l.jpg
Data Transfer

  • The transfer of data between the memory accessible to the kernel and the device itself is machine-dependent.

  • Some machines require that the CPU execute special I/O instructions to move data between a device register and addressable memory--often called direct memory access (DMA).

  • Another scheme, known as memory mapped I/O, implements the device interface as one or more locations in the memory address space.

  • The most common method uses I/O instructions, provided by the system to allow drivers access the data in a general way.

  • Linux provides inb() to read a single byte from an I/O address (port) and outb() to write a single byte to an I/O address. The calling syntax is shown here:

    unsigned char inb(int port); outb(char data, int port)


Example driver l.jpg
Example Driver

/* system include files */

#include "linux/kernel.h"

#include "linux/sched.h"

#include "linux/tty.h"

#include "linux/signal.h"

#include "linux/errno.h"

#include "asm/io.h"

#include "asm/segment.h"

#include "asm/system.h"

#include "asm/irq.h"

static int

xxx_write(struct inode *inode, struct file *file, char *buffer,int count) {

unsigned int minor=MINOR(inode->i_rdev);/*minor number of device */

int offset = 0;

char ret;


Example driver23 l.jpg
Example Driver

if (count > 4095)

return(-ENOMEM);

if (count <= 0)

return(-EINVAL);

while (count > 0) {

ret = xxx_write_byte(minor);

if (ret < 0) {

xxx_handle_error(WRITE, ret, minor);

continue;

}

buff++ = ret; offset++;

}

return offset; /* return number of bytes written */

/* xxx_write_byte() and xxx_handle_error() are functions defined elsewhere in xxx_drv.c */

}


Device driver initialization l.jpg
Device Driver Initialization

  • In order that the device driver is correctly initialized when the operating system is booted, the xxx_init() routine must be executed.

  • To ensure this happens, add the following line to the end of the chr_drv_init() function in the /usr/src/linux/driver/char/mem.c file:

    mem_start = xxx_init(mem_start);

  • and resave the file back to disk.


Appendix l.jpg
Appendix

  • Support Functions

  • Installing the Device Driver





Installing the driver in the kernel l.jpg
Installing the Driver in the Kernel

A character device driver has to be archived into the /usr/src/linux/drivers/char/char.a library. The following steps are required to link the driver to the kernel:

  • Put a copy of the source file (say xxx_drv.c ) in the /usr/src/linux/drivers/char directory.

  • Edit Makefile in the same directory so it will compile the source for the driver--add xxx_drv.o to the OBJS list, which causes the make utility to automatically compile xxx_drv.c and add the object code to the char.a library archive.

  • The last step is the recompilation of the kernel.


Recompile the linux kernel l.jpg
Recompile the Linux kernel

  • Log in as root

  • Change to the /root/linux directory

  • Carry out the following series of commands

    • make clean ; make config to configure the basic kernel

    • make dep to set-up the dependencies correctly

    • make to create the new kernel

  • Wait for the kernel to compile and go to the /usr/src/linux directory.

  • In order to boot the new kernel, copy the new kernel image ( /usr/src/linux/zImage ) into the place where the regular bootable kernel is found.


Device file creation l.jpg
Device File Creation

  • In order to access the device using system calls, a special file is created. The driver files are normally stored in the /dev directory of the system. The following commands create the special device file:

  • mknod /dev/xxx c 22 0

    • Creates a special character file named xxx and gives it major number 22 and minor number 0.

  • chmod 0666 /dev/xxx

    • Ensures that every user in the system has read/write access to the device.


ad