linux内核——12_内核与文件系统衔接流程分析

作者:GWD 时间:2019.8.1

一、课程内容
1、独立的文件系统 (Linux) SHELL
2、Linux种对文件系统的支持
3、文件系统的层次
4、熟悉每个文件夹里面都有大致什么东西
5、分析文件系统的工作流程(起点: 目的:可以运行其他应用程序,可以响应用户的命令)
二、起点分析:linux-2.6.22.6分析
1、内核的目的是运行kernel_init然后在kernel_init挂载根文件系统;
在这里插入图片描述

if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
	printk(KERN_WARNING "Warning: unable to open an initial console.\n");
			
 (void) sys_dup(0);
 (void) sys_dup(0);

打开控制台做为标准输入 复制了 标准输出 复制了标准错误
2、接下来涉及到了代码段的知识,如果执行了run_init_process就不会再执行printk了。相当于之前的switch,切换到下一个进程。若果出错了会一次执行779-782行,这些是在根文件系统中的。如果这些也没有就启动不了了,之前在移植内核时候遇到过这样的情况就是这样发生的。

if (execute_command) {				//如果命令串被定义则执行自定义的命令
	run_init_process(execute_command);
	printk(KERN_WARNING "Failed to execute %s.  Attempting "
	"defaults...\n", execute_command);
}
//如果未定义则进行默认程序执行
run_init_process("/sbin/init");				//都是由busybox所提供的
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
//如果当前的文件系统中没有可执行的初始化程序 ,则内核启动文件系统失败
panic("No init found.  Try passing init= option to kernel.");

在这里插入图片描述
3、在init_setup函数中给全局变量赋值,我们接下来看看谁调用了init_setup
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
解析:
__setup(“init=”, init_setup);

__setup_param(“init=”, init_setup, init_setup, 0)

static char __setup_str[] __initdata = “init=”;
static struct obs_kernel_param _setup
attribute_used
attribute((section(".init.setup")))
attribute((aligned((sizeof(long)))))
= { _setup_str, init_setup, 0 }
也就是在.init.setup这个段中放入obs_kernel_param这样的结构体,且early=0,这个段在lds中被定义。
4、tagglist—》内存参数、硬盘参数、视频参数、命令参数是怎么解析的?
1)、early = 0时
在这里插入图片描述
2)、early = 1时

在这里插入图片描述
梳理一下:UBOOT传入了很多的参数 tagglist,被解析为多个setup的段—存放在.init.setup的代码段中,形式为CMD(字符串),命令对应的处理函数在两个函数中,obsolete_checksetup (处理eraly为0的)、do_early_param(处理eraly不为0的)。进行了所有存放在.init.setup代码段的命令执行针对各种setup段的CMD进行全局变量的赋值

5、再举例看一下execute_command全局变量在哪里被赋值
在这里插入图片描述
也是在setup函数中被赋值,一旦绑定setup宏定义就被创建obs_kernel_param结构体
在这里插入图片描述
这个结构体叫rdinit_setup被放入了.init.setup段中,在start_kernel的parse_args,中被执行。解析参数函数parse_args又调用unknown_bootoption函数,unknown_bootoption又调用obsolete_checksetup
在这里插入图片描述

小结:tagglist---》内存参数、硬盘参数、视频参数、命令参数
parse_args("Booting kernel", static_command_line, __start___param,__stop___param - __start___param,&unknown_bootoption);
					 
unknown_bootoption  
		   
obsolete_checksetup

static int __init obsolete_checksetup(char *line)  //early为0的参数处理、
	else if (!p->setup_func) {
		printk(KERN_WARNING "Parameter %s is obsolete,"" ignored\n", p->str);
		return 1;
	} else if (p->setup_func(line + n))
		return 1;
									
static int __init do_early_param(char *param, char *val)// early不为0的参数处理
	for (p = __setup_start; p < __setup_end; p++) {
	if (p->early && strcmp(param, p->str) == 0) {
	if (p->setup_func(val) != 0)

6、execute_command是UBOOT传入的,以 init=xxxxx的参数UBOOT传入的CMD参数。
init=linurc、execute_command=linuxrc
init=
if (linuxrc)
{
run_init_process(linuxrc); 内核切换到了文件系统中进行Linuxrc应用程序的运行
}
文件系统从此开始运行:
三、在文件系统busybox中怎么运行的
1、在busybox中搜索linuxrc看看在哪里被调用
在这里插入图片描述
2、init中首先设置了一些信号,为什么呢?因为不论是shell命令,还是人为的用户程序先接触的都是文件系统,只有通过系统调用才可以接触到内核。Signal是系统内核的库函数,接触到信号后就调用系统库函数。这些程序里面基本都有一个run_action这个程序。这个程序是做什么的在下一节说。
3、

int init_main(int argc, char **argv)
	/* Set up sig handlers  -- be sure to
	* clear all of these in run() */
	signal(SIGHUP, exec_signal);
	signal(SIGQUIT, exec_signal);
	signal(SIGUSR1, shutdown_signal);
	signal(SIGUSR2, shutdown_signal);
	signal(SIGINT, ctrlaltdel_signal);
	signal(SIGTERM, shutdown_signal);
	signal(SIGCONT, cont_handler);
	signal(SIGSTOP, stop_handler);
	signal(SIGTSTP, stop_handler);

4、作业:认真理解Linux2.26参数解析的过程。找到5个类似于execute_command变量解析形式的全局变量,分析明白。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值