實驗要求:編寫簡單的字元裝置驅動模組,能夠支援建立和刪除節點,節點進行讀寫操作時分別列印「you are reading!」和「you are writing!」。
思想整理:
1. 本實驗需要我們編寫乙個驅動程式,如mymodule.c
2. 該驅動程式經編譯後生成.ko檔案,使用makefile檔案生成mymodule.ko
3. 可以掛在到系統上insmod mymodule.ko
4. 然後通過其主裝置號將其生成乙個節點mknod mymodule0 c 249 0
5. 對mumodule0進行讀寫操作cat mymodule0 或ls > mymodule
實驗原理:
1.
mymodule.c的組成
(1)
my_init_module()函式
當使用insmod命令時,系統會呼叫程式的module_init()函式,這樣也就呼叫了我們寫的my_init_module()函式。
而我們應當在my_init_module()中完成的操作有以下這些:
註冊裝置,註冊的目的是註冊了自己寫的這些file operations,如read,write等,而不是用原來vfs的read,write函式同時以後可以使用主裝置號來使用該模組。
註冊的語句是:
major = register_chrdev(0,」chardev」,&my_fops),解釋一下引數
第乙個0表示讓系統幫我分配主裝置號,你也可以自己寫,但是這樣你還得查一下系統中有空的主裝置號。
第二個引數是說明這是乙個字元裝置驅動,不用改
第三個就是我們用file_operations定義的檔案操作結構體的引用
獲取主裝置號,輸出一下主裝置號,這樣你在mknod的時候就可以找到這個裝置了。
(2)
my_cleanup_module()函式
另乙個必須有的函式是module_exit,這個函式在我們rmmod時會被呼叫,而這個函式又同時呼叫了我們自己寫的
函式,所以如果我們在my_cleanup module函式中寫printk(「goodbye」),那麼在用rmmod時他就輸出了。
在my_cleanup_module我們還有乙個必要的事要做,把剛剛註冊的裝置給登出掉,命令是unregister_chrdev(major,」chardev」);
(3)
struct file_operations my_fops{};結構體
定義了這個結構體後,這個file operations就會替換原來虛擬檔案系統的file operations,具體的方法很簡單,仿照例子即可,唯一需要注意的是順序必須按照原本file operations的順序。
struct file_operations my_fops=;
(4) 根據你要重定義的操作,也就是在file operations結構體裡面寫的那幾個,相應的寫他們的函式。
tips:在裝置開啟時,會用到乙個try_module_get函式,這個函式的目的是讓系統知道這個模組又被用了一次,只有系統確實知道我們的模組被用了多少次,模組在登出時才不會出錯,同理,用module_put函式,可以跟系統說,我的某一次呼叫已經結束了!!
2.makefile的編寫,由於這個實驗編譯的是模組,所以需要用到核心裡的makefile檔案,具體怎麼編譯的還沒有弄清楚,但是makefile的**是這樣的
kerneldir := /lib/modules/`uname -r`/build
obj-m := mymodule.o
module:
make -c $(kerneldir) m=`pwd` modules
clean:
rm -fr mymodule.o mymodule.ko mymodule.mod.*
**:
#include
#include
#include
#include
/*函式宣告*/
intmy_init_module(void);
void
my_cleanup_module(void);
static
int my_open(struct inode *, struct file *);
static
int my_release(struct inode *, struct file *);
static
ssize_t my_read(struct file *, char *, size_t, loff_t *);
static
ssize_t my_write(struct file *, const char *, size_t, loff_t *);
#define
success 0
#define
device_name "chardev"
#define
buf_len 80
static
int major;
static
int device_open = 0;
struct
file_operations my_fops=;
intmy_init_module(void)
else
return 0; }
void
my_cleanup_module(void)
static
int my_open(struct inode *inode,struct file *file)
static
int my_release(struct inode *inode,struct file *file)
static
ssize_t my_read(struct file *flip,char *buffer,size_t length,loff_t *offset)
static
ssize_t my_write(struct file *flip,const char *buff,size_t len,loff_t *off)
module_license("gpl");
module_init(my_init_module);
module_exit(my_cleanup_module);
驅動雜記1 對驅動物件,裝置物件,裝置棧的理解
windows核心採用的是物件導向的程式設計方式,但使用的確是c語言。windows核心認為許多東西都是 物件 比如乙個驅動乙個檔案乙個裝置,物件 相當於乙個基類。乙個驅動物件代表了乙個驅動程式,或者說乙個核心模組。驅動物件結構如下 typedef struct driver objectdrive...
我對字元編碼的理解
開發這些年,一直有遇到字元編碼這些問題,能一直在解決,但始終沒有做到通透的水平,現在想嘗試做一下歸納與總結。嘗試從乙個完全不懂的小白的角度,把問題講清楚。最開始的時候,只是英文世界裡面存在計算機。對於計算機而言,他只認識一些基本的位元組,不認識所謂的英文。為了顯示26個字母,出現了最早的ascii碼...
裝置驅動例項 字元裝置驅動
在整個linux裝置驅動學習中,字元裝置驅動較為基礎。通過對它的學習,對裝置驅動進一步加深了解 cdev 結構體struct cdev 講下比較重要的成員變數 dev t dev 定義了32位的裝置號,其中12位是主裝置號,20位是從裝置號。獲取主裝置號 major dev t dev 獲取從裝置號...