日期:2014-05-16  浏览次数:20744 次

基于Linux与Busybox的Reboot命令流程分析
***************************************************************************************************************************
作者:EasyWave                                                                                 时间:2013.01.26

类别:Linux 内核系统源码分析                                                             声明:转载,请保留链接

注意:如有错误,欢迎指正。这些是我学习的日志文章......

***************************************************************************************************************************

一:Busyobx层的分析

        这段时间,在忙到一个项目时,需要在busybox中用到reboot命令,开始在busybox中的shell中输入reboot命令,始终如下的信息,然后就停止在那里了,无法重启...为了彻底的弄明白这个问题,我在网络上找了很久,终于有个人写的一个reboot流程分析,我就借花献佛.在这里重新分析下busybox是如何运行这个命令,同时又是如何调用到Linux内核中的mach_reset中的arch_reset,当针对不同的ARM芯片时,作为Linux内核开发和驱动开发的朋友,对于这个流程还是一定要了解的。要不,出现问题,又如何找出问题呢。忘记了reboot的打印信息了,如下:

The system is going down NOW !!
Sending SIGTERM to all processes.
Sending SIGKILL to all processes.
Please stand by while rebooting the system.
Restarting system.
.


通过分析busybox1.20.0的代码可以看出在init.c中有这样一行的代码,如下:

int init_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int init_main(int argc UNUSED_PARAM, char **argv)
{
	static const int magic[] = {
		RB_HALT_SYSTEM,
		RB_POWER_OFF,
		RB_AUTOBOOT
	};
	static const smallint signals[] = { SIGUSR1, SIGUSR2, SIGTERM };
	......
	/* struct sysinfo is linux-specific */
#ifdef __linux__
	/* Make sure there is enough memory to do something useful. */
	if (ENABLE_SWAPONOFF) { //是否配置了swapoff命令
		struct sysinfo info;

		if (sysinfo(&info) == 0
		 && (info.mem_unit ? info.mem_unit : 1) * (long long)info.totalram < 1024*1024
		) {
			message(L_CONSOLE, "Low memory, forcing swapon");
			/* swapon -a requires /proc typically */
			new_init_action(SYSINIT, "mount -t proc proc /proc", "");
			/* Try to turn on swap */
			new_init_action(SYSINIT, "swapon -a", "");
			run_actions(SYSINIT);   /* wait and removing */
		}
	}
#endif
	......
/* Make the command line just say "init"  - thats all, nothing else */
	strncpy(argv[0], "init", strlen(argv[0]));
	/* Wipe argv[1]-argv[N] so they don't clutter the ps listing */
	while (*++argv)
		memset(*argv, 0, strlen(*argv));

	/* Set up signal handlers */
	/* Set up signal handlers */
	if (!DEBUG_INIT) {
		struct sigaction sa;

		bb_signals(0
			+ (1 << SIGUSR1) /* halt */
			+ (1 << SIGTERM) /* reboot */
			+ (1 << SIGUSR2) /* poweroff */
			, halt_reboot_pwoff);//看到这个halt_reboot_pwoff
		signal(SIGQUIT, restart_handler); /* re-exec another init */ //看到这个restart_handler函数,这是我们需要分析的

		/* Stop handler must allow only SIGCONT inside itself */
		memset(&sa, 0, sizeof(sa));
		sigfillset(&sa.sa_