上一篇说到,kernel代码重定位完成后,设置栈,跳转到 start_kernel去启动init进程。
uboot的环境变量打印:
bootargs=console=ttyS0,115200 mem=512M root=/dev/mmcblk1p1 rw rootwait init=/sbin/init
start_kernel
rest_init();
kernel_thread(kernel_init, NULL, CLONE_FS);
static int __ref kernel_init(void *unused)
if (execute_command)
ret = run_init_process(execute_command);
//grep 下 execute_command的由来
static int __init init_setup(char *str)
{
unsigned int i;
execute_command = str;
}
__setup("init=", init_setup);
下面继续分析busybox的启动:
int init_main(int argc, char **argv)
signal(SIGHUP, exec_signal);//信号的注册
parse_inittab();//解析
file = fopen(INITTAB, "r");
#define INITTAB "/etc/inittab"
new_init_action(ASKFIRST, bb_default_login_shell, VC_3);//解析inittab
new_init_action(SYSINIT, INIT_SCRIPT, "");
#define INIT_SCRIPT "/etc/init.d/rcS"
for (a = last = init_action_list; a; a = a->next)
strcmp(a->command, command)//添加到链表init_action_list中
run_actions(SYSINIT);//解析完inttab后,开始执行
for (a = init_action_list; a; a = tmp)//遍历此链表,查找SYSINIT的action
if (a->action == action)
a->pid = run(a);//执行
signal(SIGUSR1, SIG_DFL);//注册信号
pid = fork();//复制父进程
if (pid > 0) //父进程
waitfor(NULL, pid);//等待回收子进程
BB_EXECVP(cmdpath, cmd);//执行子进程。
/***********************
struct init_action {
struct init_action *next; //指针域
int action; //ASKFIRST 等
pid_t pid; //每个进程都有自己的PID
char command[INIT_BUFFS_SIZE];//
char terminal[CONSOLE_NAME_SIZE];
};
************************/
inittab内容与格式:
::sysinit:/etc/rc.d/rcS
::ctrlaltdel:/sbin/reboot
::shutdown:/etc/rc.d/rcS stop
::restart:/sbin/init
即开机后执行inittab 中一些列脚本。