admin 管理员组文章数量: 1086019
首先来张图简要的从源码的角度展示一下Linux内核的路由器启动过程(图片看不清的话建议放大后查看):
下面的重点是关注一下,kernel启动后,从第一个用户进程执行,到系统启动完毕,做了哪些事。
1. 路由器内核启动执行流程
UBoot在设置好一些环境参数后会将PC指针指向内核代码,从此CPU就交由Linux全权掌控。网上很多详解Linux启动的文章,在此就不多此一举的分析代码了,但还是画个流程图。
注意到流程图中的蓝色方框,init程序启动后会根据inittab中的配置来运行相应的程序或脚本。一般inittab会放到/etc文件加下,但是路由器中是在/etc_ro文件夹下。找到inittab文件,查看,发现只有如下两行信息:
::sysinit:/etc_ro/rcS
ttyS1::respawn:/bin/sh
2. 理解inittab文件作用机制
解读:Inittab文件每行有四个字段,字段之间用“:”分开,形式如下:
ID:入口唯一标识符,它是一个字符串,getty和mingetty等程序项,要求id和tty的编号相同。
Runlevel:配置行适用的运行级别,着这里可填入多个运行级别,比如12345或者25等
Action:运行方式如下表:
Process:所要执行的shell命令,任何合法的shell语法均适用于该字段。
现在,我们再来解读inittab里的两行信息:
::sysinit:/etc_ro/rcS //不论在哪个执行等级,都将执行/etc_ro/rcS脚本
ttyS1::respawn:/bin/sh //启动并监视/bin/sh,若/bin/sh终止则重启它
/etc_ro/rcS:脚本完成了一些系统初始化工作,它完成了磁盘检查,加载硬件模块一起其他一些需要优先执行的任务。
/bin/sh:脚本解释器,作用不解释。
知道了init程序加载inittab文件的机制后,如果我们想在开机的时候执行某些程序或脚本就可以借助inittab文件实现,相信你知道怎么做了。
设一道题目作为练习:
写一个脚本文件命名mystartmount.sh,要求系统在开机时执行该脚本,打印hello world信息。
3. init第一个启动的脚本文件rcS
查看rcs文件,内容及解释如下:
从图片中的代码可以看到,该文件除了创建一些目录节点外,启动了Telnet,将nvram_daemon放入后台运行,还启动了用户程序init_system。从名字上理解似乎这个应用程序是初始化系统的,但是我们的Linux系统都已经跑起来了,还要它初始化什么呢?
这个init_system的程序到底做了什么,请看下节。
4. init_system做了什么
init_system的源码位于user/lighttpd-1.4.20/cgi_src/目录下,查看init_system.c,找到main函数:
int main(int argc, char *argv[])
{
if (argc < 2) {
usage();
return -1;
}
if (!strcmp(argv[1], "start")) {
if (set_default() < 0)
return -1;
init_internet();
do_system("lighttpd -f /etc_ro/lighttpd/lighttpd.conf -m /etc_ro/lighttpd/lib");
} else if (!strcmp(argv[1], "restart")) {
init_internet();
} else {
usage();
}
return 0;
}
函数除了调用了do_system启动Lighttpd外,还调用init_Internet()。刨根问个底吧,查看init_Internet()代码,发现该函数在调用Lighttpd服务器里的一些CGI之前,运行了Internet.sh脚本,这是/sbin目录下的shell脚本。
static void init_internet(void)
{
do_system("internet.sh");
do_system("/etc_ro/lighttpd/www/cgi-bin/wireless.cgi init");
do_system("/etc_ro/lighttpd/www/cgi-bin/firewall.cgi init");
do_system("/etc_ro/lighttpd/www/cgi-bin/adm.cgi init");
do_system("/etc_ro/lighttpd/www/cgi-bin/internet.cgi init");
#if defined CONFIG_RALINKAPP_SWQOS || defined CONFIG_RALINKAPP_HWQOS
do_system("/etc_ro/lighttpd/www/cgi-bin/qos.cgi init");
#endif
#if defined CONFIG_USER_STORAGE
do_system("/etc_ro/lighttpd/www/cgi-bin/nas.cgi init");
do_system("/etc_ro/lighttpd/www/cgi-bin/usb.cgi init");
#endif
}
我们知道,系统下的internet.sh是随开机启动的。我们又可以联想到,假如我们要在开机执行一个我们自定义的脚本,完全可以将我们的脚本文件放在internet.sh里面调用,当然也可以放在rcS脚本里面调用,其实讲了这么多主要用意在此。internet.sh本身的内容我们现在不必理会,知道它是处理进行一些网络设置就行了。
至此,Linux系统以及一些开机启动的附属程序及shell脚本都启动完成!
版权声明:本文标题:【智能路由器】源码追踪路由器启动过程 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://roclinux.cn/b/1738320681a1963128.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论