rootfs启动第1个程序

发布时间 2023-09-05 22:43:19作者: charlie12345
static int noinline init_post(void)
{
	if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)		//标准输出
	(void) sys_dup(0);														//复制,作为标准输入
	(void) sys_dup(0);														//复制,作为标准错误

	if (execute_command) {
		run_init_process(execute_command);									//若有传入参数,"init=...",则执行该函数,该函数一般是死循环,一去不返
	}
	run_init_process("/sbin/init");											//若上面的函数执行失败,则执行该函数,该函数一般是死循环,一去不返
	run_init_process("/etc/init");											//若上面的函数执行失败,则执行该函数,该函数一般是死循环,一去不返
	run_init_process("/bin/init");											//若上面的函数执行失败,则执行该函数,该函数一般是死循环,一去不返
	run_init_process("/bin/sh");											//若上面的函数执行失败,则执行该函数,该函数一般是死循环,一去不返
}


		static int __init init_setup(char *str)
		{
			execute_command = str;
		}
		__setup("init=", init_setup);


根文件系统下的,ls,cp,init 程序,本质是链接到 busybox.
内核的目的:启动应用程序。
/sbin/init 等第一个应用程序启动后,是要启动客户的应用程序

init 程序:
	(1)读取配置文件
	(2)解析配置文件
	(3)执行(用户程序)

			
busybox -> init_main										busybox-1.7.0\init\init.c
				| signal(SIGINT, ctrlaltdel_signal);
									| run_actions(CTRLALTDEL);
				| signal(SIGTERM, shutdown_signal);
									| shutdown_system();
										| run_actions(SHUTDOWN);

				| parse_inittab
					| file = fopen(INITTAB, "r");					//打开配置文件 "/etc/inittab"	/* inittab file location */
					| new_init_action(a->action, command, id);		//(1)创建一个 init_action 结构,填充		(2)把这个结构放入 init_action_list 链表
				| run_actions(SYSINIT);
					| waitfor(a, 0);								//执行应用程序,等待它执行完毕
						| run(a);									//创建process子进程
						| waitpid(runpid, &status, 0);				//等待它结束
					| delete_init_action(a);						//在 init_action_list 链表中删除
				| run_actions(WAIT);
					| waitfor(a, 0);								//执行应用程序,等待它执行完毕
						| run(a);									//创建process子进程
						| waitpid(runpid, &status, 0);				//等待它结束
					| delete_init_action(a);						//在 init_action_list 链表中删除
				| run_actions(ONCE);
					| run(a);										//创建process子进程
					| delete_init_action(a);						//在 init_action_list 链表中删除
				| while(1){
					run_actions(RESPAWN);
						| if (a->pid == 0) {
							 a->pid = run(a);
						 }
					run_actions(ASKFIRST);
						| if (a->pid == 0) {
							 a->pid = run(a);
										| 打印"\nPlease press Enter to activate this console. "
										| while (read(0, &c, 1) == 1 && c != '\n');		等待回车
										| 创建进程
						 }
					wpid = wait(NULL);								//等待子进程推出
					while (wpid > 0) {
						a->pid = 0;									//退出后,就设置pid=0
					}
				}


static void parse_inittab(void)
{
	if (file == NULL) {
		/* No inittab file -- set up some default behavior */					//从默认的 new_init_action 反推出默认的配置文件
		/* Reboot on Ctrl-Alt-Del */
		new_init_action(CTRLALTDEL, "reboot", "");								//::CTRLALTDEL:reboot
		/* Umount all filesystems on halt/reboot */
		new_init_action(SHUTDOWN, "umount -a -r", "");							//::SHUTDOWN:umount -a -r
		/* Swapoff on halt/reboot */
		if (ENABLE_SWAPONOFF) new_init_action(SHUTDOWN, "swapoff -a", "");		//该项一般不用
		/* Prepare to restart init when a HUP is received */
		new_init_action(RESTART, "init", "");									//::RESTART:init
		/* Askfirst shell on tty1-4 */
		new_init_action(ASKFIRST, bb_default_login_shell, "");					//::ASKFIRST:-/bin/sh
		new_init_action(ASKFIRST, bb_default_login_shell, VC_2);				//tty2::ASKFIRST:-/bin/sh
		new_init_action(ASKFIRST, bb_default_login_shell, VC_3);				//tty3::ASKFIRST:-/bin/sh
		new_init_action(ASKFIRST, bb_default_login_shell, VC_4);				//tty4::ASKFIRST:-/bin/sh
		/* sysinit */
		new_init_action(SYSINIT, INIT_SCRIPT, "");								//::SYSINIT:/etc/init.d/rcS
	}

}



new_init_action(ASKFIRST, bb_default_login_shell, VC_2);		//实际等于 new_init_action(ASKFIRST, "-/bin/sh", "/dev/tty2");
static void new_init_action(int action, const char *command, const char *cons)
	(1)创建一个 init_action 结构,填充
	(2)把这个结构放入 init_action_list 链表

		
busybox-1.7.0\examples\inittab 的格式如下
	# Format for each entry: <id>:<runlevels>:<action>:<process>
	id ==> /dev/id,用作终端, stdin, stdout, stderr
	runlevels: 忽略
	action: 执行时机		sysinit, respawn, askfirst, wait, once, restart, ctrlaltdel, and shutdown.
	process: 应用程序或脚本

参考:韦东山Linux教程