博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux 文件系统sysvinit 流程分析
阅读量:6419 次
发布时间:2019-06-23

本文共 10390 字,大约阅读时间需要 34 分钟。

 

参考网上许多的教程。

然后有一下相关的笔记:

kernel 在挂载完文件系统后,会执行第一个进程init 

这个进程的PID为1

这个进程是所有进程的父进程

 

init 进程,首先要去读取inittab中的数据,根据这里面的数据去执行相关的初始化。

在inittab  可以指定默认的运行级别

  

id:5:initdefault:

还会规定第一个执行的程序

si::sysinit:/etc/init.d/rcS

 

//指定单用户模式~~:S:wait:/sbin/sulogin

 

在TI的板子上还规定终端的显示的开关

0:2345:respawn:/sbin/getty 115200 ttyO0

 

 

这里提到,他规定下一个执行的是/etc/init.d/rcS

在/etc/init.d/rcS 内又做了哪些工作呢?

PATH=/sbin:/bin:/usr/sbin:/usr/bin                                 //设置环境变量             runlevel=S                                                                      //设置运行级别prevlevel=N                                                                     umask 022                                                                       //设置默认权限补码export PATH runlevel prevlevel                                          //对外发布这些变量

 

trap ":" INT QUIT TSTP //这里话的含义是忽略ctrl + c中断信号

 

exec /etc/init.d/rc S    //运行/etc/init.d/rc    并加一个参数S

 

 

下面进入rc文件分析

1 # rc        This file is responsible for starting/stopping                      2 #       services when the runlevel changes.                                     3 4 //在文件一开始,就说明了这个文件是当运行级别改变就要更改相关的服务

 

//设置终端,将 CR 字符映射为 NL 字符,避免阶梯效应  stty onlcr 0>&1

 

 

# Get first argument. Set new runlevel to this argument.                        [ "$1" != "" ] && runlevel=$1                                                   if [ "$runlevel" = "" ]                                                         then                                                                              echo "Usage: $0 
" >&2 exit 1 fi //如果没有获取到运行级别就退出

 

previous=$PREVLEVEL  [ "$previous" = "" ] && previous=N    //传入参数是S的话,则$runleve=S $previous=N  export runlevel previous

 

//若$runlevel=“S”,即检查rcS.d是否为目录。  if [ -d /etc/rc$runlevel.d ]  then    //rcS.d是目录    PROGRESS_STATE=0    //Split the remaining portion of the progress bar into thirds    progress_size=$(((100 - $PROGRESS_STATE) / 3))//progress_size = 100/3 =33    case "$runlevel" in//runlevel=S        0|6)            first_step=-100            progress_size=100            step_change=1            ;;     S)            //Begin where the initramfs left off and use 2/3of the remaining space            first_step=$PROGRESS_STATE ///progress_size = 100/3 =33            progress_size=$(($progress_size * 2))//progress_size=66            step_change=1            ;;        *)            //Begin where rcS left off and use the final 1/3 ofthe space (by leaving progress_size unchanged)            first_step=$(($progress_size * 2 + $PROGRESS_STATE))            step_change=1            ;;    esac

 

 

num_steps=0    for s in /etc/rc$runlevel.d/[SK]*; //s取/etc/rcS.d目录下以S或K开头的文件名    do        //这句话的含义去掉变量s中所有的/etc/rcS.d/S??的部分        //例:s=/etc/rc$runlevel.d/S10checkroot,那么去掉/etc/rc$runlevel.d/K??部分后,s为checkroot    case "${s##/etc/rc$runlevel.d/S??}" in        gdm|xdm|kdm|reboot|halt)//若s剩下的文件名中为这五个则跳出for语句            break            ;;    esac    num_steps=$(($num_steps + 1))//num_steps递加,表示查找到此目录下/etc/rcS.d有多少个脚本  done//for语句结束

 

step=0     # First, run the KILL scripts.       首先运行KILL          if [ $previous != N ]                                    //由于previous = N ,所以一下不执行                       then                                                                                for i in /etc/rc$runlevel.d/K[0-9][0-9]*                                        do                                                                                  # Check if the script is there.                                                 [ ! -f $i ] && continue                                                                                                                                         # Stop the service.                                                             startup $i stop                                                             done                                                                        fi

 

 

