日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

自动创建设备节点

發(fā)布時間:2025/3/15 编程问答 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 自动创建设备节点 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

創(chuàng)建設(shè)備文件的方法:

第一種:使用mknod手工創(chuàng)建,mknod filename type major minor

第二種:自動創(chuàng)建設(shè)備節(jié)點,利用udev來實現(xiàn)設(shè)備文件的自動創(chuàng)建

?

udev介紹

udev 運行在用戶模式,而非內(nèi)核中。udev 的初始化腳本在系統(tǒng)啟動時創(chuàng)建設(shè)備節(jié)點,并且當(dāng)插入新設(shè)備——加入驅(qū)動模塊——在sysfs上注冊新的數(shù)據(jù)后,udev會創(chuàng)建新的設(shè)備節(jié)點。

udev 是一個工作在用戶空間的工具,它能根據(jù)系統(tǒng)中硬件設(shè)備的狀態(tài)動態(tài)的更新設(shè)備文件,包括設(shè)備文件的創(chuàng)建,刪除,權(quán)限等。這些文件通常都定義在/dev 目錄下,但也可以在配置文件中指定。udev 必須內(nèi)核中的sysfs和tmpfs支持,sysfs 為udev 提供設(shè)備入口和uevent 通道,tmpfs 為udev 設(shè)備文件提供存放空間。

注意,udev 是通過對內(nèi)核產(chǎn)生的設(shè)備文件修改,或增加別名的方式來達(dá)到自定義設(shè)備文件的目的。但是,udev 是用戶模式程序,其不會更改內(nèi)核行為。也就是說,內(nèi)核仍然會創(chuàng)建sda,sdb等設(shè)備文件,而udev可根據(jù)設(shè)備的唯一信息來區(qū)分不同的設(shè)備,并產(chǎn)生新的設(shè)備文件(或鏈接)。而在用戶的應(yīng)用中,只要使用新產(chǎn)生的設(shè)備文件

?

自動創(chuàng)建設(shè)備節(jié)點:

在驅(qū)動用加入對udev 的支持主要做的就是:在驅(qū)動初始化的代碼里調(diào)用class_create(...)為該設(shè)備創(chuàng)建一個class,再為每個設(shè)備調(diào)用device_create(...)創(chuàng)建對應(yīng)的設(shè)備。

內(nèi)核中定義的struct class結(jié)構(gòu)體,顧名思義,一個struct class結(jié)構(gòu)體類型變量對應(yīng)一個類,內(nèi)核同時提供了class_create(…)函數(shù),可以用它來創(chuàng)建一個類,這個類存放于sysfs下面,一旦創(chuàng)建好了這個類,再調(diào)用 device_create(…)函數(shù)來在/dev目錄下創(chuàng)建相應(yīng)的設(shè)備節(jié)點。

這樣,加載模塊的時候,用戶空間中的udev會自動響應(yīng) device_create()函數(shù),去/sysfs下尋找對應(yīng)的類從而創(chuàng)建設(shè)備節(jié)點。

?

#include <linux/module.h> #include <linux/init.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/device.h>//#define MYMAJOR 200 #define MYCNT 1 #define MYNAME "testchar"static dev_t mydev; static struct cdev test_cdev; static struct class *test_class;static int test_chrdev_open(struct inode *inode, struct file *file) {printk(KERN_INFO "test_chrdev_open...\n");return 0; }static int test_chrdev_release(struct inode *inode, struct file *file) {printk(KERN_INFO "test_chrdev_release...\n");return 0; }ssize_t test_chrdev_read(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) {printk(KERN_INFO "test_chrdev_read...\n");return 0; }static ssize_t test_chrdev_write(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) {printk(KERN_INFO "test_chrdev_write...\n");return 0; }static const struct file_operations test_fops = {.owner = THIS_MODULE,.open = test_chrdev_open,.release = test_chrdev_release,.write = test_chrdev_write,.read = test_chrdev_read, };static int __init chrdev_init(void) { int retval;printk(KERN_INFO "chrdev_init...\n");/* 分配主次設(shè)備號 */ /*mydev = MKDEV(MYMAJOR, 0);retval = register_chrdev_region(mydev, MYCNT, MYNAME);if (retval) {printk(KERN_ERR "Unable to register minors for %s\n", MYNAME);return -EINVAL;} */retval = alloc_chrdev_region(&mydev, 12, MYCNT, MYNAME);if (retval < 0) {printk(KERN_ERR "Unable to alloc minors for %s\n", MYNAME);goto flag1;}printk(KERN_INFO "alloc_chrdev_region success\n");printk(KERN_INFO "major = %d, minor = %d.\n", MAJOR(mydev), MINOR(mydev));/* 注冊字符設(shè)備驅(qū)動 */cdev_init(&test_cdev, &test_fops);retval = cdev_add(&test_cdev, mydev, MYCNT);if (retval) {printk(KERN_ERR "Unable to cdev_add\n");goto flag2;}printk(KERN_INFO "cdev_add success\n");/* 創(chuàng)建設(shè)備類 */test_class = class_create(THIS_MODULE, "test_class");if (IS_ERR(test_class)) {printk(KERN_ERR "Unable to class_create\n");goto flag3;}/* 創(chuàng)建設(shè)備節(jié)點 */device_create(test_class, NULL, mydev, NULL, "test");return 0;flag3:cdev_del(&test_cdev);flag2:unregister_chrdev_region(mydev, MYCNT); flag1: return -EINVAL; }static void __exit chrdev_exit(void) {printk(KERN_INFO "chrdev_exit...\n");/* 銷毀設(shè)備類節(jié)點 */device_destroy(test_class, mydev);class_destroy(test_class);/* 注銷字符設(shè)備驅(qū)動 */cdev_del(&test_cdev);/* 注銷申請的主次設(shè)備號 */unregister_chrdev_region(mydev, MYCNT); }module_init(chrdev_init); module_exit(chrdev_exit);MODULE_LICENSE("GPL"); // 描述模塊的許可證 MODULE_AUTHOR("lsm"); // 描述模塊的作者 MODULE_DESCRIPTION("module test"); // 描述模塊的介紹信息 MODULE_ALIAS("alias xxx"); // 描述模塊的別名信息

?

總結(jié)

以上是生活随笔為你收集整理的自动创建设备节点的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。