OpenWrt的内核启动分析

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

在这里插入图片描述

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

  Linux内核(根文件为busybox)默认启动的第一个用户空间进程是/sbin/init。但是openwrt将其修改为默认启动的第一个用户空间进程是/etc/preinit。
  在linux源码文件的/init/main.c文件内,static int __ref kernel_init(void *unused)函数在执行完后会调用/sbin/init
在这里插入图片描述
  而在openwrt源码里面/package/base-files/file/etc/preinit其实是一个shell脚本,内容为:

#!/bin/sh
# Copyright (C) 2006-2016 OpenWrt.org
# Copyright (C) 2010 Vertical Communications

[ -z "$PREINIT" ] && exec /sbin/init

export PATH="%PATH%"

. /lib/functions.sh
. /lib/functions/preinit.sh
. /lib/functions/system.sh

boot_hook_init preinit_essential
boot_hook_init preinit_main
boot_hook_init failsafe
boot_hook_init initramfs
boot_hook_init preinit_mount_root

for pi_source_file in /lib/preinit/*; do
	. $pi_source_file
done

boot_run_hook preinit_essential

pi_mount_skip_next=false
pi_jffs2_mount_success=false
pi_failsafe_net_message=false

boot_run_hook preinit_main

  编译后在openwrt系统内部内容如下图所示:
在这里插入图片描述
  其执行的第一条语句如下所示:[ -z “PREINIT”]意思为“PREINIT”为空时,即PREINIT为NULL时为真。由于执行这个preinit脚本的时候,“PREINIT”变量没有定义,所以其条件为真,于是执行后面的语句(exec /sbin/init)。
  /etc/preinit执行完之后会执行/etc/inittab文件。

二、/etc/inittab文件

  Linux操作系统/etc/inittab文件一般是被busybox下的/sbin/init解释;而openwrt系统/etc/inittab文件(位于openwrt源码的/target/linux/ramips/base-files/etc/inittab处)是由/sbin/procd来解释。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/xxxx123041/article/details/132722419