Linux内核5:文件系统2_内核与文件系统衔接
1 引言
Linux文件系统和内核是相对独立的,一个内核可以安装不同的文件系统,那么文件系统与内核的衔接就变得十分重要,Linux内核是通过什么方式与各种文件系统进行衔接的?他们的工作流程是怎样的,这就是这篇文章想要分析的问题。
2 文件系统的工作流程
文件系统这个相对独立的部分有他自己的工作流程,他的起点是什么,目的是什么,这是这一章节希望理清楚的部分。
2.1 起点分析
所谓的起点,就是内核启动文件系统的代码了,以linux kernel 2.6.22的内核代码为例,主要的部分如下面所示。
相关代码1:
在文件系统的代码中,这里为起点,这是linux kernel 2.6.22的main.c中的一段代码
1 | if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0) |
可以看到,打开了一个/dev/console,这是文件系统里面的终端,也是一个句柄,然后复制了两次句柄。
这些代码的实际功能是打开了控制台,又复制了标准输出,复制了标准错误。
相关代码2:
1 | /* |
上面这段代码也是linux内核main.c里面的,主要内容是要启动初始化程序,用来初始化文件系统,也就是那些个init程序了,这些程序都放在了文件系统里面。在启动根文件系统的时候,要运行这些应用程序,就是双引号里面的那些,很明显,根据这些目录的写法,可以看出这些东西的代码都放在了文件里面。如果文件系统里面没有这些东西,就会报错,也就是panic里面的提示信息。
要注意,那些init,sh程序,都是文件系统提供的,并不是linux内核。
相关代码3:
———————————————–updating—————————–
代码2的execute_command的定义在这里面,也是main.c
1 | static int __init init_setup(char *str) |
从上面的代码看出,execute_command这个字符串只有在init_setup函数中才会被赋值,而谁调用了这个函数呢,就是下面的那一句,
一层一层的分析下去这个宏定义,会发现这个作用是:
总结:
uboot向内核传入了很多的参数,被封装在了taglist里面,被内核解析成了多了setup的段,存放在.init.setupd的代码段中,形式未cmd(字符串)。
而命令对应的处理函数
obsolete_checksetup 处理early == 0 的情况
do_early_param 处理early != 0 的情况
中进行了所有存放在.init.setup代码段的命令的执行
针对各种setup段的cmd进行全局变量execute_command的赋值
这个execute_command就是uboot传入的以init=XXXX的参数,
Uboot传入的cmd参数
init=linuxrc
execute_command=linuxrc
也就是说代码2的第7行会变成这样
1 | if(linuxrc){ |
相关代码4
至此,执行到了文件系统里面,文件系统的相关代码,不在内核中了,需要下载busybox等文件系统查看
3 总结与问题
3.1 总结
uboot向内核传递了大量的参数,封装在了taglist里面,而内核首先就是解析出来这些个参数,把他们都存放到了全局变量里面,在需要的时候使用这些参数,比如初始化的时候。
以上就是uboot这部分和内核的沟通模式,而内核与文件系统的沟通模式也是类似的,
3.2 问题
1. 文件系统进入后,内核运行了什么应用程序?
2. 文件系统的初始化模式是否和内核是一样的?
接收配置的传入
传入参数的格式是什么样的
解析配置信息
如何进行解析,并且进行识别的
应用配置信息
在什么地方用,怎么用这些信息