proc原始碼解析(三) proc初始化

2021-06-09 14:52:51 字數 3778 閱讀 1477

在使用proc之前,我們必須首先初始化並掛載proc,並在核心記憶體中建立資料結構來描述檔案系統。但是,不同的體系結構擁有不同的proc內容,所以,在初始化階段並不完全建立子目錄的內容,有些檔案要等到系統執行時動態建立。proc檔案系統初始化的流程圖如下:

proc_root_init的定義定義如下:

void __init proc_root_init(void)

vfs_kern_mount:建立與proc_fs_type相關的vfsmount結構,該函式在vfs中已有講述。

proc_misc_init:建立/proc目錄下的檔案和子目錄,每個檔案的建立都由相應的函式來完成,例如:meminfo的建立由 create_proc_read_entry 建立,而meminfo_read_proc則用於初始化meminfo的read_proc函式。其實際的呼叫過程是:

void __init proc_misc_init(void)

*p, ******_ones = ,,,

,。。。,,

,};for (p = ******_ones; p->name; p++)

create_proc_read_entry(p->name, 0, null, p->read_proc, null);

proc_symlink("mounts", null, "self/mounts");

create_seq_entry("locks", 0, &proc_locks_operations);

create_seq_entry("devices", 0, &proc_devinfo_operations);

create_seq_entry("cpuinfo", 0, &proc_cpuinfo_operations);

。。。}

另外一些檔案是用create_seq_entry來呼叫建立函式。

create_seq_entry("locks", 0, &proc_locks_operations);

這兩個函式 create_proc_read_entry與create_seq_entry的不同之處是前者建立的是唯讀檔案,後者建立的是可讀可寫檔案。

proc_net_init:建立大量與網路相關的檔案,建立方法與前者相似,所以此處不在贅述。

以上步驟完成之後,初始化需要建立的檔案都已完成,下邊要呼叫proc_mkdir來建立子目錄。

實際上,函式最後還呼叫proc_sys_init();來完成sys子目錄的建立。

register_filesystem的實現

在proc_root_init函式中,呼叫該函式的格式是:

static struct file_system_type proc_fs_type = ;

void __init proc_root_init(void)

也是就呼叫register_filesystem函式把描述proc檔案型別的結構 proc_fs_type註冊到系統中,其中register_filesystem函式函式實現很簡單,這裡主要關注 proc_get_sb函式。該函式的主要功能是獲取proc的super_block。其呼叫流程圖如下:

proc_get_sb中主要的執行函式是proc_fill_super;該函式的主要執行過程如下,為了方便理解,我刪去了"多餘部分",只留下程式骨幹。

int proc_fill_super(struct super_block *s)

第乙個階段:初始化super block的元素,唯一值得注意的是s->s_op = &proc_sops;

這是初始化super block的struct super_operations *s_op;其中函式集是:

static const struct super_operations proc_sops = ;

第二個階段: proc_get_inode函式用來獲得proc的inode,其主要的實現過程如下,為了便於理解我刪去了部分**:

struct inode *proc_get_inode(struct super_block *sb, unsigned int ino,

struct proc_dir_entry *de)

/* 使用proc_root的各個域初始化inode */

if (de->size)

inode->i_size = de->size;

if (de->nlink)

inode->i_nlink = de->nlink;

if (de->proc_iops)

inode->i_op = de->proc_iops;//proc_root的inode操作函式

if (de->proc_fops)

else

inode->i_fop = de->proc_fops; //proc_root的file操作函式}}

}  

紅色部分說明如果是普通檔案使用proc_reg_file_ops 初始化,其定義為:

static const struct file_operations proc_reg_file_ops = ;

proc_fill_super在呼叫該函式時(proc_get_inode(s, proc_root_ino, &proc_root))傳入的引數為proc_root,這是乙個全域性變數,是proc的根目錄的dentry,其定義為:

static const struct file_operations proc_root_operations = ;

static const struct inode_operations proc_root_inode_operations = ;

struct proc_dir_entry proc_root = ;

在 proc_get_inode函式的初始化過程中,大部分的域都是用proc_root中相應的域來初始化,這也正好將proc的dentry和vfs層的dentry和inode對接起來。各個域的操作函式集合此處就不在深入,有需要的朋友可以查閱原始碼。

第三個階段:呼叫 d_alloc_root建立proc根結點的dentry,該函式比較短,此處引用它的定義:

/*** d_alloc_root - allocate root dentry

* @root_inode: inode to allocate the root for

* allocate a root ("/") dentry for the inode given. the inode is

* instantiated and returned. %null is returned if there is insufficient

* memory or the inode passed is %null.

*/struct dentry * d_alloc_root(struct inode * root_inode)

;res = d_alloc(null, &name);//allocate a dcache entry

if (res)

}return res;

}到此為止proc的初始化過程已經完成,此時,/proc目錄下除了要動態建立的檔案和子目錄外,初始化過程中應該建立的檔案和子目錄都已建立完畢,接下來就需要掛載proc檔案系統到目錄樹上,這是下一節要講的內容。

proc原始碼解析(三) proc初始化

在使用proc之前,我們必須首先初始化並掛載proc,並在核心記憶體中建立資料結構來描述檔案系統。但是,不同的體系結構擁有不同的proc內容,所以,在初始化階段並不完全建立子目錄的內容,有些檔案要等到系統執行時動態建立。proc檔案系統初始化的流程圖如下 proc root init的定義定義如下 ...

proc原始碼解析(六) proc檔案讀寫函式

前邊說過目錄項建立時一般都使用預設的讀寫函式,本節就來看看預設的檔案操作函式的定義。前邊已經引用過該定義,此處再次引用 static const struct file operations proc file operations proc file read的實現 從proc檔案中讀取資料需要經...

proc原始碼解析(二) proc資料結構

上節主要說明了proc下的內容,從本節開始解析proc的實現。與普通檔案系統一樣,proc當然需要虛擬檔案系統的支援,所以它必須具備檔案系統的幾個主要的資料結構。1.proc dir entry 在proc檔案系統中,每個entry的例項是由proc dir entry來描述的,其結構如下 stru...