0% found this document useful (0 votes)
16 views27 pages

Char Drivers

Uploaded by

langorerohan57
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as ODP, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views27 pages

Char Drivers

Uploaded by

langorerohan57
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as ODP, PDF, TXT or read online on Scribd
You are on page 1/ 27

Linux Device Drivers

– Char Drivers
Agenda

● Introduction to Device Drivers


● Char Drivers
Introduction to Device Drivers
Role of a Device Driver

User Application
● Interaction with user apps
● Interaction with hardware
● Interaction with the kernel
● Logic Management
Kernel Device Driver ● Buffer Management
● Concurrency issues

Hardware
Classification of Device Drivers

● Classes of Device Drivers :


– Character Drivers
– Block Drivers
– Network Drivers
Char Drivers
Char Drivers

● Device Numbers
● Allocating and Freeing Device Numbers
● Char Device Registration
● Important Data Structures
● File Operations
Anatomy of Char Drivers

User Application
Accessed using the
name of the file

Device node in
/dev
Accessed using the
device number

Kernel Device Driver

Hardware
Device Numbers

● Device numbers :
– Major number : Identifies the driver associated with the device
– Minor number : Distinguishes amongst devices of the driver
● ls -l /dev
Device Number Representation
● 'dev_t' holds the device number
Major : a Major : a ● It is a 32-bit quatity :
Minor : x Minor : y
– Major : 12-bits
– Minor : 20-bits
/dev/cdev0 /dev/cdev1
● Device no. to :
– Major : MAJOR(dev_t dev);
– Minor : MINOR(dev_t dev);

Major:Minor to dev_t :
Device Driver

– MKDEV(int major, int minor);


Allocating and Freeing Device Numbers

● Obtain one or more devices to work with


:
– Include <linux/fs.h>
– Statically :
int register_chrdev_region(dev_t first,
unsigned int count,

const char *name);


– Dynamically :
int alloc_chrdev_region(dev_t *dev,
unsigned int firstminor,
unsigned int count,
Char Device Registration

● Kernel uses structures of type struct cdev


(linux/cdev.h) to represent char devices internally.
● Two step process :
– Allocate and initialise the char device :
void cdev_init(struct cdev *cdev, struct
file_operations *fops);
– Inform the kernel about the device :
int cdev_add(struct cdev *dev, dev_t num,
unsigned int count);
● Remove the char device from the system :
void cdev_del(struct cdev *dev);
Creation of device nodes

● Applications in the user-space can refer to a


device by creating a device file(or node)
in /dev of the filesystem
● # mknod /dev/node_name device_type
major minor --mode=perm
● Ex :
# mknod /dev/myDev c 249 0 --mode=0666
Important Data Structures

● struct file
● struct inode
● struct file_operations
struct file

● Represents an open file.


● Created by the kernel on open and is passed to
any function that operates on the file, until the last
close.
● For every instance of an open file, a struct file is
created.
● Each file can have multiple struct file, depending on
the number of times it has been opened.
struct file

<linux/fs.h>
struct file {
...
unsigned int f_flags;
struct file_operations *f_op;
void *private_data;
};
struct inode

● Used by the kernel to represent files, no matter


open or close.
● It basically holds the file's properties.
● Unlike struct file, it has got only one instance, even
though the file has been opened any number of
times.
struct inode

<linux/fs.h>
struct inode {
...
dev_t i_rdev;
struct cdev *i_cdev;
};
struct inode Vs struct file

struct file filp_1; struct file filp_2 struct file filp_3;

App-1 App-2 App-3

open()
open()
open()

struct inode ind;


struct file_operations

<linux/fs.h>
struct file_operations {
...
int (*open) (struct inode *, struct file *);
ssize_t (*read) (struct file *, char __user *, size_t, loff_t *);
ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *);
int (*release) (struct inode *, struct file *);
};
struct file_operations : open()

● int (*open) (struct inode *, struct file *);


● Check for device-specific errors (such as device-not-
ready or similar hardware problems)
● Initialize the device if it is being opened for the first
time
● Acquire the resources
● Allocate and fill any data structure to be put in filp-
>private_data
● Returns :
● 0 : Success
● Negative value, for any errors
struct file_operations : release()

● int (*release) (struct inode *, struct file *);


● Used to release access from the requested device.
● Deallocate anything that open() allocated
● Shutdown the device.
struct file_operations : read()

● ssize_t (*read) (struct file *, char __user *, size_t,


loff_t *);
● Interacts with the user-space application and
implements the read functionality for the user-space.
● Copies data from the kernel space to the user-space
by :
– <linux/uaccess.h>
unsigned long copy_to_user(void __user *to,
const void *from, unsigned long count);
● Returns :
– No. of bytes copied to the user
– Negative value on an error
struct file_operations : write()

● ssize_t (*write) (struct file *, const char __user *, size_t,


loff_t *);
● Interacts with the user-space application and
implements the write functionality for the user-space.
● Copies data from the user-space to the kernel space
by :
– <linux/uaccess.h>
unsigned long copy_from_user(void *to,
const void __user *from, unsigned
long count);
● Returns :
– No. of bytes copied from the user
– Negative value on an error
file_operations : read & write

User Application

write() read()

Device node in
/dev
write() read()
{ {
copy_from_user(); copy_to_user();
} }
Device Driver
References

● Jonathan Corbet, Alessandro Rubini and Greg


Kroah-Hartman,”Linux Device Drivers”,3rd Edition,
O'Reilly Publications
● www.google.com
Thank You :)

You might also like