They are not normal “files”, but look like files from the program’s point of view: you can read from them, write to them, mmap() onto them, and so forth.When you access such a device “file,” the kernel recognizes the I/O request and passes it a device driver, which performs some operation, such as reading data from a serial port, or sending data to a hardware.
All device files are stored in
/dev
directory. Use ls command to browse the directory:ls -l /dev/
/dev
. For example, /dev/ttyS0
corresponds to the first serial port, known as COM1 under MS-DOS; /dev/hda2
corresponds to the second partition on the first IDE drive.There are a number of pseudo-devices in
/dev
that don’t correspond to any actual peripheral. For example, /dev/null
acts as a byte sink; any write request to /dev/null
will succeed, but the data written will be ignored.
When using
ls -l
to list device files in /dev
, you’ll see something like the following:crw--w---- 1 root tty 4, 0 Aug 15 10:40 tty0
brw-rw---- 1 root disk 1, 0 Aug 15 10:40 ram0
First of all, note that the first letter of the permissions field is denoted that driver type. Device files are denoted either by b, for block devices, or c, for character devices.
Also, note that the size field in the ls -l
listing is replaced by two numbers, separated by a comma. The first value is the major device number and the second is the minor device number.Creating Device File
We can create the dive file in two ways.
- Manually
- Automatically
We will see one by one.
Manually Creating Device File
We can create the device file manually by using
mknod
.mknod -m <permissions> <name> <device type> <major> <minor>
c – Character Device
b – Block Device
-m <permissions> – optional argument that sets the permission bits of the new device file to permissions
Example:
sudo mknod -m 666 /dev/etx_device c 246 0
If you don’t want to give permission, You can also use chmod to set the permissions for a device file after creation.
Automatically Creating Device File
The automatic creation of device files can be handled with udev. Udev is the device manager for the Linux kernel that creates/removes device nodes in the /dev directory dynamically.
Just follow the below steps.
- Include the header file linux/device.h and linux/kdev_t.h
- Create the struct Class
- Create Device with the class which is created by above step
Create the class
This will create the struct class for our device driver. It will create structure under
/sys/class/
.struct class * class_create (struct module *owner, const char *name);
owner – pointer to the module that is to “own” this struct class
name – pointer to a string for the name of this class
This is used to create a struct class pointer that can then be used in calls to
class_device_create
.
Note, the pointer created here is to be destroyed when finished by making a call to
class_destroy
.void class_destroy (struct class * cls);
Create Device
This function can be used by char device classes. A struct device will be created in sysfs, registered to the specified class.
struct device *device_create (struct *class, struct device *parent,
dev_t dev, const char *fmt, ...);
class – pointer to the struct class that this device should be registered to
parent – pointer to the parent struct device of this new device, if any
devt – the dev_t for the char device to be added
fmt – string for the device’s name
… – variable arguments
#include
#include
#include
#include
#include
#include
dev_t dev = 0;
static struct class *dev_class;
static int __init hello_world_init(void)
{
/*Allocating Major number*/
if((alloc_chrdev_region(&dev, 0, 1, "etx_Dev")) <0){
printk(KERN_INFO "Cannot allocate major number for device\n");
return -1;
}
printk(KERN_INFO "Major = %d Minor = %d \n",MAJOR(dev), MINOR(dev));
/*Creating struct class*/
if((dev_class = class_create(THIS_MODULE,"etx_class")) == NULL){
printk(KERN_INFO "Cannot create the struct class for device\n");
goto r_class;
}
/*Creating device*/
if((device_create(dev_class,NULL,dev,NULL,"etx_device")) == NULL){
printk(KERN_INFO "Cannot create the Device\n");
goto r_device;
}
printk(KERN_INFO "Kernel Module Inserted Successfully...\n");
return 0;
r_device:
class_destroy(dev_class);
r_class:
unregister_chrdev_region(dev,1);
return -1;
}
void __exit hello_world_exit(void)
{
device_destroy(dev_class,dev);
class_destroy(dev_class);
unregister_chrdev_region(dev, 1);
printk(KERN_INFO "Kernel Module Removed Successfully...\n");
}
module_init(hello_world_init);
module_exit(hello_world_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("EmbeTronicX
MODULE_DESCRIPTION("A simple hello world driver");
MODULE_VERSION("1.2");
|
- Build the driver by using Makefile (
sudo make
) - Load the driver using
sudo insmod
- Check the device file using
ls -l /dev/ | grep "etx_device"
linux@embetronicx-VirtualBox:/home/driver/driver$ ls -l /dev/ | grep "etx_device"
crw------- 1 root root 246, 0 Aug 15 13:36 etx_device
- Unload the driver using
sudo rmmod
No comments:
Post a Comment