字元裝置驅動Open呼叫過程

2021-10-06 07:11:01 字數 2697 閱讀 8825

使用open函式開啟裝置檔案,到底做了些什麼工作?下圖中列出了open函式執行的大致過程。

裝置檔案通常在開機啟動時自動建立的,不過,我們仍然可以使用命令mknod來建立乙個新的裝置檔案,命令的基本語法如下:

mknod裝置名 裝置型別 主裝置號 次裝置號

當我們使用上述命令,建立了乙個字元裝置檔案時,實際上就是建立了乙個裝置節點inode結構體,並且將該裝置的裝置編號記錄在成員i_rdev,將成員i_fop指標指向了def_chr_fops結構體。這就是mknod負責的工作內容,具體**見如

mknod呼叫關係

static

struct inode *

shmem_get_inode

(struct super_block *sb,

const

struct inode *dir,

umode_t mode, dev_t dev,

unsigned

long flags)

}else

shmem_free_inode

(sb)

;return inode;

}void

init_special_inode

(struct inode *inode, umode_t mode, dev_t rdev)....}

命令mknod最終會呼叫init_special_inode函式,由於我們建立的是字元裝置,因此,會執行第22~23行的**。這樣就完成了上圖的內容。

我們使用的open函式在核心中對應的是sys_open函式,sys_open函式又會呼叫do_sys_open函式。在do_sys_open函式中,首先呼叫函式get_unused_fd_flags來獲取乙個未被使用的檔案描述符fd,該檔案描述符就是我們最終通過open函式得到的值。緊接著,又呼叫了do_filp_open函式,該函式通過呼叫函式get_empty_filp得到乙個新的file結構體,之後的**做了許多複雜的工作,如解析檔案路徑,查詢該檔案的檔案節點inode等,直接來到了函do_dentry_open函式,如下所示。

do_dentry_open函式(位於核心原始碼/fs/open.c檔案)

static

intdo_dentry_open

(struct file *f,

struct inode *inode,

int(

*open)

(struct inode *

,struct file *),

const

struct cred *cred)

…… }

以上**中的第7行使用fops_get函式來獲取該檔案節點inode的成員變數i_fop,在上圖中我們使用mknod建立字元裝置檔案時,將def_chr_fops結構體賦值給了該裝置檔案inode的i_fop成員。到了這裡,我們新建的file結構體的成員f_op就指向了def_chr_fops。

def_chr_fops結構體(位於核心原始碼/fs/char_dev.c檔案)

const

struct file_operations def_chr_fops =

;

最終,會執行def_chr_fops中的open函式,也就是chrdev_open函式,可以理解為乙個字元裝置的通用初始化函式,根據字元裝置的裝置號,找到相應的字元裝置,從而得到操作該裝置的方法,**實現如下。

chrdev_open函式(位於核心原始碼/fs/char_dev.c檔案)

static

intchrdev_open

(struct inode *inode,

struct file *filp)

elseif(

!cdev_get

(p))

ret =

-enxio;

}elseif(

!cdev_get

(p))

ret =

-enxio;

spin_unlock

(&cdev_lock)

;cdev_put

(new);if

(ret)

return ret;

ret =

-enxio;

fops =

fops_get

(p->ops);if

(!fops)

goto out_cdev_put;

replace_fops

(filp, fops);if

(filp->f_op->open)

return0;

out_cdev_put:

cdev_put

(p);

return ret;

}

最後,呼叫上圖的fd_install函式,完成檔案描述符和檔案結構體file的關聯,之後我們使用對該檔案描述符fd呼叫read、write函式,最終都會呼叫file結構體對應的函式,實際上也就是呼叫cdev結構體中ops結構體內的相關函式

驅動呼叫過程

驅動呼叫過程 剛接觸到linux下驅動程式設計,一般都是照著模式寫 或是修改一下已有原始碼,對驅動的呼叫過程並不是很熟悉。在網上不斷的 算是有點明白了,現在我就說下自己的了解。我們載入驅動模組後都會做乙個工作,就是通過mknod在 dev資料夾下建立乙個裝置檔案 如mknod dev c major...

驅動介面函式呼叫過程

首先我們來反彙編讀驅動的程式 跳轉到 libc read 發現他把 r7賦值給3,3是傳過去的引數,然後呼叫 svc指令,進入核心態相應的入口 接下來就已經進入核心態,入口函式中將存入r7中的3 取出。然後載入一張表,表名是sys call call,根據這個表中內容,斷定 3到底是對應什麼操作 這...

probe呼叫過程

這幾天搞ti的vpfe,裡面裝置的註冊使用platform,平台裝置註冊方式來註冊的。一直都知道 cpp view plain copy print 112 struct device driver 裡的probe函式,但是不知道是何時被呼叫的。經過跟蹤 在module init vpfe init...