/proc/version 的生成过程

通常我们cat /proc/version时,会显示kernel相关的版本、编译等信息

那么问题来了,这些信息是怎么生成的呢?

/proc/version文件是在kernel fs/proc/version.c 中生成

#include <linux/fs.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/utsname.h> static int version_proc_show(struct seq_file *m, void *v)
{
seq_printf(m, linux_proc_banner, //linux_proc_banner()在init/version.c中定义
utsname()->sysname, //utsname()在include/linux/utsname.h中定义
utsname()->release,
utsname()->version);
return 0;
} static int version_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, version_proc_show, NULL);
} static const struct file_operations version_proc_fops = {
.open = version_proc_open,
.read = seq_read,
.llseek = seq_lseek,
.release = single_release,
}; static int __init proc_version_init(void)
{
proc_create("version", 0, NULL, &version_proc_fops);
return 0;
}
module_init(proc_version_init);

utsname()定义:

//include/linux/utsname.h
static inline struct new_utsname *utsname(void)
{
return &current->nsproxy->uts_ns->name;
} //current 是一个宏,表示当前进程的指针
//arch/arm/include/asm/current.h
#ifndef _ASMARM_CURRENT_H
#define _ASMARM_CURRENT_H #include <linux/thread_info.h> static inline struct task_struct *get_current(void) __attribute_const__; static inline struct task_struct *get_current(void)
{
return current_thread_info()->task;
} #define current (get_current()) #endif /* _ASMARM_CURRENT_H */ //nsproxy, 是指kernel的namespace机制,关于机制,这里不展开。
//nsproxy 的初始化的定义在./kernel/nsproxy.c文件中
struct nsproxy init_nsproxy = {
.count = ATOMIC_INIT(1),
.uts_ns = &init_uts_ns,
#if defined(CONFIG_POSIX_MQUEUE) || defined(CONFIG_SYSVIPC)
.ipc_ns = &init_ipc_ns,
#endif
.mnt_ns = NULL,
.pid_ns = &init_pid_ns,
#ifdef CONFIG_NET
.net_ns = &init_net,
#endif
}; //该结构在task初始化的时候会被初始化,在include/linux/init_task.h文件中
#define INIT_TASK(tsk) \
...
.nsproxy = &init_nsproxy, \
... //init_nsprosy定义在init/version.c中
struct uts_namespace init_uts_ns = {
.kref = {
.refcount = ATOMIC_INIT(2),
},
.name = {
.sysname = UTS_SYSNAME,
.nodename = UTS_NODENAME,
.release = UTS_RELEASE,
.version = UTS_VERSION,
.machine = UTS_MACHINE,
.domainname = UTS_DOMAINNAME,
},
.user_ns = &init_user_ns,
};
EXPORT_SYMBOL_GPL(init_uts_ns);
//到这里&current->nsproxy->uts_ns->name的路径就全部联系起来了。

linux_proc_banner定义:

#include <generated/compile.h>
#include <linux/module.h>
#include <linux/uts.h>
#include <linux/utsname.h>
#include <generated/utsrelease.h>
#include <linux/version.h> #ifndef CONFIG_KALLSYMS
#define version(a) Version_ ## a
#define version_string(a) version(a) extern int version_string(LINUX_VERSION_CODE);
int version_string(LINUX_VERSION_CODE);
#endif struct uts_namespace init_uts_ns = {
.kref = {
.refcount = ATOMIC_INIT(2),
},
.name = {
.sysname = UTS_SYSNAME,
.nodename = UTS_NODENAME,
.release = UTS_RELEASE,
.version = UTS_VERSION,
.machine = UTS_MACHINE,
.domainname = UTS_DOMAINNAME,
},
.user_ns = &init_user_ns,
};
EXPORT_SYMBOL_GPL(init_uts_ns); /* FIXED STRINGS! Don't touch! */
const char linux_banner[] =
"Linux version " UTS_RELEASE " (" LINUX_COMPILE_BY "@"
LINUX_COMPILE_HOST ") (" LINUX_COMPILER ") " UTS_VERSION "\n"; const char linux_proc_banner[] =
"%s version %s"
" (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")"
" (" LINUX_COMPILER ") %s\n"; //那么,linux_proc_banner相当于
// "UTS_SYSNAME version UTS_RELEASE"
// " (" LINUX_COMPILE_BY "@" LINUX_COMPILE_HOST ")"
// " (" LINUX_COMPILER ") UTS_VERSION\n"; /*
* UTS_SYSNAME
* UTS_NODENAME
* UTS_RELEASE
* UTS_VERSION
* UTS_MACHINE
* UTS_DOMAINNAME
* LINUX_COMPILE_BY
* LINUX_COMPILE_HOST
* LINUX_COMPILER
* 这些宏都是在编译kernel 是自动生成的。都放在include/generated/compile.h文件中
*/

include/generated/compile.h

#define UTS_MACHINE "arm"
#define UTS_VERSION "#3 SMP PREEMPT Tue Jul 31 12:04:09 CST 2018"
#define LINUX_COMPILE_BY "frank"
#define LINUX_COMPILE_HOST "ubuntu"
#define LINUX_COMPILER "gcc version 4.8.3 (OpenWrt/Linaro GCC 4.8-2014.04 unknown) "

