系統呼叫Open 函式的核心追蹤 上篇

2021-06-22 18:09:08 字數 3223 閱讀 4195

from:

open函式相信大家都用過,這裡就不多說它的使用方法等事項,現直接進入正題...

使用者態程式呼叫open函式時,會產生乙個中斷號為5的中斷請求,其值以該巨集__nr__open進行標示.而後該程序上下文(processcontext)將會被切換到核心空間。待核心中的相關操作完成後,就會從核心返回,此時還需要一次程序上下文切換(processcontext switch)。

待程序執行流進入核心後,會通過一系列轉換(這裡我們不關心),最終進入syscall_define3(open,...)函式中。看起來該函式定義比較特殊,其實syscall_drfine3是乙個巨集,它被定義成如下形式:

#

define syscall_define3(name,..

.) syscall_definex(3, _#

#name,

__va_args__

)

而 syscall_definex巨集具有如下形式:

#

ifdef config_ftrace_syscalls

#define syscall_definex(x, sname,..

.)                \

static

const

char

*types_#

#sname=

;                            \

static

const

char

*args_#

#sname=

;                            \

syscall_metadata(sname, x)

;                \

__syscall_definex(x, sname,

__va_args__)#

else

#define syscall_definex(x, sname,..

.)                \

__syscall_definex(x, sname,

__va_args__)#

endif

可以看到,不論是何種形式的巨集定義,最終都會進入__syscall_definex中,而__syscall_definex的定義如下:

#

define syscall_define(name)

static

inline

long sysc_#

#name

#define __syscall_definex(x, name,..

.)                    \

asmlinkage long sys#

#name(__sc_decl#

#x(__va_args__))

;        \

static

inline

long sysc#

#name(__sc_decl#

#x(__va_args__))

;    \

asmlinkage long sys#

#name(__sc_long#

#x(__va_args__

))        \

\syscall_alias(sys#

#name, sys#

#name)

;                \

static

inline

long sysc#

#name(__sc_decl#

#x(__va_args__))

#else

#define syscall_define(name) asmlinkage long sys_#

#name

#define __syscall_definex(x, name,..

.)                    \

asmlinkage long sys#

#name(__sc_decl#

#x(__va_args__))

#endif

經過該巨集的替換作用以後,最終我們就會得到sys_open或sys_open所對應的函式原型。如下:

asmlinkage long sys_open(const char __user filename,

int flags,

int mode);

這也就是我們最常見到的open函式所對應的在核心中的實現部份。其實,對於linux下所有的系統呼叫函式,採用上述方法均可找到與其對應的核心函式sys_***().

接下來我們來看sys_open()函式。其實現如下:

syscall_define3(open, const char __user *

, filename,

int, flags,

int, mode)

在函式中首先呼叫force_o_largefile()巨集進行largefile?確認。若是largefile則將其在flags中置位。隨後呼叫主處理函式do_sys_open進行後續處理。其實,open的工作也就是在該函式中進行的。該函式原型如下:

long do_sys_open(

int dfd,

const

char __user *filename,

int flags,

int mode)

;

在獲得了有效的fd之後,我們通過do_filp_open()函式開啟或者建立相應的檔案,並且返回與之對應的檔案結構structfile*f。如果函式返回的結構位址有效的話,那麼就會呼叫fsnotify_open()函式(引數為f)將該檔案加入到檔案監控的系統中。該系統是用來監控檔案被開啟,建立,讀寫,關閉,修改等操作的,具體工作原理見後面文章。本文中不做講述。隨後呼叫fd_install()函式將structfile*f加入到fd索引位置處的陣列中。如果後續過程中,有對該檔案描述符的操作的話,就會通過查詢該陣列得到對應的檔案結構,而後在進行相關操作。完成這些工作之後,open函式就返回了。返回值也就是剛才得到的fd.

那麼,在do_filp_open()函式中有具體做了哪些工作呢?檔案是如何被建立的呢?以及檔案若存在的話,又是怎樣被找到,而後被開啟的呢?在中篇中我們將會回答這些問題。

linux 系統呼叫 open函式使用

函式介紹 本文僅僅將open系統呼叫的使用簡單總結一下,關於其實現原理大批的大佬分享可以自行學習。open系統呼叫主要用於開啟或者建立乙個檔案,並返回檔案描述符。以上兩個函式引數含義如下 返回值 作業系統會為當前程序從3開始分配乙個未使用的檔案描述符,因為0,1,2已經被stdin,stdout,s...

open系統呼叫在核心中的流程分析

真是蠻複雜的,我分三步走,力求講得比較清楚。以字元裝置為例,相對於塊裝置要簡單些。基於2.6.26的核心 一 驅動註冊open函式都幹了些什麼?register chrdev cdev add kobj map file fs char dev.c int register chrdev unsig...

open 系統呼叫的實現

open系統呼叫的服務例程是sys open 函式,它接受三個引數 要開啟檔案的路徑名filename,訪問模式的表示flags和檔案許可權掩碼mode。在核心中,sys open實際呼叫do sys open函式來完成所有操作。do sys open主要執行如下操作 1,通過getname 從程序...