构建根文件系统启动(1)
a、挂接根文件系统
内核怎样启动第一个应用程序 {
b、启动应用程序
1、打开设备
if (sys_open((const char __user *) "/dev/console", O_RDWR, 0) < 0)
printk(KERN_WARNING "Warning: unable to open an initial console.\n");
(void) sys_dup(0); 复制
(void) sys_dup(0); 复制
"/dev/console" 里面为标准输入输出错误,printf 、scanf、err() 终端 现在为串口0
if (execute_command) { run_init_process(execute_command); printk(KERN_WARNING "Failed to execute %s. Attempting " "defaults...\n", execute_command); } run_init_process("/sbin/init"); run_init_process("/etc/init"); run_init_process("/bin/init"); run_init_process("/bin/sh");
2、通过run_init_process启动应用程序具体哪一个依次优先考虑(执行后一去不复返):
a、命令行init = xxxxxxxxxxxxxxx(u-boot传过来的参数)
b、/sbin/init
c、............
d、.............
f、.............
构建根文件系统
busybox ls cp cd ........
lrwxrwxrwx 1 1000 1000 7 Jan 6 2010 /bin/ls -> busybox
lrwxrwxrwx 1 1000 1000 7 Jan 6 2010 /bin/cp -> busybox
执行ls cp其实就是执行 busybox应用程序
lrwxrwxrwx 1 1000 1000 14 Jan 6 2010 /sbin/init -> ../bin/busybox
u-boot:启动内核
内核:启动应用程序 --》先启动 /abin/init -->启动客户程序
1、配置文件
init程序 { 2、解析配置文件
3、执行应用程序
busybox --》 init_main
parse_inittab
file = fopen(INITTAB, "r"); //打开配置文件/etc/inittab
new_init_action //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.
等待回车
创建子进程
}
wpid = wait(NULL); //等待子进程退出
while (wpid > 0) {
a->pid = 0; //退出后,就设置pid=0
}
}
配置文件:
a、指定程序
b、何时执行
从默认的new_init_action反推出默认的配置文件
#inittab格式:
#<id>:<runlevels>:<action>:<process>
#id =》 /dev/id 用作终端: stdin ,stdout,stderr:printf,scanf,err
#runlevels:忽略
#action:执行时机
# <action>: Valid actions include: sysinit, respawn, askfirst, wait, once,
# restart, ctrlaltdel, and shutdown.
#process:脚本或应用程序
::CTRLALTDEL:reboot
::SHUTDOWN:umount -a -r
::RESTART:init
::ASKFIRST;-/bin/sh
tty2::ASKFIRST;-/bin/sh
tty3::ASKFIRST;-/bin/sh
tty4::ASKFIRST;-/bin/sh
::SYSINIT:/etc/init.d/rcS
/* Reboot on Ctrl-Alt-Del */ new_init_action(CTRLALTDEL, "reboot", ""); /* Umount all filesystems on halt/reboot */ new_init_action(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", ""); /* Askfirst shell on tty1-4 */ new_init_action(ASKFIRST, bb_default_login_shell, ""); new_init_action(ASKFIRST, bb_default_login_shell, VC_2); new_init_action(ASKFIRST, bb_default_login_shell, VC_3); new_init_action(ASKFIRST, bb_default_login_shell, VC_4); /* sysinit */ new_init_action(SYSINIT, INIT_SCRIPT, "");
new_init_action(ASKFIRST, bb_default_login_shell, VC_2); #define LIBBB_DEFAULT_LOGIN_SHELL "-/bin/sh" # define VC_2 "/dev/tty2"
new_init_action(ASKFIRST, -/bin/sh, /dev/tty2);
struct init_action {
struct init_action *next;
int action;
pid_t pid;
char command[INIT_BUFFS_SIZE];
char terminal[CONSOLE_NAME_SIZE];
};
static void new_init_action(int action, const char *command, const char *cons) { struct init_action *new_action, *a, *last; if (strcmp(cons, bb_dev_null) == 0 && (action & ASKFIRST)) return; /* Append to the end of the list */ for (a = last = init_action_list; a; a = a->next) { /* don't enter action if it's already in the list, * but do overwrite existing actions 已存在则覆盖,否者新建*/ if ((strcmp(a->command, command) == 0) && (strcmp(a->terminal, cons) == 0) ) { a->action = action; return; } last = a; } new_action = xzalloc(sizeof(struct init_action)); if (last) { last->next = new_action; } else { init_action_list = new_action; } strcpy(new_action->command, command); new_action->action = action; strcpy(new_action->terminal, cons); messageD(L_LOG | L_CONSOLE, "command='%s' action=%d tty='%s'\n", new_action->command, new_action->action, new_action->terminal);
new_init_action(int action, const char *command, const char *cons)
最小根文件系统需要
1、/dev/console /dev/null //如果没有设置标准输出则定位到这
2、init本身即busybox
3、/ect/inittab
4、配置文件里指定的应用程序
5、库