目录

第1章 Init进程的初始化总体流程

1.1 Linux根文件系统

1.2 Init机制systemD的区别

1.3.Init进程的初始化总体流程

第1步骤:init进程的位置的位置

第2步骤:利用/etc/inittab进行初始

2.1 格式

2.2 案例

第3步骤:利用/etc/rd.d/rc.sysinit进行初始化

第4步骤:利用/etc/rd.d/rc x 进行初始化

4.1 /etc/rd.d/rc.local

4.2 /etc/rd.d/rc.x

第5步骤:初始化shell终端/sbin/agetty ttyx 9600

第6步骤:图形模式与文字模式的切换方式

第7步骤:Linux 关机

结尾语


第1章 Init进程的初始化总体流程

1.1 Linux根文件系统

init进程对应的程序文件位于根文件系统中,init进程调用的脚本也位于跟文件系统中。

关于根文件系统的详细信息,请参看:

[架构之路-30]:目标系统 - 系统软件 - Linux OS根文件系统rootfs的概念、组成、制作以及用busybox制作根文件系统_文火冰糖的硅基工坊的博客-CSDN博客

1.2 Init机制systemD的区别

Linux系统的启动过程并不是大家想象中的那么复杂,其过程可以分为5个阶段:

  • 内核的引导。
  • 运行 init。
  • 系统初始化。
  • 建立终端 。
  • 用户登录系统。

