韦东山uboot_内核_根文件系统学习笔记4.1-第004课_根文件系统-第001节_构建根文件系统之启动第1个程序

一 内核如何启动第一个应用程序

  1. 首先挂载根文件系统
    如果在uboot中删除掉根文件系统:
    在这里插入图片描述
    启动内核:
    在这里插入图片描述
    (1)此时根文件系统已经删除,相当于空目录,所以无法启动2.打开设备的代码。上图中报的warning也和下图代码中的打印信息一致。
    在这里插入图片描述
    (2)上图报告的第二个错误信息对应下图代码的打印信息
    在这里插入图片描述
    (3)上图报告的第三个错误信息对应下图代码的打印信息
    在这里插入图片描述
  2. 内核调用init_post函数
static int noinline init_post(void)
  1. 打开设备
sys_open((const char __user *) "/dev/console", O_RDWR, 0)
(void) sys_dup(0);
(void) sys_dup(0);

dev/console:对应终端,所有的标准输入(printf)/标准输出(scanf)/标准错误(err);这里对应的是Uart0,对于其他设备可以是液晶屏幕等…

/*
 * We try each of these until one succeeds.
 *
 * The Bourne shell can be used instead of init if we are
 * trying to recover a really broken machine.
 */
if (execute_command) {
	run_init_process(execute_command);
	printk(KERN_WARNING "Failed to execute %s.  Attempting "
				"defaults...\n", execute_command);
}
  1. 那么检索execute_command的出处
execute_command:
static int __init init_setup(char *str)
{
	unsigned int i;

	execute_command = str;										//execute_command在这里被命令行参数赋值“init=”
	/*
	 * In case LILO is going to boot us with default command line,
	 * it prepends "auto" before the whole cmdline which makes
	 * the shell think it should execute a script with such name.
	 * So we ignore all arguments entered _before_ init=... [MJ]
	 */
	for (i = 1; i < MAX_INIT_ARGS; i++)
		argv_init[i] = NULL;
	return 1;
}
__setup("init=", init_setup);									//命令行参数:init=//命令行启动init_setup函数

继续追踪,既然确定execute_command是uboot启动的时候向内核传递参数得到的,那么查看uboot传递的参数是什么呢?由下图可知execute_command=/linuxrc
在这里插入图片描述

  1. 回到3.中提到的run_init_process(execute_command);
/*
 * We try each of these until one succeeds.
 *
 * The Bourne shell can be used instead of init if we are
 * trying to recover a really broken machine.
 */
if (execute_command) {
	run_init_process(execute_command);							//如果定义了execute_command就会启动对应的程序,进入该应用程序之后就会死循环,不会返回了。
	printk(KERN_WARNING "Failed to execute %s.  Attempting "
				"defaults...\n", execute_command);
}
  1. 继续看init_post函数后续部分,如果未定义execute_command那么就会执行如下代码,下列代码每一个都是一个函数。
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
  1. 小结
    linux内核执行的第一个应用程序通过两种方式传递进内核:(1)uboot的环境变量init=xxxx;(2)/sbin/init /etc/init /bin/init /bin/sh启动优先级依次变低
  2. 进入linux系统的shell
    在这里插入图片描述

ps(即进程状态)命令用于提供有关当前正在运行的进程的信息,包括其进程标识号(PID)。进程,也称为任务,是程序的执行(即,运行)实例。系统为每个进程分配一个唯一的PID。
init:linux内核执行的第一个app程序,在这里是linuxrc程序
-sh:shell程序即控制台程序

猜你喜欢

转载自blog.csdn.net/xiaoaojianghu09/article/details/104192704