IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 系统运维 -> 【linux kernel】start_kernel函数详解系列之proc_root_init -> 正文阅读

[系统运维]【linux kernel】start_kernel函数详解系列之proc_root_init

一、开篇

? 本文所有代码出自linux内核版本:4.1.15

? 在start_kernel函数中将调用proc_root_init()初始化proc文件系统的目录。该函数定义如下(/fs/proc/root.c):

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_root_init()函数开始处,调用proc_init_inodecache()函数分配proc的inode缓存(proc_inode_cachep),如下代码片段(/fs/proc/inode.c):

void __init proc_init_inodecache(void)
{
	proc_inode_cachep = kmem_cache_create("proc_inode_cache",
					     sizeof(struct proc_inode),
					     0, (SLAB_RECLAIM_ACCOUNT|
						SLAB_MEM_SPREAD|SLAB_PANIC),
					     init_once);
}

上述代码中,proc_inode_cachep是一个指向struct kmem_cache结构的指针。当对proc文件系统分配inode时,将在proc_inode_cachep指向的slab缓存区域中分配内存,这个操作由proc_alloc_inode()函数完成,如下代码:

static struct inode *proc_alloc_inode(struct super_block *sb)
{
	/* 省略了部分代码 */
    
	ei = (struct proc_inode *)kmem_cache_alloc(proc_inode_cachep, GFP_KERNEL);
    
	/* 省略了部分代码 */
	return inode;
}

当释放proc文件系统分配的inode时,将调用proc_i_callback()函数释放proc_inode_cachep指向的slab缓存区(proc_i_callback()函数被proc_destroy_inode()调用),如下代码所示:

static void proc_i_callback(struct rcu_head *head)
{
	struct inode *inode = container_of(head, struct inode, i_rcu);
	kmem_cache_free(proc_inode_cachep, PROC_I(inode));
}

对于proc文件系统来说,对proc_inode_cachep指向的slab缓存区域的分配和释放两个操作函数都被注册到了proc文件系统超级块的操作集合(proc_sops)中,如下代码所示(/fs/proc/inode.c):

static const struct super_operations proc_sops = {
    /* 分配inode */
	.alloc_inode	= proc_alloc_inode,
    /* 释放inode */
	.destroy_inode	= proc_destroy_inode,
    
	/* ......*/
    
};

回到proc_root_init()函数中,会继续调用register_filesystem()向linux内核注册proc文件系统,其文件系统的类型描述定义如下:

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,
};

在向内核中注册了proc文件系统后,会调用proc_self_init()函数(fs/proc/self.c)为self分配索引节点号(/proc/self目录指:访问/proc文件系统的进程)。

接着,将调用proc_setup_thread_self()函数,该函数将设置/proc/thread-self目录,其中包含有关当前线程的信息。如下代码片段:

	proc_self_init();
	proc_thread_self_init();

紧接着,会创建/proc/self/mounts,它将包含调用的挂载点:

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

接着会创建/proc/fs、/proc/driver、/proc/mounts、/proc/net、/proc/sys、/proc/tty相关proc文件系统的信息条目,如下代码:

   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_root_init()函数的最后,会调用proc_sys_init()函数创建/proc/sys目录并初始化sysctl。


二、结尾

至此,proc_root_init()函数就分析完毕啦。总结一下,该函数主要用于为proc文件系统创建目录

我们可以使用proc_mkdir()函数创建自己的proc文件系统目录,例如小生这里创建了一个目录如下:

proc_mkdir("iriczhao", NULL);

编译linux内核后运行,在bash shell中输入ls /proc/,命令将显示我们自己定义的目录,如下图所示:
在这里插入图片描述
(当然,以上操作似乎无任何意义,这么做,无非加深对linux内核的理解啦。毕竟动手实践,永远是把控linux内核的最佳方式!)

linux内核如何向proc文件系统递交内核本身的信息,这又是另外的话题了…

搜索/关注【嵌入式小生】wx公众号,获取更多精彩内容>>>>
请添加图片描述

  系统运维 最新文章
配置小型公司网络WLAN基本业务(AC通过三层
如何在交付运维过程中建立风险底线意识,提
快速传输大文件,怎么通过网络传大文件给对
从游戏服务端角度分析移动同步(状态同步)
MySQL使用MyCat实现分库分表
如何用DWDM射频光纤技术实现200公里外的站点
国内顺畅下载k8s.gcr.io的镜像
自动化测试appium
ctfshow ssrf
Linux操作系统学习之实用指令(Centos7/8均
上一篇文章      下一篇文章      查看所有文章
加:2022-05-13 12:00:08  更:2022-05-13 12:00:27 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 15:17:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码