OpenWRT新框架的boot过程

昨天在分析procd如何工作的时候,有找到过下面这样一段描述新架构boot过程的文字:

1) Bootloader (uboot, redboot, adam2, grub, …)
2) Linux kernel starts, tries to find the mtd partition called “rootfs”, mounts it
3) Linux executes /etc/preinit
4) Preinit waits a few seconds for failsafe triggering
5) Preinit mounts or initializes the jffs2 overlay
6) Preinit loads kernel modules specified in /etc/modules.d/
7) Preinit executes hotplug2, a kernel uevent handler
8) Preinit hands control off to init to start the main boot
9) The init process executes all /etc/rc.d/ scripts to bring up services

今天发现,事实并不是这样的,至少在我手上的系统中并非如此。首先,我在uboot中打印了uboot传给kernel的参数(著名的cmdline参数):

bootargs=console=ttyS0,115200 root=31:02 rootfstype=squashfs init=/sbin/init mtdparts=ar7240)
bootcmd=bootm 0x9F020000

其中,root=31:02是告诉kernel知道rootfs是在mtdblock2上面。使用这种挂载rootfs的方式时,kernel必须包含有加载rootfs所需要的全部驱动,即,这里的kernel在编译时是加入了mtd设备相关驱动程式的。

kernel在挂载完rootfs之后,根据uboot告诉它的init=path_to_init_file参数,kernel会找到path_to_init_file并执行这个文件。

所以,这里,我们的系统在挂载文件系统之后,是先执行的/sbin/init。

init是一个用C写的程序,同样也是在luci2新框架下面。找了一下它的代码,在luci2/procd/initd/init.c,具体如下(只是main):

int
main(int argc, char **argv)
{
        pid_t pid;

        sigaction(SIGTERM, &sa_shutdown, NULL);
        sigaction(SIGUSR1, &sa_shutdown, NULL);
        sigaction(SIGUSR2, &sa_shutdown, NULL);

        early();
        cmdline();
        watchdog_init(1);

        pid = fork();
        if (!pid) {
                char *kmod[] = { "/sbin/kmodloader", "/etc/modules-boot.d/", NULL };

                if (debug < 3) {
                        int fd = open("/dev/null", O_RDWR);

                        if (fd > -1) {
                                dup2(fd, STDIN_FILENO);
                                dup2(fd, STDOUT_FILENO);
                                dup2(fd, STDERR_FILENO);
                                if (fd > STDERR_FILENO)
                                        close(fd);
                        }
                }
                execvp(kmod[0], kmod);
                ERROR("Failed to start kmodloader\n");
                exit(-1);
        }
        if (pid <= 0)
                ERROR("Failed to start kmodloader instance\n");
        else
                waitpid(pid, NULL, 0);
        uloop_init();
        preinit();
        uloop_run();

        return 0;
}

我们看到,这里其实一直到最后才进行了preinit。

不过,在此之前进行的操作都和用户没多大关系,所以,似乎直接认为是从preinit好像也没什么不妥。

唔,忍不住对main里面调用的几个函数进行了进一步挖掘。

early() 是在luci2/procd/initd/early.c中,可以在这里看到,它打印了一条消息:“Console is alive”。这条信息在启动打印信息里面是可以明显看到的。它在后台做的事情还包括了(这些是在打印Console is alive前就完成的):

1. 挂载proc,sysfs,tmpfs。

2. 添加设备/dev/null。

3. 将stdin,stdout,stderr都设置为我们指定的设备,比如“/dev/console”;如果我们没有指定设备,会被设置为/dev/nul,即被扔掉。

cmdline() 是在luci2/procd/initd/init.c中,它是从/proc/cmdline中取出init_debug,并设置debug等级。

watchdog() 就不用说了。

然后后面的,通过execvp来执行“ /sbin/kmodloader /etc/modules.d/”,则是把分离编译的kernel module设备挂载上来。

这里就到最后了,就是preinit()。这里其实也是先执行了“ /sbin/procd -h /etc/hotplug-preinit.json ”,然后才执行的“/bin/sh /etc/preinit”。具体在preinit中,则又是去执行在/lib/preinit下的一个个脚本。这里有个神奇的/lib/functions.sh,比较好奇,但是看了一眼有些晕,功夫不够,哪天心情好翻开看看再。

