dev_t類型用來保存設備編號(包含主設備號和次設備號),實際上是一個32位整數,12位用來表示主設備號,後20位表示次設備號。
[code]#define MINORBITS 20 #define MINORMASK ((1U << MINORBITS) - 1) //提取主設備號 #define MAJOR(dev) ((unsigned int) ((dev) >> MINORBITS)) //提取次設備號 #define MINOR(dev) ((unsigned int) ((dev) & MINORMASK)) //生成設備號 #define MKDEV(ma,mi) (((ma) << MINORBITS) | (mi))
[code]/** * register_chrdev_region() - register a range of device numbers * @from: the first in the desired range of device numbers; must include * the major number. * @count: the number of consecutive device numbers required * @name: the name of the device or driver. * * Return value is zero on success, a negative error code on failure. */ int register_chrdev_region(dev_t from, unsigned count, const char *name)指定從設備號from開始,申請count個設備號,在/proc/devices中的名字為name
[code]int alloc_chrdev_region(dev_t *dev, unsigned baseminor, unsigned count, const char *name)動態申請從次設備號baseminor開始的count個設備號,在/proc/devices中的名字為name,並通過dev指針把分配到的設備號返回給調用函數者。
[code]void unregister_chrdev_region(dev_t from, unsigned count)
[code]struct cdev { struct kobject kobj; struct module *owner;//一般初始化為THIS_MODULE const struct file_operations *ops;//文件操作結構體 struct list_head list; dev_t dev;//設備號 unsigned int count;//添加的設備個數 };注冊的三個步驟:
1)分配cdev;
2)初始化cdev;
3)添加cdev;
truct cdev* test_cdev;
test_cdev = cdev_alloc();
[code]/** * cdev_init() - initialize a cdev structure * @cdev: the structure to initialize * @fops: the file_operations for this device * * Initializes @cdev, remembering @fops, making it ready to add to the * system with cdev_add(). */ void cdev_init(struct cdev *cdev, const struct file_operations *fops)這個函數干了兩件事情:
1)內核自己填充了結構體中list和kobj的內容
2)把傳入的文件操作結構體也填充進去
一般的,還要手工定義結構體成員owner。
[code]int cdev_add(struct cdev *cdev, dev_t dev, unsigned count)
參數:
cdev:指定要被添加的cdev結構體;
dev:對應的設備號
count:從設備號dev開始添加count個設備.
函數干了也兩件事:
1)把cdev結構體中還沒填充的兩個成員dev和count按照傳入參數賦值。
2)把cdev結構體中傳入內核,這樣內核就知道對應設備號和具體的文件操作結構體了。
[code]void cdev_del(struct cdev *p)