標籤:va_list round 資料 uname ati build lin 更新 程式
建立裝置檔案的方法:
第一種是使用mknod手工建立:mknod filename type major minor
第二種是自動建立裝置節點:利用udev(mdev)來實現裝置檔案的自動建立,首先應保證支援udev(嵌入式系統用mdev),由busybox配置。
udev介紹
udev 運行在使用者模式,而非核心中。udev 的初始化指令碼在系統啟動時建立裝置節點,並且當插入新裝置——加入驅動模組——在sysfs上註冊新的資料後,udev會創新新的裝置節點。
udev 是一個工作在使用者空間的工具,它能根據系統中硬體裝置的狀態動態更新裝置檔案,包括裝置檔案的建立,刪除,許可權等。這些檔案通常都定義在/dev 目錄下,但也可以在設定檔中指定。udev 必須核心中的sysfs和tmpfs支援,sysfs 為udev 提供裝置入口和uevent 通道,tmpfs 為udev 裝置檔案提供存放空間。
注意,udev 是通過對核心產生的裝置檔案修改,或增加別名的方式來達到自訂裝置檔案的目的。但是,udev 是使用者模式程式,其不會更改核心行為。也就是說,核心仍然會建立sda,sdb等裝置檔案,而udev可根據裝置的唯一資訊來區分不同的裝置,併產生新的裝置檔案(或連結)。而在使用者的應用中,只要使用新產生的裝置檔案
自動建立裝置節點:
在驅動用加入對udev 的支援主要做的就是:在驅動初始化的代碼裡調用class_create(...)為該裝置建立一個class,再為每個裝置調用device_create(...)建立對應的裝置。
核心中定義的struct class結構體,顧名思義,一個struct class結構體類型變數對應一個類,核心同時提供了class_create(…)函數,可以用它來建立一個類,這個類存放於sysfs下面,一旦建立好了這個類,再調用 device_create(…)函數來在/dev目錄下建立相應的裝置節點。
這樣,載入模組的時候,使用者空間中的udev會自動響應 device_create()函數,去/sysfs下尋找對應的類從而建立裝置節點。
1、class_create(...) 函數
功能:建立一個類;
#define class_create(owner, name) \ ({ \ static struct lock_class_key __key; \ __class_create(owner, name, &__key); \ })
owner:THIS_MODULE
name : 名字
__class_create(owner, name, &__key)原始碼如下:
struct class *__class_create(struct module *owner, const char *name, struct lock_class_key *key) { struct class *cls; int retval; cls = kzalloc(sizeof(*cls), GFP_KERNEL); if (!cls) { retval = -ENOMEM; goto error; } cls->name = name; cls->owner = owner; cls->class_release = class_create_release; retval = __class_register(cls, key); if (retval) goto error; return cls; error: kfree(cls); return ERR_PTR(retval); } EXPORT_SYMBOL_GPL(__class_create);
銷毀函數:void class_destroy(struct class *cls)
void class_destroy(struct class *cls) { if ((cls == NULL) || (IS_ERR(cls))) return; class_unregister(cls); }
2、device_create(...) 函數
struct device *device_create(struct class *class, struct device *parent,
dev_t devt, void *drvdata, const char *fmt, ...)
功能:建立一個字元裝置檔案
參數:
struct class *class :類
struct device *parent:NULL
dev_t devt :裝置號
void *drvdata :null、
const char *fmt :名字
返回:
struct device *
下面是源碼解析:
struct device *device_create(struct class *class, struct device *parent, dev_t devt, void *drvdata, const char *fmt, ...) { va_list vargs; struct device *dev; va_start(vargs, fmt); dev = device_create_vargs(class, parent, devt, drvdata, fmt, vargs); va_end(vargs); return dev; }
下面是一個執行個體:
hello.c
#include <linux/module.h> #include <linux/fs.h> #include <linux/cdev.h> #include <linux/device.h> static int major = 250; static int minor=0; static dev_t devno; static struct class *cls; static struct device *test_device; static int hello_open (struct inode *inode, struct file *filep) { printk("hello_open \n"); return 0; } static struct file_operations hello_ops= { .open = hello_open, }; static int hello_init(void) { int ret; printk("hello_init \n"); devno = MKDEV(major,minor); ret = register_chrdev(major,"hello",&hello_ops); cls = class_create(THIS_MODULE, "myclass"); if(IS_ERR(cls)) { unregister_chrdev(major,"hello"); return -EBUSY; } test_device = device_create(cls,NULL,devno,NULL,"hello");//mknod /dev/hello if(IS_ERR(test_device)) { class_destroy(cls); unregister_chrdev(major,"hello"); return -EBUSY; } return 0; } static void hello_exit(void) { device_destroy(cls,devno); class_destroy(cls); unregister_chrdev(major,"hello"); printk("hello_exit \n"); } MODULE_LICENSE("GPL"); module_init(hello_init); module_exit(hello_exit);
test.c
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <stdio.h> main() { int fd; fd = open("/dev/hello",O_RDWR); if(fd<0) { perror("open fail \n"); return ; } close(fd); }
#ubuntu的核心源碼樹,如果要編譯在ubuntu中安裝的模組就開啟這2個KERN_VER = $(shell uname -r)KERN_DIR = /lib/modules/$(KERN_VER)/build # 開發板的linux核心的源碼樹目錄#KERN_DIR =/lib/modules/2.6.31-14-generic/build#KERN_DIR = /home/book/per/kernel/linux-2.6.22.6#/root/driver/kernelobj-m += hello.oall: make -C $(KERN_DIR) M=`pwd` modules #cp:# cp *.ko /root/porting_x210/rootfs/rootfs/driver_test.PHONY: clean clean: make -C $(KERN_DIR) M=`pwd` modules clean
轉自:http://blog.csdn.net/zqixiao_09/article/details/50864014
http://blog.csdn.net/zqixiao_09/article/details/50849735
如何自動建立裝置節點