到此,init过程结束。

参考:http://lirobo.blogspot.tw/2014/07/openwrt-boot.html

OpenWRT新框架的boot过程

时间: 2024-08-14 06:02:21

OpenWRT新框架的boot过程的相关文章

OpenWRT新框架的flash layout

唔,新框架下,同时支持了一个只读的文件系统(SquashFS)和一个可读写的文件系统(jffs2).所以,这些是怎么处理的,需要进一步了解. 关于flash 在大多数嵌入式系统中,flash是其主要的程序和data的存储空间.因为flash的速度原因,在系统运行时,这些程序和data还要再被搬移到RAM中去,运行时,CPU事实上是从RAM中取程序和data.著名的uboot就是专门负责把操作系统搬移到RAM中去的,至于存储在文件系统中的data和其他程序,则是由操作系统负责去加载. 根据其内部结

nios ii boot过程

目录 1       概述....................................................................... 1 2       几种常见的boot方式......................................................... 1 2.1.................................................................................

niosii boot过程

1 概述Nios II 的boot过程要经历两个过程. FPGA器件本身的配置过程.FPGA器件在外部配置控制器或自身携带的配置控制器的控制下配置FPGA的内部逻辑.如果内部逻辑中使用了Nios II,则配置完成的FPGA中包含有Nios II软核CPU. Nios II本身的引导过程.一旦FPGA配置成功后,Nios II 就被逻辑中的复位电路复位,从reset地址开始执行代码.Nios II 的reset地址可以在SOPC builder的“Nios II More‘CPU’setting”

Android Service组件在新进程绑定(bindService)过程

1.首先看两个例子 (1)进程内 Client端 public class CounterService extends Service implements ICounterService { ...... public class CounterBinder extends Binder { public CounterService getService() { return CounterService.this; } } ...... } Server端 public class Ma

放弃OT了,找了个新框架ThinkCMF

放弃OT了,找了个新框架ThinkCMF,感觉还不错,用用看. 选择OT的原因: 1. OT基于ThinkPHP 2. OT对ThinkPHP进行了封装,使得开发应用更加简单 3. yershop应用是基于OT的 放弃的原因: 1. OT已经长时间没人维护了 2. OT提供的版本包问题太多,不适合使用. 接下来几天研究下ThinkCMF,希望有所进展.

Android4.3引入的UiAutomation新框架官方简介

译者序:Google在Android 4.3发布时提供了一套新的UiAutomation框架来支持用户界面自动化测试,该框架通过运用已有的Accessibility APIs来模拟用户跟设备用户界面的交互:比如获取窗口界面控件和注入事件等.如在4.3之前UiAutomator工具是通过InputManager或者更早的WindowManager来注入KeyEvent等,4.3之后用的就是新框架UiAutomation使用的Accessibility APIs来注入事件了. Class Overv

ReactiveCocoa - iOS开发的新框架

本文转载至 http://www.infoq.com/cn/articles/reactivecocoa-ios-new-develop-framework ReactiveCocoa(其简称为RAC)是由Github 开源的一个应用于iOS和OS X开发的新框架.RAC具有函数式编程和响应式编程的特性.它主要吸取了.Net的 Reactive Extensions的设计和实现.本文将详细介绍该框架试图解决什么问题,以及其用法与特点. ReactiveCocoa试图解决什么问题 经过一段时间的研

Eclipse中创建新的Spring Boot项目

简单几步,在Eclipse中创建一个新的Spring Boot项目: 1.Eclipse中安装STS插件: Help -> Eclipse Marketplace... Search或选择"Popular"标签,选择Spring Tool Suite (STS) for Eclipse插件,安装: 2.New -> Project... 找到Spring目录,选择Spring Starter Project,Next 3.填写跟项目相关的各种信息,然后Next: 4.选择需

[转] iOS --- ReactiveCocoa - iOS开发的新框架

转载唐巧的博客:ReactiveCocoa - iOS开发的新框架