OpenWrt开发:48---openwrt的内核启动流程(17.01.4源码)

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_41453285/article/details/102767797
  • 总体执行流程如下:

  • 脚本调用流程如下:

一、启动的第一个进程(/etc/preinit)

  • u-boot从Flash分区中读取Linux内核到内存,然后跳转到内存(某个地址)执行Linux内核。Linux内核会进行一系列验证,注册相关驱动,根据分区表(见下图openwrt源码/target/linux/ramips/dts/XXX.dts,)创建分区,然后挂载根文件系统,启动第一个用户空间进程

  • 原生的Linux内核默认启动的第一个用户空间进程是(busybox)/sbin/init。但是openwrt将其修改为默认启动的第一个用户空间进程是/etc/preinit。(参见下图Linux源码/init/main.c)

  • /etc/preinit(位于openwrt源码/package/base-files/etc/preinit)其实是一个shell脚本,其执行的第一条语句如下所示:[ -z  “PREINIT”]意思为“PREINIT”为空时,即PREINIT为NULL时为真。由于执行这个preinit脚本的时候,“PREINIT”变量没有定义,所以其条件为真,于是执行后面的语句(exec  /sbin/init),preinit程序的运行暂时暂停

二、/sbin/init进程的执行

  • /sbin/init主要做以下工作:
    • ①环境变量设置、文件系统挂载、内核模块加载等
    • ②之后会创建两个进程,两个进程分别执行:
      • 执行/etc/preinit的后半部分代码:执行/etc/preinit之前会设置变量PREINIT
      • 执行/sbin/procd(位于openwrt源码/build_dir/target-mipsel_24kec+dsp_uClibc-0.9.33.2/procd-2019-10-27/prod.c):/sbin/procd执行会带-h参数
    • ③当/sbin/init退出后调用exec执行/sbin/procd替换当前的/sbin/init进程
  • 到此为止,openwrt的启动流程就结束了,ps命令查看进程号为1的进程就是最终的/sbin/procd

/etc/preinit后半部分代码介绍

  • 先是执行下面3个脚本(源码位于/package/base-files/etc/preinit)

  • preinit.sh脚本(/package/base-files/files/lib/functions/preinit.sh)中需要注意下面2个函数:
    • boot_hook_init:初始化一个函数队列
    • boot_run_hook:会运行一个函数队列

  • 再看看/etc/preinit这段代码:这段代码目的是循环执行/package/base-files/files/lib/preinit目录下的所有脚本,其实这些脚本还没真正运行,这是添加到自己的函数队列中而已

  • /package/base-files/files/lib/preinit目录如下

  • 以/package/base-files/files/lib/preinit目录下的02_default_set_state为例(其他的都差不多)
    • boot_hook_add:在一个函数队列中添加一个函数(最后后面的为函数名)

  • 通过观察发现,/etc/preinit将/lib/preinit目录下的脚本分为如下5类(如左图所示),但是实际上只实现了preinit_main和failsafe这2类,后面接的是函数名(如右图所示)

  • 下面介绍这些函数:

  • 总体的结果就是,执行/etc/preinit后半部分代码,调用preinit.sh脚本,执行preinit.sh脚本中的boot_run_hook函数。然后执行/package/base-files/files/lib/preinit目录下的脚本,执行到preinit_main的时候,队列中的所有函数就会一次执行
  • /etc/preinit执行完之后,init进程就会根据inittab文件执行其他的启动项

三、/etc/inittab的执行

  • 原生的Linux操作系统/etc/inittab文件一般是被busybox下的/sbin/init解释;而openwrt系统/etc/inittab文件(位于openwrt源码的/target/linux/ramips/base-files/etc/inittab处)是由/sbin/procd来解释
  • 关于/etc/inittab的详情见文章:https://blog.csdn.net/qq_41453285/article/details/102545624
  • /etc/inittab目的:初始化文件系统
  • /etc/inittab分析:为Linux初始化文件系统时init初始化程序所用到的配置文件,
  • /etc/inittab格式如下:每一行都是如下格式:
    • 负责设置init的初始化程序脚本在哪里:每个运行级别初始化时运行的命令:开机、关机、重启对应的命令:各运行级登录时所使用的命令(隔空后面跟的是命令的参数)。
    • 例如下面:
      • 第一行:开机启动时执行/etc/init.d/rcS脚本,参数为S和boot
      • 第二行:关机时执行/etc/init.d/rcS脚本,参数为K和shutdown

猜你喜欢

转载自blog.csdn.net/qq_41453285/article/details/102767797