# Now run the START scripts for this runlevel.                                  for i in /etc/rc$runlevel.d/S*                                                  do                                                                                  [ ! -f $i ] && continue                                                                                                                                         if [ $previous != N ] && [ $previous != S ]     //由于previous为N所以跳过                    then                                                                                #                                                                               # Find start script in previous runlevel and                                    # stop script in this runlevel.                                                 #                                                                               suffix=${i#/etc/rc$runlevel.d/S[0-9][0-9]}                                      stop=/etc/rc$runlevel.d/K[0-9][0-9]$suffix                                      previous_start=/etc/rc$previous.d/S[0-9][0-9]$suffix                            #                                                                               # If there is a start script in the previous level                              # and _no_ stop script in this level, we don't                                  # have to re-start the service.                                                 #                                                                               [ -f $previous_start ] && [ ! -f $stop ] && continue                        fi                                                                              case "$runlevel" in                                                                 0|6)                                                                                startup $i stop                                                                 ;;                                                *)                                                                                  startup $i start            //然后启动了相关的服务   运行在文件前面定义的 startup 函数                                   ;;                                                                      esac                                                                        done                                                                          fi

 

startup函数有如下定义:

#                                                                               # Start script or program.                                                      #                                                                               startup() {                                                                       # Handle verbosity                                                              [ "$VERBOSE" = very ] && echo "INIT: Running $@..."                                                                                                             case "$1" in             //判断第一个参数,如果是一个脚本,执行第一个                    *.sh)                                                                               # Source shell script for speed.                                                (                                                                                   trap - INT QUIT TSTP                                                            scriptname=$1                                                                   shift                               //shift 命令每执行一次,变量的个数($#)减一,而变                    量值提前一位                                          . $scriptname                  //在执行第一个参数                                             )                                                                               ;;                                                                          *)                            //如果不是一个脚本,那么认为是一个服务                                                      "$@"                                                                            ;;                                                                        esac                                                                            startup_progress             //再运行前一个函数                                                  }

 

startup_progress 函数详解

startup_progress() {                                                                step=$(($step + $step_change))                                                  if [ "$num_steps" != "0" ]; then                                                    progress=$((($step * $progress_size / $num_steps) + $first_step))           else                                                                                progress=$progress_size                                                     fi                                                                              #echo "PROGRESS is $progress $runlevel $first_step + ($step of $num_steps) $step_change $progress_size"    #if type psplash-write >/dev/null 2>&1; then                                    #    TMPDIR=/mnt/.psplash psplash-write "PROGRESS $progress" || true            #fi                                                                             if [ -e /mnt/.psplash/psplash_fifo ]; then                                          echo "PROGRESS $progress" > /mnt/.psplash/psplash_fifo                      fi                                                                              echo progress over...                                                       }

 

 

 

最后,执行qt.sh

#Uncomment to cause psplash to exit manually, otherwise it exits when it sees a VC switchif [ "x$runlevel" != "xS" ] && [ ! -x /etc/init.d/xserver-nodm ]; then              . /etc/init.d/qt.sh                                                         #    if type psplash-write >/dev/null 2>&1; then                                #        TMPDIR=/mnt/.psplash psplash-write "QUIT" || true                      #       umount /mnt/.psplash                                                    #    fi                                                                         fi

 

 

参考:

http://www.cnblogs.com/cnland/archive/2013/03/26/2981967.html

https://wiki.archlinux.org/index.php/Arch_boot_process_(%E7%AE%80%E4%BD%93%E4%B8%AD%E6%96%87)#Init_.E6.B5.81.E7.A8.8B

http://blog.chinaunix.net/uid-17188120-id-4073497.html

你可能感兴趣的文章
windows下ACS服务器的认证(h3c)【路由器、交换机】
查看>>
Android通过Socket与服务器进行通信
查看>>
你看到的都是错的!——虚拟化技术的真相
查看>>
打印机的一些高级设置
查看>>
好用的Java数学表达式计算工具——Exp4j
查看>>
浅谈ListBox在Windows Phone 7 中的使用(2)
查看>>
FreeBSD下挂载EXT2,FAT32,NTFS文件系统解决方案下挂载EXT2,FAT32,NTFS文件系统解决方案...
查看>>
拦截器实现文件过滤
查看>>
App-V 4.6 SP1系列之一安装
查看>>
FreeRADIUS 负载均衡和高可用
查看>>
ansible-playbook批量部署zabbix
查看>>
静默安装Oracle数据库10g篇
查看>>
2017软考信息系统项目管理师软考热点
查看>>
十个生成模型(GANs)的最佳案例和原理 | 代码+论文
查看>>
Json拼接字符串必须用双引号
查看>>
闭包--循序学习
查看>>
项目实战之集成邮件开发
查看>>
java泛型操作复习,以及讲解在android中使用的场景
查看>>
解决C3P0在Linux下Failed to get local InetAddress for VMID问题
查看>>
1531 山峰 【栈的应用】
查看>>