linux内核与文件系统的衔接关系

Posted 西邮菜

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux内核与文件系统的衔接关系相关的知识,希望对你有一定的参考价值。

    一、如何从内核跳转到busybox,和文件系统的工作流程  

      在创建根文件系统的时候,如果使用Busybox的话,只需要在/dev目录下创建必要的设备节点,在/etc目录下增加一些配置文件即可,当然,如果Busybox使用动态链接,那么还需要再/lib目录下包含库文件。下面是Busybox源码目录结构图:

	if (execute_command)
		run_init_process(execute_command);

	run_init_process("/sbin/init");
	run_init_process("/etc/init");
	run_init_process("/bin/init");
	run_init_process("/bin/sh");

        如果设立了execute_command变量则跳转到他的代码中,这里execute_command=linuxrc,则跳转到busybox上,其实linuxrc与/sbin/init都指向了busybox文件系统。现在开始跑文件系统的代码。进入的是init_main函数。

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);
    
    console_init();

    parse_inittab();

    run_actions(SYSINIT);

	run_actions(WAIT);

	run_actions(ONCE);

    while (1) 
		run_actions(RESPAWN);

		run_actions(ASKFIRST);

		sleep(1);

		wpid = wait(NULL);
		while (wpid > 0) 
			for (a = init_action_list; a; a = a->next) 
				if (a->pid == wpid) 
					a->pid = 0;
					message(L_LOG, "process '%s' (pid %d) exited. "
							"Scheduling it for restart.",
							a->command, wpid);
				
			
			wpid = waitpid(-1, NULL, WNOHANG);
		

二、__setup宏分析原理

下面是 __setup宏分析,__setup这条宏在Linux Kernel中,使用最多的地方就是定义处理Kernel的启动参数 的函数及数据结构,宏定义如下:

#define __setup(str, fn)					\\
	static char __setup_str_##fn[] __initdata = str;	\\
	static struct obs_kernel_param __setup_##fn		\\
		 __attribute_used__				\\
		 __attribute__((__section__(".init.setup")))	\\
		=  __setup_str_##fn, fn 


init.h:
struct obs_kernel_param 
	const char *str;
	int (*setup_func)(char *);
;


vmlinux.lds.S:
  . = ALIGN(16);
  __setup_start = .;
  .init.setup :  *(.init.setup)   .init.setup段的位置。
  __setup_end = .;

比如:__setup("init=", init_setup);被解析后就是:

#define __setup(init=,init_setup )					\\
	static char __setup_str_ __initdata = “init=”;	\\
	static struct obs_kernel_param __setup_		\\
		 __attribute_used__				\\
		 __attribute__((__section__(".init.setup")))	\\
		=  __setup_str_, fn 

初始化内容为"root=",由于该变量用 __initdata修饰,它将被放入.init.data输入段;另一变量是结构变量__setup_str,其类型为 struct obs_kernel_param, 该变量被放入 输入段.init.setup中。

通过__setup宏定义obs_kernel_param结构变量都被放入.init.setup段中,这样一来实际是使.init.setup段变成一张表Kernel在处理每一个启动参数时,都会来查找这张表,与每一个数据项中的成员str进行比较,如果完全相同,就会调用该数据项的函数指针成员setup_func所指向的函数(该函数是在使用__setup宏定义该变量时传入的函数参数),并将启动参数 如root=后面的内容 传给该处理函数。

execute_command是UBOOT传入的,以 init=xxxxx的参数UBOOT传入的CMD参数。
init=linurc、execute_command=linuxrc。最后程序跳转进busybox文件系统。(
uboot传来init=linurc,我们的“init=”经过段中表查找得出linuxrc,所以最终execute_command=linuxrc

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

以上是关于linux内核与文件系统的衔接关系的主要内容,如果未能解决你的问题,请参考以下文章

Linux 内核Linux 操作系统结构 ( Linux 内核在操作系统中的层级 | Linux 内核子系统及关系 | 进程调度 | 内存管理 | 虚拟文件系统 | 网络管理 | 进程间通信 )

Linux和安卓具体是存在啥关系

linux发行版和内核的关系

Linux内核编程-0:来自内核的 HelloWorld

Linux 内核进程管理 ( 进程与操作系统 | 进程与程序 | 进程与线程 | 虚拟地址空间 )

dev devfs udev sysfs及关系