proc文件系統及初始化

proc 文件系統及初始化

proc 文件系統簡述:
proc文件系統使得內核可以生成與系統的狀態和配置有關的信息。該信息可以由用戶和系統程序從普通文件讀取,而無需專門的工具與內核通信。通過proc文件系統,可以獲得有關內核各子系統的信息,也可以在不重新編譯內核源代碼的情況下修改內核的行爲,或重啓系統。

在使用proc文件系統之前,必須用mount裝載他,而內核必須建立並初始化幾個數據結構,以便在內核內存中描述該文件系統的結構。由proc_root_init()完成proc初始化。基本步驟:

  1. proc_init_inodecache() 利用kmem_cache_create()創建proc_inode對象創建一個slab緩存。

  2. register_filesystem() 將該文件系統正式地註冊到內核。

  3. proc_net_init() 建立很多與網絡相關的文件。

  4. proc_tty_init() 建立與tty相關文件

  5. proc_mkdir() 建立/proc的若干子目錄。

  6. proc_sys_init() 建立sysctl層次結構,即/proc/sys/ 目錄層次。sysctl信息導出到/proc/sys目錄下。

     fs/proc/root.c    
     static struct file_system_type proc_fs_type = {
     .name		= "proc",
     .mount		= proc_mount,
     .kill_sb	= proc_kill_sb,
     .fs_flags	= FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
     };
    
     void __init proc_root_init(void)
     {
     	int err;
    
     	proc_init_inodecache();
     	err = register_filesystem(&proc_fs_type);
     	if (err)
                 return;
    
     	proc_self_init();
     	proc_thread_self_init();
     	proc_symlink("mounts", NULL, "self/mounts");
    
     	proc_net_init();
    
     	#ifdef CONFIG_SYSVIPC
     	proc_mkdir("sysvipc", NULL);
     	#endif
     	proc_mkdir("fs", NULL);
     	proc_mkdir("driver", NULL);
     	proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */
     	#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
     	/* just give it a mountpoint */
     	proc_create_mount_point("openprom");
     	#endif
     	proc_tty_init();
     	proc_mkdir("bus", NULL);
     	proc_sys_init();
     }
    

proc_mkdir新生成proc_dir_entry實例並將新生成proc_dir_entry實例註冊到內核。基本步驟:

  1. 檢測和賦值權限mode。

  2. 利用__proc_create(parent, name, node, nlink)新生成proc_dir_entry實例,其實質爲在parent目錄下建立目錄(文件)名爲name的子目錄(文件)。

  3. 使proc_iops和proc_fops分別指向inode_operations和file_operations類型實例,其父目錄的鏈接數加一。

  4. 新生成的proc_dir_entry實例註冊到內核中。並利用pde_subdir_insert()將新創建的目錄或文件添加到其父目錄的紅黑樹中。

    struct proc_dir_entry *proc_mkdir(const char *name,
    struct proc_dir_entry *parent)
    {
    return proc_mkdir_data(name, 0, parent, NULL);
    }

    struct proc_dir_entry *proc_mkdir_data(const char *name, umode_t mode,
    struct proc_dir_entry *parent, void *data)
    {
    struct proc_dir_entry *ent;

     if (mode == 0)
     	mode = S_IRUGO | S_IXUGO;
    
     ent = __proc_create(&parent, name, S_IFDIR | mode, 2);
     if (ent) {
     	ent->data = data;
     	ent->proc_fops = &proc_dir_operations;
     	ent->proc_iops = &proc_dir_inode_operations;
     	parent->nlink++;
     	if (proc_register(parent, ent) < 0) {
     		kfree(ent);
     		parent->nlink--;
     		ent = NULL;
     	}
     }
     return ent;
    

    }
    EXPORT_SYMBOL_GPL(proc_mkdir_data);
    參考:深入linux內核架構, linux-4.4

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章