init程序的类型:

  • SysV: init, CentOS 5之前, 配置文件: /etc/inittab。
  • Upstart: init,CentOS 6, 配置文件: /etc/inittab, /etc/init/*.conf。
  • Systemd: systemd, CentOS 7,配置文件: /usr/lib/systemd/system、 /etc/systemd/system。

init和systemD都是Linux提供的在用户空间初始化Linux系统、初始化应用程序进程、管理应用程序进程的机制。init先与sysmteD的机制,关于他们的区分,请参看:

[架构之路-31]:目标系统 - 系统软件 - Linux OS 什么是Linux1号进程? init进程与systemD的比较?_文火冰糖的硅基工坊的博客-CSDN博客

1.3.Init进程的初始化总体流程

进程0:内核idle进程

进程1:init进程

进程2:shell进程

进程n:其他进程。

如下的这张图,是X86 Linux的初始化流程,嵌入式Linux是该流程的简化。

本文以X86 Linxu为描述对象。

位于根文件系统的init进程,负责根据etc目录中的各种配置文件,在用户空间对Linux系统进行初始化

第1步骤:init进程的位置的位置

init 进程是系统所有进程的起点,你可以把它比拟成系统所有进程的老祖宗,没有这个进程,系统中任何进程都不会启动。

init 程序首先是需要读取配置文件 /etc/inittab。

try_to_run_init_process("/linuxrc")   => 嵌入式Linux

try_to_run_init_process("/sbin/init")

try_to_run_init_process("/etc/init")

try_to_run_init_process("/bin/init")

try_to_run_init_process("/bin/sh")

第2步骤:利用/etc/inittab进行初始

许多程序需要开机启动。它们在Windows叫做"服务"(service),在Linux就叫做"守护进程"(daemon)。

init进程的一大任务,就是去运行这些开机启动的程序。

但是,不同的场合需要启动不同的程序,比如用作服务器时,需要启动Apache,用作桌面就不需要。

Linux允许为不同的场合,分配不同的开机启动程序,这就叫做"运行级别"(runlevel)。也就是说,启动时根据"运行级别",确定要运行哪些程序。

inittab为linux初始化文件系统时init初始化程序用到的配置文件。

这个文件负责设置init初始化程序初始化脚本在哪里;每个运行级初始化时运行的命令; 开机、关机、重启对应的命令;各运行级登录时所运行的命令。

实际上,inittab定义的是:如何启动Linux的各种脚本。

2.1 格式

id:runlevels:action:process 其中某些部分可以为空

(1)id:指定指派给进程的用户标识

1~2个字符,配置行的唯一标识,在配置文件中不能重复。

(2)runlevels:指定进程运行等级

配置行适用的运行级别,在这里可填入多个运行级别,比如12345或者35等

Linux系统有7个运行级别(runlevel):

  • 运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动
  • 运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登录
  • 运行级别2:多用户状态(没有NFS)
  • 运行级别3:完全的多用户状态(有NFS),登录后进入控制台命令行模式
  • 运行级别4:系统未使用,保留
  • 运行级别5:X11控制台,登录后进入图形GUI模式
  • 运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动

备注:

所谓的运行等级,是指Linux不同的启动类型,包括关机、重启、正常单用户启动、多用户启动等。

不同的启动类型:

有些待执行的脚本在所有的情形下都需要执行。

有些待执行的脚本在不同的情形下是不相同的。如下:rc x脚本。

(4)process

指定所要执行的shell命令或进程。

(3)action:指定init进行如何管理进程

init有如下几种行为, init行为:

行为

描述

respawn

启动并监视第4项指定的process,若process终止则自动重启该进程

wait

执行第4项指定的process,并等待它执行完毕

once

执行第4项指定的process,启动后,无需等待进程的执行完毕,init进程也不会监控该进程。

boot

不论在哪个执行等级,系统重新启动时都会运行第4项指定的process。

bootwait

不论在哪个执行等级,系统启动时都会运行第4项指定的process,且一直等它执行完备

off

关闭任何动作,相当于忽略该配置行

ondemand

进入ondemand执行等级时,执行第4项指定的process

initdefault

系统启动后进入的执行等级,该行不需要指定process

sysinit

不论在哪个执行等级,系统会在执行boot 及bootwait之前执行第4项指定的process

powerwait

当系统的供电不足时执行第4项指定的 process,且一直等它执行完毕

powerokwait

当系统的供电恢复正常时执行第4项指定的process,且一直等它执行完毕

powerfailnow

当系统的供电严重不足时执行第4项指定的process

ctrlaltdel

当用户按下【Ctrl+Alt+Del】时执行的进程

kbrequest

当用户按下特殊的组合键时执行第4项指定的process,此组合键需在keymaps文件定义

2.2 案例

# Begin /etc/inittab

id:3:initdefault:                              =》默认为执行等级3,具有网络功能的多用户字符界面。

si::sysinit:/etc/rc.d/init.d/rc.sysinit              =》所有级别都执行的进程rc sysinit

l0:0:wait:/etc/rc.d/init.d/rc 0                        =》不同的启动等级,执行不同的rc x。

l1:1:wait:/etc/rc.d/init.d/rc 1              =》 当运行级别改变时,负责启动/停止各种服务。

l2:2:wait:/etc/rc.d/init.d/rc 2

l3:3:wait:/etc/rc.d/init.d/rc 3

l4:4:wait:/etc/rc.d/init.d/rc 4

l5:5:wait:/etc/rc.d/init.d/rc 5

l6:6:wait:/etc/rc.d/init.d/rc 6                        =》不同的启动等级,执行不同的rc x。

ca:12345:ctrlaltdel:/sbin/shutdown -t1 -a -r now =》当用户按下【Ctrl+Alt+Del】时执行的进程

su:S016:once:/sbin/sulogin

1:2345:respawn:/sbin/agetty tty1 9600   =》监控tty进程,若process终止则自动重启该进程

2:2345:respawn:/sbin/agetty tty2 9600

3:2345:respawn:/sbin/agetty tty3 9600

4:2345:respawn:/sbin/agetty tty4 9600

5:2345:respawn:/sbin/agetty tty5 9600

6:2345:respawn:/sbin/agetty tty6 9600

# End /etc/inittab

第3步骤:利用/etc/rd.d/rc.sysinit进行初始化

在init的配置文件中有这么一行:

si::sysinit:/etc/rc.d/rc.sysinit 

它调用执行了/etc/rc.d/rc.sysinit,而rc.sysinit是一个bash shell的脚本,它主要是完成一些系统初始化的工作,rc.sysinit是每一个运行级别都要首先运行的重要脚本。

它主要完成的工作有:激活交换分区,检查磁盘,加载硬件模块以及其它一些需要优先执行任务。

(1)主要功能

  • HOSTNAME=`/bin/hostname` # 取得主机名
  • HOSTTYPE=`uname -m` # 取得主机类型
  • unamer=`uname -r` # 取得内核的 release 版本
  • /etc/sysconfig/network # network 文件主要控制是否启用网络、默认网关、主机名
  • HOSTNAME=localhost # 则将主机名设置为 "localhost"
  • mount -n -t proc /proc /proc
  • [ -d /proc/bus/usb ] && mount -n -t usbfs /proc/bus/usb /proc/bus/usb # 如果存在 /proc/bus/usb 目录则把 /proc/bus/usb 以 usbfs 挂载到 /proc/bus/usb 下
  • mount -n -t sysfs /sys /sys >/dev/null 2>&1 # 接下来就是把 /sys 目录以 sysfs 格式挂载到 /sys 目录下
  • . /etc/init.d/functions # 执行 /etc/init.d/functions 文件,该文件提供了很多有用的函数,具体见 “functions 脚本提供的函数”一文

备注:

/proc、sysfs等RAM文件系统在此时给mount起来,就可参看内核的信息了。

(2)示例

#!/bin/bash
#
# /etc/rc.d/rc.sysinit - run once at boot time
#
#
# Rerun ourselves through initlog                                                // 通过 /sbin/initlog 命令重新运行自己
if [ -z "$IN_INITLOG" -a -x /sbin/initlog ]; then                            // 条件是 :如果 IN_INITLOG 变量的值不为空,且 /sbin/initlog 可执行exec /sbin/initlog -r /etc/rc.d/rc.sysinit                                // 调用 exec /sbin/initlog ,-r 是表示运行某个程序
fi
#############################################################################################################
HOSTNAME=`/bin/hostname`                            # 取得主机名
HOSTTYPE=`uname -m`                                    # 取得主机类型
unamer=`uname -r`                                          # 取得内核的 release 版本(例如 2.4.9.30-8)eval version=`echo $unamer | awk -F '.' '{ print "(" $1 " " $2 ")" }'`            # 取得版本号
if [ -f /etc/sysconfig/network ]; then                # 如果存在 /etc/sysconfig/network ,则执行该文件。. /etc/sysconfig/network                             # network 文件主要控制是否启用网络、默认网关、主机名
fi
if [ -z "$HOSTNAME" -o "$HOSTNAME" = "(none)" ]; then            # 如果执行 network 文件后 HOSTNAME 为空或者为 "(none)" ,HOSTNAME=localhost                                                        # 则将主机名设置为 "localhost"
fi
# Mount /proc and /sys (done here so volume labels can work with fsck)        # 接下来是挂载 /proc 和 /sys ,这样 fsck 才能使用卷标
mount -n -t proc /proc /proc                                                                      #  -n 表示不写 /etc/mtab ,这在 /etc 所在的文件系统为只读时用。因为此时的/还是只读的
[ -d /proc/bus/usb ] && mount -n -t usbfs /proc/bus/usb /proc/bus/usb        # 如果存在 /proc/bus/usb 目录则把 /proc/bus/usb 以 usbfs 挂载到 /proc/bus/usb 下
mount -n -t sysfs /sys /sys >/dev/null 2>&1                                                    # 接下来就是把 /sys 目录以 sysfs 格式挂载到 /sys 目录下
##############################################################################################################
. /etc/init.d/functions             # 执行 /etc/init.d/functions 文件,该文件提供了很多有用的函数,具体见 “functions 脚本提供的函数”一文
##############################################################################################################
# Check SELinux status
selinuxfs=`awk '/ selinuxfs / { print $2 }' /proc/mounts`
SELINUX=
if [ -n "$selinuxfs" ] && [ "`cat /proc/self/attr/current`" != "kernel" ]; then            if [ -r $selinuxfs/enforce ] ; thenSELINUX=`cat $selinuxfs/enforce`else# assume enforcing if you can't read itSELINUX=1fi
fiif [ -x /sbin/restorecon ] && LC_ALL=C fgrep -q " /dev " /proc/mounts ; then/sbin/restorecon  -R /dev 2>/dev/null
fidisable_selinux() {echo "*** Warning -- SELinux is active"echo "*** Disabling security enforcement for system recovery."echo "*** Run 'setenforce 1' to reenable."echo "0" > $selinuxfs/enforce
}relabel_selinux() {if [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; thenchvt 1fiecho "*** Warning -- SELinux relabel is required. ****** Disabling security enforcement.         ****** Relabeling could take a very long time, ****** depending on file system size.          ***"echo "0" > $selinuxfs/enforce/sbin/fixfiles -F relabel > /dev/null 2>&1 rm -f  /.autorelabel echo "*** Enabling security enforcement.         ***"echo $SELINUX > $selinuxfs/enforceif [ -x /usr/bin/rhgb-client ] && /usr/bin/rhgb-client --ping ; thenchvt 8fi
}

第4步骤:利用/etc/rd.d/rc x 进行初始化

4.1 /etc/rd.d/rc.local

(1) 主要功能

  • 启动根文件系统中的httpd服务
  • 其他

(2) 示例

[root@localhost ~]# vi /etc/rc.d/rc.local#!/bin/sh#This script will be executed after all the other init scripts.
#You can put your own initialization stuff in here if you don’t
#want to do the full Sys V style init stuff.
touch /var/lock/subsys/local
#默认会touch这个文件,每次系统启动时都会touch这个文件,这个文件的修改时间就是系统的启动时间
#写入想要启动系统并运行的语句
#例1:
/etc/rc.d/init.d/httpd start
#如果写入RPM包安装的apache服务的启动命令,apache服务就会在开机时自动启动
#例2:
[ -f /usr/local/gse/proxy/bin/gsectl ] && /usr/local/gse/proxy/bin/gsectl start > /var/log/gse_start.log 2>&1
#某系统的开机自启设置

4.2 /etc/rd.d/rc.x

l5:5:wait:/etc/rc.d/rc 5

这一行表示以5为参数运行/etc/rc.d/rc

/etc/rc.d/rc是一个Shell脚本,它接受5作为参数,去执行/etc/rc.d/rc5.d/目录下的所有的rc启动脚本,/etc/rc.d/rc5.d/目录中的这些启动脚本实际上都是一些连接文件,而不是真正的rc启动脚本,真正的rc启动脚本实际上都是放在/etc/rc.d/init.d/目录下。

而这些rc启动脚本有着类似的用法,它们一般能接受start、stop、restart、status等参数。

/etc/rc.d/rc5.d/中的rc启动脚本通常是K或S开头的连接文件,对于以 S 开头的启动脚本,将以start参数来运行。

而如果发现存在相应的脚本也存在K打头的连接,而且已经处于运行态了(以/var/lock/subsys/下的文件作为标志),则将首先以stop为参数停止这些已经启动了的守护进程,然后再重新运行。

这样做是为了保证是当init改变运行级别时,所有相关的守护进程都将重启。

至于在每个运行级中将运行哪些守护进程,用户可以通过chkconfig或setup中的"System Services"来自行设定。

第5步骤:初始化shell终端/sbin/agetty ttyx 9600

一般来说,用户的登录方式有三种:

  • (1)命令行登录
  • (2)ssh登录
  • (3)图形界面登录

对于运行级别为5的图形方式用户来说,他们的登录是通过一个图形化的登录界面。登录成功后可以直接进入 KDE、Gnome 等窗口管理器。

而本小结主要讲的还是文本方式登录的情况:当我们看到mingetty的登录界面时,我们就可以输入用户名和密码来登录系统了。

Linux 的账号验证程序是 login,login 会接收 mingetty 传来的用户名作为用户名参数。

然后 login 会对用户名进行分析:如果用户名不是 root,且存在 /etc/nologin 文件,login 将输出 nologin 文件的内容,然后退出。

这通常用来系统维护时防止非root用户登录。只有/etc/securetty中登记了的终端才允许 root 用户登录,如果不存在这个文件,则 root 用户可以在任何终端上登录。

/etc/usertty文件用于对用户作出附加访问限制,如果不存在这个文件,则没有其他限制。

第6步骤:图形模式与文字模式的切换方式

Linux预设提供了六个命令窗口终端机让我们来登录。

默认我们登录的就是第一个窗口,也就是tty1,这个六个窗口分别为tty1,tty2 … tty6,你可以按下Ctrl + Alt + F1 ~ F6 来切换它们。

如果你安装了图形界面,默认情况下是进入图形界面的,此时你就可以按Ctrl + Alt + F1 ~ F6来进入其中一个命令窗口界面。

当你进入命令窗口界面后再返回图形界面只要按下Ctrl + Alt + F7 就回来了。

如果你用的vmware 虚拟机,命令窗口切换的快捷键为 Alt + Space + F1~F6. 如果你在图形界面下请按Alt + Shift + Ctrl + F1~F6 切换至命令窗口。

第7步骤:Linux 关机

在linux领域内大多用在服务器上,很少遇到关机的操作。毕竟服务器上跑一个服务是永无止境的,除非特殊情况下,不得已才会关机。

正确的关机流程为:sync > shutdown > reboot > halt

关机指令为:shutdown ,你可以man shutdown 来看一下帮助文档。

例如,你可以运行如下命令关机:

sync 将数据由内存同步到硬盘中。shutdown 关机指令,你可以man shutdown 来看一下帮助文档。例如你可以运行如下命令关机:shutdown –h 10 ‘This server will shutdown after 10 mins’ 这个命令告诉大家,计算机将在10分钟后关机,并且会显示在登陆用户的当前屏幕中。shutdown –h now 立马关机shutdown –h 20:25 系统会在今天20:25关机shutdown –h +10 十分钟后关机shutdown –r now 系统立马重启shutdown –r +10 系统十分钟后重启reboot 就是重启,等同于 shutdown –r nowhalt 关闭系统,等同于shutdown –h now 和 poweroff

不管是重启系统还是关闭系统,首先要运行 sync 命令,把内存中的数据写到磁盘中。

关机的命令有 shutdown –h now halt poweroff 、 init 0 ,

重启系统的命令有 shutdown –r now 、reboot 、init 6

备注:

Linux系统有7个运行级别(runlevel):

  • 运行级别0:系统停机状态,系统默认运行级别不能设为0,否则不能正常启动
  • 运行级别1:单用户工作状态,root权限,用于系统维护,禁止远程登录
  • 运行级别2:多用户状态(没有NFS)
  • 运行级别3:完全的多用户状态(有NFS),登录后进入控制台命令行模式
  • 运行级别4:系统未使用,保留
  • 运行级别5:X11控制台,登录后进入图形GUI模式
  • 运行级别6:系统正常关闭并重启,默认运行级别不能设为6,否则不能正常启动

结尾语

init进程是Linux在用户空间启动根文件系统中程序(脚本和可执行程序)的一种机制。

(1)它离不开根文件系统这个物理载体

(2)同时它还要考虑各种适应性,以适应各种不同的场合

(3)负责启动Linux在用户空间根文件系统中的程序

(4)复杂监控和管理需要由init进程监控和管理的进程,在需要的时候,由init进程自动重启这些进程。

[架构之路-32]:目标系统 - 系统软件 - Linux OS用户空间程序的启动、关闭、监管 -- init进程相关推荐

  1. [架构之路-39]:目标系统 - 系统软件 - Linux OS内核进程/线程调度的基本原理

    目录 第1章 Linux进程概述 1.1 什么是进程 1.2 进程简单的状态迁移 1.3 进程复杂状态迁移 1.4 引起进程状态转换的具体原因如下: 1.5 进程的地址空间 1.6 用户空间如何创建进 ...

  2. [架构之路-30]:目标系统 - 系统软件 - Linux OS根文件系统rootfs的概念、组成、制作以及用busybox制作根文件系统

    目录 前言: 第1章 什么是根文件系统 1.1 什么是文件 1.2 什么是文件系统 1.3 文件系统组织文件的方式:树形结构 1.4 统一的虚拟文件系统 1.5 物理存储介质与物理文件系统类型 1.5 ...

  3. [架构之路-38]:目标系统 - 系统软件 - Linux OS硬件设备驱动必须熟悉的六大工作机制之(并发与互斥、阻塞与非阻塞、异步通知)

    目录 前言: 第4章 内核程序并发与互斥机制 4.1 内核程序优先级机制 4.2 内核线程状态:并发与竞争 4.3 内核锁的类型 4.4 乱序问题 第5章 阻塞与非阻塞机制 5.1 什么是阻塞问题 5 ...

  4. [架构之路-49]:目标系统 - 系统软件 - Linux下的网络通信-7-快速数据平面开发套件DPDK - 快速部署软件入门指南

    目录 前言: 第1章 概述 1.1 本文的英文参考 1.2 概述 1.3 DPDK常见的文档 第2章 系统需求 2.1.x86上的BIOS设置前提条件 2.2.编译DPDK的要求 2.3 运行DPDK ...

  5. Linux的用户空间与内核空间

    一. 简介 Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间.两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针 ...

  6. linux 内核空间 sy,在 Linux 下用户空间与内核空间数据交换的方式,第 1 部分: 内核启动参数、模块参数与sysf...

    级别: 初级 燚 杨 (), 计算机科学硕士 2006 年 2 月 16 日 本系列文章包括两篇,它们文详细地介绍了 Linux 系统下用户空间与内核空间数据交换的九种方式,包括内核启动参数.模块参数 ...

  7. Linux下用户空间访问I/O端口的相关函数

    Linux下设置端口权限的系统调用有两个:ioperm和iopl函数. ioperm 功能描述 为调用进程设置I/O端口访问权限,从端口地址from起始,共设置num个值为turn_on.ioperm ...

  8. android gpu linux,Arm发布针对Mali GPU的Android Linux Vulkan用户空间驱动(HiKey 960,Firefly-RK3288主板)...

    前一段时间,CNXSoft曾为宏碁Chromebook R13撰写了Imagination的PowerVR CLDNN神经网络SDK和图像,还有一些人对Arch Linux Arm镜像进行了研究,并且 ...

  9. linux之用户空间和内核空间

    linux驱动程序一般工作在内核空间,但也可以工作在用户空间.下面我们将详细解析,什么是内核空间,什么是用户空间,以及如何判断他们. Linux简化了分段机制,使得虚拟地址与线性地址总是一致,因此,L ...

  10. [架构之路-43]:目标系统 - 系统软件 - Linux下的网络通信-3-TCP/IP协议族:IP、TCP/UDP/SCTP、Socket、应用层协议

    目录 第1章 TCP/IP协议简介 1.1 简介 1.2 协议栈 1.3 IP网络 第2章 IP协议 2.1 简介 2.2 IP功能 2.4 IP V4地址 2.5 IP V6地址 2.6 IPV4地 ...

最新文章

  1. 电子书格式怎么在线转换为PDF格式
  2. NOIP模拟题 斐波那契数列
  3. 两所顶尖大学,签约落地深圳!
  4. 在给定约束下可以使用a,b和c形成的字符串数
  5. 1,滑动验证,前后台接口
  6. python操作haproxy配置文件实例
  7. 用 Python 编写一个天气查询应用 pyqt5
  8. key rocketmq 有什么用_rocketmq 介绍(一)
  9. LinkedList的源码分析(基于jdk1.8)
  10. 《自控力》——[美]Kelly McGonigal
  11. cad怎么设置线的粗细_CAD图纸线条粗细如何修改?CAD图纸线宽如何调整?
  12. 2012系分真题案例分析 软件项目管理 工期管理
  13. html中的长度单位
  14. 如何读懂EDIFACT报文?
  15. linux程序间管道通信,linux进程间通信——管道 详解
  16. 股市理论---牛马熊
  17. 强推5款办公工具,网页版免下载,拿来即用
  18. 如何阅读Python代码?
  19. linux服务器垃圾清理,Linux下垃圾清理方法总结[转发]
  20. linux的gedit打开文件乱码,gedit中文乱码问题

热门文章

  1. 举个栗子!Tableau技巧(7):如何做帕累托图
  2. 如何在一个事件中使用(调用)另一个事件
  3. JQuery解析二维码
  4. spass modeler
  5. fanuc机器人负载设定
  6. 论文:YOLOX: Exceeding YOLO Series in 2021
  7. java中sof是什么意思_SOF是什么意思
  8. java导出繁体字word,word繁体字转换
  9. VMware安装ubantu系统
  10. antd4.x [antd: Switch] `value` is not a valid prop, do you mean `checked`? 解决办法