我對字元裝置驅動的理解

2021-05-23 21:25:52 字數 3278 閱讀 5920

實驗要求:編寫簡單的字元裝置驅動模組,能夠支援建立和刪除節點,節點進行讀寫操作時分別列印「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 獲取從裝置號...