EmbLogic's Blog

Device Drivers in OS Environment

DEVICE DRIVER ::A device driver is a software, it’s not a hardware. A driver is a code which is completely specific to a hardware device and brings all the functionality to it. Without a driver in OS environment an application can’t make use of the hardware functionalities. Driver has to be in the kernel space in the case of monolithic kernel. It has to be in the privileged environment, it is so because in the privileged space/kernel space only the driver code has the ability to perform operations on the hardware. This kind of code can also be written for micro controllers where there is no OS.
Applications reside in a non privileged environment and have to rely on services provided by drivers to access the hw. This is done to reduce complexity and making the use of information hiding that is encapsulating and providing abstraction, so as to make the applications easier and safer to write in less time. In linux the drivers are the kernel services to access the hw functionalities.

OS KERNEL :: The operating system is not what you see on your display device or your monitor. The operating system consists of a kernel(the soul of your system), shell and utility programs or api to
access services and interacting with the hardware. The most important part rather the soul of an operating system is it’s kernel. The kernel’s job is to manage memory, do task scheduling, bring functionality to the device through device drivers and provide services for interprocess communication.
The kernel may be MONOLITHIC or a MICRO KERNEL. A monolithic kernel is a kernel where every part of the it is just build into it as a unit and has a disadvantage that if any thing goes wrong with any part of the kernel code that may be for example a device driver code trying to dereference an invalid address the whole SYSTEM crashes. Micro kernels have an advantage over this, as the device drivers and rest of the kernel services lie out side the kernel space and kernel just supervises each of the operations as a server and whole of the kernel is based on CLIENT AND SERVER computing model. Thus the kernel has less probability to crash.

DEVICE DRIVERS :: We use peripheral devices. These are the mouse, keyboard, printer, Network devices to send and receive network information. These devices are not directly connected to the cpu through a bus, they are first connected to a controller or a bridge device (Device IO controller) through a bus that is referred to as peripheral bus. The device IO controller may be UART controller, USB controller, VGA controller, NETWORK controller etc. This controller is again further connected to the processor through the controller bus (in case of a PC set up).
Example :: USB is a peripheral bus and PCI is a controller bus.

DEVICE DRIVER LOGIC :: We cannot directly perform operations on the device as we have the device controller in between. We need to give commands to the controller. Then on behalf of the our code the controller will do the job. Thus our first issue is to send commands to the controller according to the functionalities offered by the device. We must know what all operations this device can support or simply options on the device.
Thus our driver code is broken up into two parts ::

#1 Low Level Driver (LLD):: Interfacing with the controller.(This code remains the same for a specific controller)

#2 High Level Driver (HLD) :: Code specific to the peripheral device functionality.(Without the knowledge of which device you are talking we can’t write this code.)

Interfacing with the controller is called the low level drive. The low level drivers provide the code to interact with the controllers. The high level drivers are only about what to execute on the device.

We need this kind of division because there are different controllers on different architectures. The usb controller for example may be different on different on different boards. If we mix both HLD and LLD in one code our driver will never be portable, will not be able to reuse our code. But if we divide this logically the HLD can remain same while the LLD can differ. The HLD must remain absolutely controller independent and reusable.

To make HLD independent of hw we hide the details of LLD and call it BUS MANAGER. The bus manager is similar to the virtual file system which is an abstraction hiding all the complexities of othe file systems.

Writing low level driver is writing board bring up driver. We have two domains of device driver community BSP driver community and and PERIPHERAL driver community. Simply BSP driver community write LLD and PERIPHERAL driver community write HLD.

In PC domain we don’t really have to worry about the LLD because it comes along with the kernel sources. But in the embedded domain we may have write a little bit of LLD.

HIGH LEVEL DRIVERS :: The high level drivers or the peripheral device drivers reside in the kernel space. The applications are in the user space which use these drivers. Now we have to provide an interface through which the applications can request like do this operation do that operation. Also we communicate with the hard ware which done through the API of low level driver. Now writing this driver is also broken down into two parts.

#1 Interfacing with the application.(This code is specific to design of kernel)(SYS CALLS in Linux)
#2 Interaction with hardware.(This code is specific to bus manager)

Exploring the interaction with hardware requires the reading and understanding of kernel sources.

Linux provides three different approaches for writing interfacing with the application.
Linux Driver Classes =
#1 CHARACTER DRIVER MODEL
#2 BLOCK DRIVER MODEL
#3 NETWORK DRIVER MODEL

The approach we choose depends upon two factors.
#1 Synchronous communication.
#2 Asynchronous communication.

Asynchronous means :: An application will not directly interact with the driver instead it will submit a request and go back. The driver will then carry out the operations. Application will either poll for the operation to be done or the driver will send a signal to the application that the job is done.

Synchronous means :: An application will make a call to a function and wait for it to return.

Example :: A char driver can be for pci bus, it can be on usb bus and so on.

Ankit

15/02/11

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>