First, write the driver file
#include <linux/init.h> // A header file that all modules must include
#include <linux/module.h> // Some macro definitions, such as KERN_INFO here
#include <linux/fs.h>
#include < linux/device.h>
#include <linux/cdev.h>
#include "hello_world.h"
#define VICHIP_DEV "vichip"
static struct class *driver_class; // 定义类static dev_t vichip_device_no; // 定义设备号
// 定义结构体
struct vichip_control {
struct cdev cdev;
};
static struct vichip_control vichip;
static int vichip_open(struct inode *inode, struct file *file)
{
int ret = 0; printk(KERN_INFO "----vichip_open----\n"); return ret; } static int vichip_release(struct inode *inode, struct file *file) { int ret = 0; printk(KERN_INFO "----vichip_release----\n"); return ret; } static const struct file_operations vichip_fops = { .owner = THIS_MODULE, .open = vichip_open,
.release = vichip_release
};
static int __init hello_init(void)
{
int rc;
struct device *class_dev; rc = alloc_chrdev_region(&vichip_device_no, 0, 1, VICHIP_DEV); // dynamically allocate device number if (rc < 0) { pr_err( "alloc_chrdev_region failed %d\n", rc); return rc; } driver_class = class_create(THIS_MODULE, VICHIP_DEV); // create class if (IS_ERR(driver_class)) { rc = -ENOMEM; pr_err("class_create failed %d\ n", rc); goto exit_unreg_chrdev_region; } class_dev = device_create(driver_class, NULL, vichip_device_no, NULL, VICHIP_DEV); // create a device (which class of device this device belongs to) if (IS_ERR(class_dev)) {
pr_err("class_device_create failed %d\n", rc);
rc = -ENOMEM;
goto exit_destroy_class;
} cdev_init(&vichip.cdev, &vichip_fops); // initialize character device vichip.cdev.owner = THIS_MODULE; rc = cdev_add(&vichip .cdev, MKDEV(MAJOR(vichip_device_no), 0), 1); // add a character device to the kernel if (rc < 0) { pr_err("cdev_add failed %d\n", rc); cdev_del(&vichip. cdev); // remove character device from kernel goto exit_destroy_device; } printk(KERN_INFO "----hello_init rc = [%d]----\n", rc); return rc; exit_destroy_device: device_destroy( driver_class, vichip_device_no); // Destroy the device exit_destroy_class: class_destroy (driver_class); // Destroy the class
exit_unreg_chrdev_region:
unregister_chrdev_region(vichip_device_no, 1); // unregister the dynamically allocated device number
return rc;
}
static void __exit hello_exit(void)
{
cdev_del(&vichip.cdev);
device_destroy(driver_class, vichip_device_no); class_destroy
(driver_class);
unregister_chrdev_region( vichip_device_no, 1); printk(KERN_INFO "----hello_exit----\n"); } module_init(hello_init);// The macro is used to specify the entry, and the loading function in the module will be called when the module is loaded module_exit(hello_exit ); // the module's license MODULE_LICENSE("GPL"); // the module's author MODULE_AUTHOR(DRIVER_AUTHOR); // the module's description
MODULE_DESCRIPTION(DRIVER_DESC);
Second, the header file hello_world.h
#define DRIVER_AUTHOR "[email protected]"
#define DRIVER_DESC "A sample driver"
3. Write Makefile
ifeq ($(KERNELRELEASE),)
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
clean:
$(MAKE) -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
else
obj-m := hello_world.o
endif
Fourth, compile the module
make all
Five, install the kernel module
insmod hello_world.ko
Six, write the test file test.c
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#define DEV_NAME "/dev/vichip"
int main(int argc, char *argv[])
{
int fd = -1;
printf("------------start---------------\n");
if(fd < 0)
{
perror("open file error:");
return -1;
}
close(fd);
printf("------------end---------------\n");
}
Seven, compile the test file
gcc test.c -o test
Eight, test driver
./test
9. Test results
1. View the created class
Result: There is a vichip directory in the /sys/class directory.
2. View the created device
Result: there are vichip device files in the /dev directory
crw------- 1 root root 243, 0 May 9 16:42 vichip
or cat /proc/devices
243 vichip
3. View the output message
dmesg
----hello_init rc = [0]----
4. Uninstall installed kernel modules
rmmod hello_world
Do the following:
cdev_del(&vichip.cdev);
device_destroy(driver_class, vichip_device_no);
class_destroy(driver_class);
unregister_chrdev_region(vichip_device_no, 1);