那么问题又来了,compile.h是有谁生成的呢?

在scripts/mkcompile_h脚本中。

/proc/version 的生成过程的更多相关文章

  1. Linux From Scratch(从零开始构建Linux系统,简称LFS)- Version 7.7(一)

    一. 准备工作 1. 需要一个Linux宿主系统,例如早先版本的 LFS,Ubuntu/Fedora,SuSE 或者是在你的架构上可以运行的其它发行版 如果想实现Win7与Linux双系统,可参考我的 ...

  2. /proc 【虚拟文件系统】

    在安装新硬件到 Linux 系统之前,你会想要知道当前系统的资源配置状况. Linux 将这类信息全集中在 /proc 文件系统下./proc 目录下的文件都是 Linux 内核虚拟出来的,当你读取它 ...

  3. proc文件系统

    在shell终端里不带任何参数,直接运行mount命令可以显示正在挂载的文件系统.其中有这么一行 none on /proc type proc (rw) 这就是/proc文件系统.第一个域显示non ...

  4. linux 中/proc 详解

    proc 文件系统 在Linux中有额外的机制可以为内核和内核模块将信息发送给进程-- /proc 文件系统.最初设计的目的是允许更方便的对进程信息进行访问(因此得名),现在它被每一个有有趣的东西报告 ...

  5. ndk学习13: proc

    一.进程相关信息 /proc目录中包含许多以数字命名的子目录,这些数字表示系统当前正在运行进程的进程号,里面包含对应进程相关的多个信息文件 结构如下: 进程相关的信息如下: 部分信息如下 cmdlin ...

  6. Linux中/proc目录下文件详解

    转载于:http://blog.chinaunix.net/uid-10449864-id-2956854.html Linux中/proc目录下文件详解(一)/proc文件系统下的多种文件提供的系统 ...

  7. Linux /proc、/dev Principle

    目录 . /proc简介 . 内核机制相关 . 进程信息 . 硬件设备相关 . 系统信息 . /dev简介 . 内存相关 1. /proc简介 在linux的根目录下有一个/proc目录,/proc文 ...

  8. Linux下/proc目录简介

    文章转载至:http://blog.csdn.net/zdwzzu2006/article/details/7747977 1. /proc目录Linux 内核提供了一种通过 /proc 文件系统,在 ...

  9. mypc--------------->lspci,lsusb,meminfo cpuinfo ioports filesystems interrupts mounts net partitions pagetypeinfo slabinfo timer_list uptime version zoneinfo 等配置信息

    [user@username home]$ lspci00:00.0 Host bridge: Intel Corporation 4th Gen Core Processor DRAM Contro ...

随机推荐

  1. MySql_安装及简单命令

    一.下载MySql http://dev.mysql.com/downloads/file/?id=461390 版本位5.7.11.0.msi,32位的,但是该版本在64位机器上也可以使用 二.安装 ...

  2. Android之通知使用权

    通知使用权打开方式 设置--提示音和通知--通知使用权. 具体界面如图: 存在须要拥有通知使用权应用时: 不存在须要拥有通知使用权应用时: 用户为应用勾选复选框后系统弹dialog须要用户进一步确认时 ...

  3. Java笔记15:多线程

    Java实现多线程有两种方式:一是继承Thread类:二是实现Runable接口. 一.Thread实现 publicclass ThreadDemo2 { publicstaticvoid main ...

  4. 【原创】Android自定义适配器的使用方法

    比如说我们已经得到了数据,想在一个listview或者在其他的控件中显示的,并且我们显示想要自己设计样式来显示的话就要用到自定义适配器了,下面让我们结合代码讲一下具体的使用方法: 代码会有注释的哦: ...

  5. [Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘终结篇:UniLua热更新全然解读

    ---------------------------------------------------------------------------------------------------- ...

  6. spring-boot 集成 swagger 问题的解决

    spring-boot 集成 swagger 网上有许多关于 spring boot 集成 swagger 的教程.按照教程去做,发现无法打开接口界面. 项目由 spring mvc 迁移过来,是一个 ...

  7. 关于vector push_back()与其他方式读取数据的效率对比(转)

    引言: 在读取大量数据(数组)时,使用vector会尽量保证不会炸空间(MLE),但是相比于scanf的读取方式会慢上不少.但到底效率相差有多大,我们将通过对比测试得到结果. 测试数据:利用srand ...

  8. 基于redis的简易分布式爬虫框架

    代码地址如下:http://www.demodashi.com/demo/13338.html 开发环境 Python 3.6 Requests Redis 3.2.100 Pycharm(非必需,但 ...

  9. PHP-四种解析XML文件的方法

    XML处理是开发过程中经常遇到的,PHP对其也有很丰富的支持,本文只是对其中某几种解析技术做简要说明,包括:Xml parser, SimpleXML, XMLReader, DOMDocument. ...

  10. Struts2中防止表单重复提交,global-results定义全局结果处理

    1.在表单中加入<s:token/>标签 2.在动作类中加入token的拦截器 <!--如果单单写 name="token" 会丧失 defaultStack 拦 ...