Linux內核學習-字符驅動學習(一)
現在學習一下Linux的字符設備驅動,參考的樣本應該就是ldd3這書大概第3章的內容吧。
下面的所說的字符設備都是基於2.6內核的,
一般的流程都是,呵呵,其實也不算是一般的流程了,只是手動加載字符設備驅動的一種方法吧,
1. 先使用register_chrdev_region或alloc_chrdev_region來註冊一個字符設備的設備號,大家都知道Linux是通過設備號來找到相應的驅動程序的,所以你要註冊字符設備的時候,需要一個設備號或系統爲你指定一個設備號。這兩函數的差別就是register_chrdev_region是註冊指定設備號的字符設備,這個如果註冊設備號已經存在則有可能會失敗,而alloc_register_region是系統分配一個未使用的設備號然後再註冊
2. 再使用cdev_add函數,把該設備號相應的文件操作file_operation文件操作入口表添加到內核的散列表裏面,其中file_operation是需要你在驅動裏面實現的。然後使用命令mknod,創建與該字符設備(設備號)對應的設備節點,當有用戶程序打開這個設備並對其操作時候,系統會調用kobj_lookup() 函數,根據設備編號就可以找到 cdev 結構變量,從而取出其中的 ops (file_operation)字段,跳到相應的驅動入口去執行。
3. 當需要卸載驅動的時候(手動加載),需要做一些清理工作,cdev_del函數把散列表裏面的數據清除,再調用unregister_chrdev_region.
下面簡單介紹一下相關的函數:
|
上面有個count參數,文字意義上是數量的意思,而從函數名中的_region可以看出是註冊某一範圍的設備號的
把這兩個結合起來就是說,註冊使用從first[或dev]到(frist+count)[或dev+count],這個編號範圍的設備使用該驅動。。。
內核用dev_t類型(<linux/types.h>)來保存設備編號,dev_t是一個32位的數,12位表示主設備號,20爲表示次設備號。
在實際使用中,是通過<linux/kdev_t.h>中定義的宏來轉換格式。
(dev_t)-->主設備號、次設備號 | MAJOR(dev_t dev) MINOR(dev_t dev) |
主設備號、次設備號-->(dev_t) | MKDEV(int major,int minor) |
如果只是在module_init函數裏面做上面的這一步,加載內核模塊的時候,會可以cat /proc/devices裏面看到你註冊的設備和主設備號。
大家應該都知道file_operation函數的,它在<linux/fs.h>文件裏面有定義,是一個保存驅動操作函數入口的結構體,我們要做的工作基本都在這裏,完成這一步之後,使用cdev_add函數,把設備號與相應的file_operation指針添加到系統cdev_map 散列表裏面去,
初始化struct cdev
void cdev_init(struct cdev *cdev, const struct file_operations *fops)
初始化cdev.owner
cdev.owner = THIS_MODULE;
cdev.ops = &fops;
cdev設置完成,通知內核struct cdev的信息(在執行這步之前必須確定你對struct cdev的以上設置已經完成!)
int cdev_add(struct cdev *p, dev_t dev, unsigned count)
這裏面的count的意義跟上面register_chrdev_region中的是一樣的。
從系統中移除一個字符設備:void cdev_del(struct cdev *p)
完成這一步之後,你已經註冊了字符設備,但是你還不能對它進行操作(打開,關閉讀,寫等),你需要使用mknod命令手動的去生成一個設備號對應的索引節點,這個需要管理員權限的,你的主設備號可以通過cat /proc/devices看到
mknod - make block or character special files
mknod [OPTION]... NAME TYPE [MAJOR MINOR]
option 有用的就是 -m 了
name 自定義
type 有 b 和 c 還有 p
主設備號
次設備號
sudo mknod /dev/char01 c 250 0
最後你可以在你的用戶程序裏面使用open("/dev/char01", O_RDONLY);去打開這個設備了,
由於創建/dev/*節點的時候,是隻有管理員有權限的,所以你的測試程序也需要管理員權限執行。
下面是相應的源文件:
char01.c
Makefile:
測試文件,char01_test.c
參考文章:
http://blog.chinaunix.net/space.php?uid=20543672&do=blog&id=94290