ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

04-最简单的字符设备驱动

04-最简单的字符设备驱动

设备驱动分类

linux设备驱动一般分为3类,字符设备,块设备,网络设备。前两个在/dev目录下有对应的设备节点,网络设备比较特殊,没有。通过ls -l /dev/xx可以看出设备类型:

thammer@test:~$ ls -l /dev/nvme0n1
brw-rw---- 1 root disk 259, 0 10月  9 08:59 /dev/nvme0n1
thammer@test:~$ ls -l /dev/tty
crw-rw-rw- 1 root tty 5, 0 10月 10 15:25 /dev/tty

b开头的表示块设备(block),以c开头的表示字符设备(character)。块设备一般是指硬盘(HDD),固态硬盘(SSD),移动存储介质如SD卡,TF卡,U盘等,其他拥有设备节点的驱动基本都属于字符设备。暂时仅关注字符设备驱动。

极简字符设备驱动

#include <linux/module.h>
#include <linux/fs.h>// 主设备号
static int major;
static char devName[] = "mychardev";// 对应应用空间的open系统调用
static int chardev_open(struct inode *inode, struct file *file)
{printk(KERN_INFO "chardev open\n");return 0;
}// 对应应用空间的close系统调用
static int chardev_release(struct inode *inode, struct file *file)
{printk(KERN_INFO "chardev release\n");return 0;
}// 字符设备驱动对应的文件操作结构
static struct file_operations fOpts = {.owner = THIS_MODULE,.open = chardev_open,.release = chardev_release
};//加载内核模块后的入口函数
static int __init chardev_drv_init(void)
{printk(KERN_INFO "chardev driver init\n");//向内核注册字符设备驱动major = register_chrdev(0, devName, &fOpts);if (major < 0){printk(KERN_ERR "chardev driver regist\n");return major;}printk(KERN_INFO "got major:%d\n", major);return 0;
}//卸载内核模块后的清理函数
static void __exit chardev_drv_exit(void)
{//向内核注销字符设备驱动unregister_chrdev(major, devName);printk(KERN_INFO "chardev driver exit\n");
}module_init(chardev_drv_init);
module_exit(chardev_drv_exit);MODULE_LICENSE("GPL");

编译该字符设备驱动的Makfile:

KERN_DIR=/usr/src/linux-headers-$(shell uname -r)all:make -C ${KERN_DIR} M=$(shell pwd) modulesclean:make -C ${KERN_DIR} M=$(shell pwd) modules cleanobj-m += chardev_drv.o

编译后,插入驱动模块

make
sudo insmod chardev_drv.ko

通过dmesg可以看到内核日志输出:

[ 5476.132713] chardev driver init
[ 5476.132717] got major:237

到此应用程序如果要操作这个驱动,还缺乏对应的设备节点。这里需要我们手动创建设备节点:

sudo mknod /dev/testchardev c $(cat /proc/devices | grep mychardev | awk '{print $1}') 0

mknode命令用于手动创建设备节点,其命令创建设备节点的格式为:

mknod [选项]... 节点路径 类型 [主设备号 次设备号]
  • 选项:一般可以通过-m指定创建的设备节点的文件权限。也可以在创建后通过chmod修改。
  • 节点路径:习惯位于/dev下面或者其子目录,但是这仅仅是一个习惯而已,实际如果你想要,可以是任意位置。
  • 类型:就是c,b等,还可以是比较少见的p或者up表示管道,uc等价。
  • 主,次设备号:当类型为p时不能指定主,次设备号,其他类型时,必须指定。
返回列表