Linux内核之misc框架
2022/2/27 7:23:37
本文主要是介绍Linux内核之misc框架,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
Linux内核为每种设备都抽象出了框架,开发人员只需往框架中填充信息即可进行设备的注册。下面来讲解一下Linux内核的misc框架。
misc又叫杂散类设备,在早期的内核中,向ADC、WATCHDOG、PWM等设备都没有一个明确的框架,于是这些设备就都归类到了misc框架。在后来内核版本中才逐步完善各种设备框架。下面就来简单了解一下misc设备的框架,以及使用misc框架来写一个测试驱动。
- misc框架代码
static int __init misc_init(void) { int err; #ifdef CONFIG_PROC_FS proc_create("misc", 0, NULL, &misc_proc_fops); #endif misc_class = class_create(THIS_MODULE, "misc"); // 创建类,类名叫misc err = PTR_ERR(misc_class); if (IS_ERR(misc_class)) goto fail_remove; err = -EIO; if (register_chrdev(MISC_MAJOR,"misc",&misc_fops)) // 注册misc字符设备,设备号是10 goto fail_printk; misc_class->devnode = misc_devnode; return 0; fail_printk: printk("unable to get major %d for misc devices\n", MISC_MAJOR); class_destroy(misc_class); fail_remove: remove_proc_entry("misc", NULL); return err; }
misc_init函数是初始化misc框架,首先会先创建一个叫misc的类,然后在这个类中注册一个叫misc的设备,设备号是10。
可以看到在内核中,通过命令可以查看misc设备的主设备号是10,在class中有一个叫misc的类。
int misc_register(struct miscdevice * misc) { dev_t dev; int err = 0; INIT_LIST_HEAD(&misc->list); mutex_lock(&misc_mtx); if (misc->minor == MISC_DYNAMIC_MINOR) { // 判断次设备是否为255,如果是就自动分配次设备号,否则就使用开发人员传进来的次设备号 int i = find_first_zero_bit(misc_minors, DYNAMIC_MINORS); if (i >= DYNAMIC_MINORS) { err = -EBUSY; goto out; } misc->minor = DYNAMIC_MINORS - i - 1; set_bit(i, misc_minors); } else { struct miscdevice *c; list_for_each_entry(c, &misc_list, list) { if (c->minor == misc->minor) { err = -EBUSY; goto out; } } } dev = MKDEV(MISC_MAJOR, misc->minor); // 将主设备号和次设备号进行合并得到设备号 misc->this_device = device_create_with_groups(misc_class, misc->parent, dev, misc, misc->groups, "%s", misc->name); // 创建设备 if (IS_ERR(misc->this_device)) { int i = DYNAMIC_MINORS - misc->minor - 1; if (i < DYNAMIC_MINORS && i >= 0) clear_bit(i, misc_minors); err = PTR_ERR(misc->this_device); goto out; } /* * Add it to the front, so that later devices can "override" * earlier defaults */ list_add(&misc->list, &misc_list); out: mutex_unlock(&misc_mtx); return err; }
misc_register是内核提供给开发人员的注册misc设备的接口函数。该函数主要做了两件事情,首先判断次设备号是否需要自动分配,然后调用device_create_with_groups注册设备。
struct miscdevice { int minor; // 次设备号 const char *name; // 设备名字 const struct file_operations *fops; // 字符设备操作函数 struct list_head list; // 链表头 struct device *parent; // 父设备 struct device *this_device; const struct attribute_group **groups; const char *nodename; umode_t mode; };
struct miscdevice结构体需要开发者对里面的成员变量进行填充,填充完之后调用misc_register注册设备。
下面来写一个简单的misc设备驱动。
驱动程序
struct miscdevice led_misc; // 定义misc结构体变量 ssize_t chrdev_read (struct file *file, char __user *usr, size_t size, loff_t *loff) { printk("%s\r\n",__func__); return 0; } int chrdev_open (struct inode *inode, struct file *file) { printk("%s\r\n",__func__); return 0; } int chrdev_release (struct inode *inode, struct file *file) { printk("%s\r\n",__func__); return 0; } struct file_operations led_fops = { .open = chrdev_open, .read = chrdev_read, .release = chrdev_release, }; static int __init chrdev_init(void) { int ret = 0; led_misc.minor = MISC_DYNAMIC_MINOR; // 自动分配次设备号 led_misc.name = "led_misc_dev"; // 设备名 led_misc.fops = &led_fops; // 关联文件操作函数 misc_register(&led_misc); // 注册设备 return 0; } static void __exit chrdev_exit(void) { misc_deregister(&led_misc); } module_init(chrdev_init); module_exit(chrdev_exit); MODULE_DESCRIPTION("xxxxxx"); MODULE_AUTHOR("xxxxxx"); MODULE_LICENSE("GPL");
可以看到驱动程序使用misc框架注册设备非常简单,不用再关心主设备号,次设备号,不用再自己去注册类,然后再注册设备。因为misc框架已经帮我们把这些东西全部都搭建好了,我们需要做的就是填充struct miscdevice结构体,然后调用misc_register函数就可以完成注册。
这篇关于Linux内核之misc框架的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-12如何创建可引导的 ESXi USB 安装介质 (macOS, Linux, Windows)
- 2024-11-08linux的 vi编辑器中搜索关键字有哪些常用的命令和技巧?-icode9专业技术文章分享
- 2024-11-08在 Linux 的 vi 或 vim 编辑器中什么命令可以直接跳到文件的结尾?-icode9专业技术文章分享
- 2024-10-22原生鸿蒙操作系统HarmonyOS NEXT(HarmonyOS 5)正式发布
- 2024-10-18操作系统入门教程:新手必看的基本操作指南
- 2024-10-18初学者必看:操作系统入门全攻略
- 2024-10-17操作系统入门教程:轻松掌握操作系统基础知识
- 2024-09-11Linux部署Scrapy学习:入门级指南
- 2024-09-11Linux部署Scrapy:入门级指南
- 2024-08-21【Linux】分区向左扩容的方法