Linux如何启动流程?Linux启动流程详解

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux如何启动流程?Linux启动流程详解相关的知识,希望对你有一定的参考价值。

当用户打开电源后,Bios开机自检,确定启动设备,安装启动设备,启动设备上面安装的GRUB开始引导Linux,Linux首先先进行内核引导,通过跟切换,执行init程序,init程序确定启动级别,根据启动级别进行系统初始化和运行的服务,然后返回init启动终端,用户通过验证成功登陆Shell,这就是一个从开机到登陆的启动过程。

一、硬件引导启动
当用户打开电源后POST开始自检,检测硬件设备是否确实或者存在故障(是否影响正常开机),如果不影响正常开机,就把任务交给BIOS。BIOS通过搜索,安装启动确定启动设备,启动项为硬盘,BIOS去读取硬盘的前512字节到内存,找到BootLoader,确定GRUB

二、GRUB引导启动内核
这一部分概况起来就是:GRUB程序加载执行并开始引导kernel程序

Boot Loader就是在操作系统内核运行之前运行的一小段程序。通过GRUB引导可以确定内核程序,因为引导扇区只有446字节,GRUB只是一个小的程序安装在里面,真正使用的在MBR后面的扇区存放,我们想使用Bootloader GRUB功能必须读取后面的文件,Bootloader GRUB功能程序的运行和加载配置选项分为三个阶段

Stage1阶段:
Stage1阶段其实就是执行系统安装时预先写入到MBR的Bootloader中的程序。

Stage1阶段的任务仅是将硬盘0柱面0磁道2扇区的内容读入内存并执行,它是Stage1.5阶段或Stage2阶段的入口,引导进入Stage1.5阶段或Stage2阶段。 在此Stage1阶段,还没有识别文件系统的能力。

Stage1.5阶段:
stage1.5阶段是stage1阶段和stage2阶段的中间桥梁。stage1.5阶段具有识别启动分区文件系统的能力,此后GRUB程序便有能力去访问/boot分区下/grub目录下的 stage2文件,并将stage2载入内存执行。

Stage2阶段
Stage2阶段执行时,首先会解析GRUB程序的配置文件grub.conf,并依配置文件决定是否显示系统启动菜单。然后加载内核镜像到内存中,通过initrd程序建立RAMDisk内存虚拟根文件系统。此时控制权将转交给内核程序。

三、内核引导启动
这一部分主要是通过在内存中建立虚拟根文件系统实现相关设备的驱动并建立和切换到真正的根文件系统。

解压内核镜像加载到内存,以及initrd程序建立RAMDisk内存虚拟根文件系统后,内核开始驱动基本硬件,并调用虚拟根文件系统中的init程序加载驱动模块初始化系统中各种设备的相关配置工作,其中包括CPU、I/O、存储设备等。当所需的驱动程序加载完后,会根据grub.conf配置文件中“root=XXX”部分所指定的内容创建一个根设备,然后将根文件系统以只读的方式挂载,并切换到真正的根文件系统上,同时调用系统进程的/sbin/init程序,进入系统初始化阶段。

四、系统初始化
这一步是通过/sbin/init,init程序准备软件运行坏境,启动系统服务

通过/etc/inittab文件确定运行级别,然后去执行系统初始化脚本/etc/rc.sysinit,为用户初始化用户空间环境,在完成初始化后,根据运行级别,系统开始对应级别的目录启动服务,关闭那些不要的服务(里面S99local -> ../rc.local)用户自动服务启动脚本

运行级别:为系统运行或维护等目的而设定;0-6:7个级别
0:关机
1:单用户模式(root自动登录), single, 维护模式
2: 多用户模式,启动网络功能,但不会启动NFS;维护模式
3:多用户模式,正常模式;文本界面
4:预留级别;可同3级别
5:多用户模式,正常模式;图形界面
6:重启
默认级别:3, 5
切换级别:init #
查看级别:runlevel ; who -r
五、启动终端,用户登录
这一步是用户登录shell过程

如果没有改变级别,默认情况执行/sbin/mingetty打开6个纯文本终端,让用户输入用户名和密码。输入完成后,再调用login程序,核对密码。如果密码正确,就从文件 /etc/passwd 读取该用户指定的shell,然后启动这个shell。更多Linux介绍请查看《Linux就该这么学》。
参考技术A

在BIOS阶段,计算机的行为基本上被写死了,可以做的事情并不多;一般就是通电、BIOS、主引导记录、操作系统这四步。所以我们一般认为加载内核是linux启动流程的第一步。

第一步、加载内核

操作系统接管硬件以后,首先读入 /boot 目录下的内核文件。

我们查看一下,/boot 目录下面大概是这样一些文件:

  $ ls /boot      config-3.2.0-3-amd64   config-3.2.0-4-amd64   grub   initrd.img-3.2.0-3-amd64   initrd.img-3.2.0-4-amd64   System.map-3.2.0-3-amd64   System.map-3.2.0-4-amd64   vmlinuz-3.2.0-3-amd64   vmlinuz-3.2.0-4-amd64

第二步、启动初始化进程

内核文件加载以后,就开始运行第一个程序 /sbin/init,它的作用是初始化系统环境。

由于init是第一个运行的程序,它的进程编号(pid)就是1。其他所有进程都从它衍生,都是它的子进程。

第三步、确定运行级别

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

init进程的一大任务,就是去运行这些开机启动的程序。但是,不同的场合需要启动不同的程序,比如用作服务器时,需要启动Apache,用作桌面就不需要。Linux允许为不同的场合,分配不同的开机启动程序,这就叫做"运行级别"(runlevel)。也就是说,启动时根据"运行级别",确定要运行哪些程序。

Linux预置七种运行级别(0-6)。一般来说,0是关机,1是单用户模式(也就是维护模式),6是重启。运行级别2-5,各个发行版不太一样,对于Debian来说,都是同样的多用户模式(也就是正常模式)。
init进程首先读取文件 /etc/inittab,它是运行级别的设置文件。如果你打开它,可以看到第一行是这样的:

id:2:initdefault:

initdefault的值是2,表明系统启动时的运行级别为2。如果需要指定其他级别,可以手动修改这个值。

那么,运行级别2有些什么程序呢,系统怎么知道每个级别应该加载哪些程序呢?回答是每个运行级别在/etc目录下面,都有一个对应的子目录,指定要加载的程序。

/etc/rc0.d /etc/rc1.d /etc/rc2.d /etc/rc3.d /etc/rc4.d /etc/rc5.d /etc/rc6.d

上面目录名中的"rc",表示run command(运行程序),最后的d表示directory(目录)。下面让我们看看 /etc/rc2.d 目录中到底指定了哪些程序。

  $ ls /etc/rc2.d      README   S01motd   S13rpcbind   S14nfs-common   S16binfmt-support   S16rsyslog   S16sudo   S17apache2   S18acpid   ...

可以看到,除了第一个文件README以外,其他文件名都是"字母S+两位数字+程序名"的形式。字母S表示Start,也就是启动的意思(启动脚本的运行参数为start),如果这个位置是字母K,就代表Kill(关闭),即如果从其他运行级别切换过来,需要关闭的程序(启动脚本的运行参数为stop)。后面的两位数字表示处理顺序,数字越小越早处理,所以第一个启动的程序是motd,然后是rpcbing、nfs......数字相同时,则按照程序名的字母顺序启动,所以rsyslog会先于sudo启动。

这个目录里的所有文件(除了README),就是启动时要加载的程序。如果想增加或删除某些程序,不建议手动修改 /etc/rcN.d 目录,最好是用专门命令进行管理。

第四步、加载开机启动程序

前面提到,七种预设的"运行级别"各自有一个目录,存放需要开机启动的程序。不难想到,如果多个"运行级别"需要启动同一个程序,那么这个程序的启动脚本,就会在每一个目录里都有一个拷贝。这样会造成管理上的困扰:如果要修改启动脚本,岂不是每个目录都要改一遍?

Linux的解决办法,就是七个 /etc/rcN.d 目录里列出的程序,都设为链接文件,指向另外一个目录 /etc/init.d ,真正的启动脚本都统一放在这个目录中。init进程逐一加载开机启动程序,其实就是运行这个目录里的启动脚本。

下面就是链接文件真正的指向。

  $ ls -l /etc/rc2.d      README   S01motd -> ../init.d/motd   S13rpcbind -> ../init.d/rpcbind   S14nfs-common -> ../init.d/nfs-common   S16binfmt-support -> ../init.d/binfmt-support   S16rsyslog -> ../init.d/rsyslog   S16sudo -> ../init.d/sudo   S17apache2 -> ../init.d/apache2   S18acpid -> ../init.d/acpid   ...

这样做的另一个好处,就是如果你要手动关闭或重启某个进程,直接到目录 /etc/init.d 中寻找启动脚本即可。比如,我要重启Apache服务器,就运行下面的命令:

$ sudo /etc/init.d/apache2 restart

/etc/init.d 这个目录名最后一个字母d,是directory的意思,表示这是一个目录,用来与程序 /etc/init 区分。

第五步、用户登录

开机启动程序加载完毕以后,就要让用户登录了。

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

(1)命令行登录

(2)ssh登录

(3)图形界面登录

这三种情况,都有自己的方式对用户进行认证。

(1)命令行登录:init进程调用getty程序(意为get teletype),让用户输入用户名和密码。输入完成后,再调用login程序,核对密码(linux还会再多运行一个身份核对程序/etc/pam.d/login)。如果密码正确,就从文件 /etc/passwd 读取该用户指定的shell,然后启动这个shell。

(2)ssh登录:这时系统调用sshd程序(linux还会再运行/etc/pam.d/ssh ),取代getty和login,然后启动shell。

(3)图形界面登录:init进程调用显示管理器,Gnome图形界面对应的显示管理器为gdm(GNOME Display Manager),然后用户输入用户名和密码。如果密码正确,就读取/etc/gdm3/Xsession,启动用户的会话。

第六步、进入 login shell

所谓shell,简单说就是命令行界面,让用户可以直接与操作系统对话。用户登录时打开的shell,就叫做login shell。

linux默认的shell是Bash,它会读入一系列的配置文件。上一步的三种情况,在这一步的处理,也存在差异。

(1)命令行登录:首先读入 /etc/profile,这是对所有用户都有效的配置;然后依次寻找下面三个文件,这是针对当前用户的配置。

  ~/.bash_profile   ~/.bash_login   ~/.profile

需要注意的是,这三个文件只要有一个存在,就不再读入后面的文件了。比如,要是 ~/.bash_profile 存在,就不会再读入后面两个文件了。

(2)ssh登录:与第一种情况完全相同。

(3)图形界面登录:只加载 /etc/profile 和 ~/.profile。也就是说,~/.bash_profile 不管有没有,都不会运行。

第七步,打开 non-login shell

老实说,上一步完成以后,Linux的启动过程就算结束了,用户已经可以看到命令行提示符或者图形界面了。但是,为了内容的完整,必须再介绍一下这一步。

用户进入操作系统以后,常常会再手动开启一个shell。这个shell就叫做 non-login shell,意思是它不同于登录时出现的那个shell,不读取/etc/profile和.profile等配置文件。

non-login shell的重要性,不仅在于它是用户最常接触的那个shell,还在于它会读入用户自己的bash配置文件 ~/.bashrc。大多数时候,我们对于bash的定制,都是写在这个文件里面的。

你也许会问,要是不进入 non-login shell,岂不是.bashrc就不会运行了,因此bash 也就不能完成定制了?事实上,Debian已经考虑到这个问题了,请打开文件 ~/.profile,可以看到下面的代码:

  if [ -n "$BASH_VERSION" ]; then     if [ -f "$HOME/.bashrc" ]; then       . "$HOME/.bashrc"     fi   fi

上面代码先判断变量 $BASH_VERSION 是否有值,然后判断主目录下是否存在 .bashrc 文件,如果存在就运行该文件。第三行开头的那个点,是source命令的简写形式,表示运行某个文件,写成"source ~/.bashrc"也是可以的。

因此,只要运行~/.profile文件,~/.bashrc文件就会连带运行。但是上一节的第一种情况提到过,如果存在~/.bash_profile文件,那么有可能不会运行~/.profile文件。解决这个问题很简单,把下面代码写入.bash_profile就行了。

  if [ -f ~/.profile ]; then     . ~/.profile   fi

这样一来,不管是哪种情况,.bashrc都会执行,用户的设置可以放心地都写入这个文件了。

Bash的设置之所以如此繁琐,是由于历史原因造成的。早期的时候,计算机运行速度很慢,载入配置文件需要很长时间,Bash的作者只好把配置文件分成了几个部分,阶段性载入。系统的通用设置放在 /etc/profile,用户个人的、需要被所有子进程继承的设置放在.profile,不需要被继承的设置放在.bashrc。

顺便提一下,除了Linux以外, Mac OS X 使用的shell也是Bash。但是,它只加载.bash_profile,然后在.bash_profile里面调用.bashrc,而且不管是ssh登录还是在图形界面里启动shell窗口都是如此。

Linux的启动流程以及GRUB详解

 一、Linux引导和启动流程

      概述,计算机电源接通后通过BISO之后,没有问题,就会去硬盘上找到MBR(Main Boot Record 主引导记录区)位于整个硬盘的0磁道0柱面1扇区,它记录着主引导记录中包含了硬盘的一系列参数和一段引导程序,其中的硬盘引导程序的主要作用是检查分区表是否正确并且在系统硬件完成自检以后引导具有激活标志的分区上的操作系统,并将控制权交给启动程序(GRUB)。GRUB启动引导器是计算机启动过程中运行的第一个真正的软件,GRUB负责加载启动硬盘分区中的操作系统,之后就是操作系统的事情了,系统会启动第一个进程init,然后去读取initab配置文件,该文件的内容定义了系统启动时的配置信息,有了这些信息,系统就会读取相应的运行级别下的脚本命令,启动系统。如图:技术分享

下面详细介绍上图中的每个步骤:

 1.BISO自检

     计算机在接通电源之后,首先由BISO进行自检,然后依据BISO内设置的引导顺序从硬盘、软盘或CDROM中读入“引导块”。在PC中,引导LINUX的是从BISO中的0xFFFF0开始的。BISO的第一个步骤就是加电自检,对硬件进行检测。第二个步骤就是进行本地设备的枚举和初始化。给定BISO功能的不同用法之后,BISO由两部分组成:POST代码和运行时服务。 当POST完成之后,它从内存中清理出来,但是BISO服务保留在内存中,目标操作系统可以使用这些服务。要引导一个操作系统,BISO运行时会按照CMOS设置的顺序来搜索处于活动状态并且可以引导的设备。引导的设备可以使软盘、CD-ROM、硬盘上的某个分区、网络上的某个设备、甚至是USB闪存。通常情况下,Linux是从硬盘上引导的,其中主引导记录(MBR)中包含主引导加载程序。当MBR被加载到内存中,BISO就会将控制权交给MBR。

 2.MBR

     MBR在之前的硬盘分区时有讲过其功能,MBR(Master Boot Recorder),我们称之为主引导记录。BIOS是怎样寻找可启动设备的呢?我们知道在分区时,硬盘的第一块扇区512个字节就是存放的MBR,如果该设备是可启动设备,那么该扇区的最后两个字节肯定是55/AA,所以此时在寻找可启动设备时,如果发现该设备的最后两个字节是这个,那么该设备就是可启动设备。BIOS在找到可启动设备以后就会执行其引导代码,因为MBR占据了第一块扇区的512字节,分区表占用了 16*4 =64字节,再加上最后两个标志字节,所以MBR的引导代码就是MBR的前446个字节,当然这446个字节太小了,并不能完成整个操作系统的引导程序,所以这446个字节里面可能存放的就是启动引导程序的一些代码。

 3.启动GRUB

     GRUB是引导加载程序,将引导操作系统,当机器引导它的操作系统时,BISO就会读取引导介质上最前面的扇区,即MBR。多说一点:这里的扇区中:MBR只占用了其中的446个字节,另外的64个字节交给了DPT(Disk Partition Table硬盘分区表),最后两个字节“55,AA”是分区的结束标志。下文有专门讲解GRUB。

4.加载内核

      当内核映像被加载到内存之后,内核阶段就开始了。内核映像不是一个可执行的内核,是一个压缩过的内核映像。通常是一个zImage(压缩映像,小于512)或bzImage(大压缩映像,大于512) ,它是提起使用zIlb进行压缩的。在这个内核映像前面是一个例程,它实现少量硬件设置,并对映像中包含的内核进行解压,然后将其放入高端的内存中,如果有出事换RAM磁盘映像,就会将她移动到内存中,并标明以后使用。然后该例程会调用内核,并开始启动内核引导的过程。

在GRUB命令行中,可以使用initrd映像引导一个特定的内核 

gurb> kernel /bzImage-2.6.14.2

输出: [Linux-bzImage,setup=0x1400,size=0x29672e]
gurb> initrd /initrd-2.6.14.2.img
输出:  [Linux-initrd @ 0x5f13000, 0xcc199 bytes]
grub> boot  
输出:Uncompressing Linux ... Ok ,booting the kernel 

如果你不知道引导的内核名称,只需要使用斜线(/),然后按下“Tab”键即可。GURB会显示内核和initrd映像列表。Linux系统的内核都是存放在/boot目录下:

例如,在boot目录下执行命令  

ls -l vmlinuz-2.6.32-358.el6.x86_64 

 便会输出内核信息:

 -rwxr-xr-x. 1 root root 4043888 Feb 22 08:56 vmlinuz-2.6.32-358.el6.x86_64

操作系统在加载内核时的时候通常还会去加载内核模块打包文件:/boot/initramfs-2.6.32-358.el6.x86_64.img ;我们在系统启动完后通过 dmesg 命令可以查看本次启动时操作系统的内核输出信息,这样可以操作系统内核出现问题时对其进行错误排查:

[[email protected] boot]# dmesg
Initializing cgroup subsys cpuset
Initializing cgroup subsys cpu
Linux version 2.6.32-358.el6.x86_64 ([email protected]) (gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC) ) #1 SMP Fri Feb 22 00:31:26 UTC 2013
Command line: ro root=UUID=6e24ec7a-2d19-466e-bacc-92750b1f4bef rd_NO_LUKS rd_NO_LVM LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet
KERNEL supported cpus:
  Intel GenuineIntel
  AMD AuthenticAMD
  Centaur CentaurHauls
BIOS-provided physical RAM map:
 BIOS-e820: 0000000000000000 - 000000000009fc00 (usable)
 BIOS-e820: 000000000009fc00 - 00000000000a0000 (reserved)
 BIOS-e820: 00000000000f0000 - 0000000000100000 (reserved)
 BIOS-e820: 0000000000100000 - 00000000207f0000 (usable)
 BIOS-e820: 00000000207f0000 - 0000000020800000 (ACPI data)
 BIOS-e820: 00000000fffc0000 - 0000000100000000 (reserved)
DMI 2.5 present.
SMBIOS version 2.5 @ 0xFFF60
DMI: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
e820 update range: 0000000000000000 - 0000000000001000 (usable) ==> (reserved)
e820 remove range: 00000000000a0000 - 0000000000100000 (usable)
last_pfn = 0x207f0 max_arch_pfn = 0x400000000
MTRR default type: uncachable
MTRR variable ranges disabled:
x86 PAT enabled: cpu 0, old 0x7040600070406, new 0x7010600070106
CPU MTRRs all blank - virtualized system.

我们看到其输出了非常多的信息,都是操作系统启动时,内核的输出信息。当然我们可以在 /var/log 目录下发现也有一个 dmesg 文件,这个文件存放的内容和通过 dmesg 命令输出的内容是一模一样的

[[email protected] ~]# ls -l /var/log/dmesg
-rw-r--r--. 1 root root 21190 May 19 13:06 /var/log/dmesg

5.init

   init进程是系统所有进程的起点,内核在完成核内引导以后,即在本线程空间内加载init程序,它的进程号是1。我们可以通过 ps -aux | more 命令来看一下   

[[email protected] ~]# ps -aux | more
Warning: bad syntax, perhaps a bogus -? See /usr/share/doc/procps-3.2.8/FAQ
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.2  19348  1464 ?        Ss   13:05   0:01 /sbin/init

我们看到操作系统运行的第一个进程就是 init 进程,这个进程在启动以后就会一直运行,直到系统退出关机。

   init是所有进程的发起者和控制者,因为在任何基于UNIX的系统中,它都是第一个运行的进程,所以init进程的编号PID永远是1.如果init出现了问题,系统的其余部分也就随之不可用。init进程有以下两个作用:

  1/ 是扮演终结父进程的角色。因为init进程永远不会被终止,所以系统总是可以确信它的存在,并在必要的时候以它为参照。如果某个进程在它衍生出来的全部子进程结束之前被终止,就会出现必须以init为参照的情况。此时那些失去了父进程的子进程就都会以init作为它们的父进程。

  2/ 是在进入某个特定的运行级别时运行相应的程序,以此对各种运行级别进行管理。它的这个作用是由/etc/inittab文件定义的。

  我们通常将运行级别设置成3或者5,运行级别3和5的唯一不同,就是是否启动时拥有图形界面。在生产环境下我们通常将其设置成3,直接进入到命令行终端模式,我们可以通过修改 /etc/inittab 这个文件来修改系统默认的运行级别:

[[email protected] ~]# cat /etc/inittab
# inittab is only used by upstart for the default runlevel.
#
# ADDING OTHER CONFIGURATION HERE WILL HAVE NO EFFECT ON YOUR SYSTEM.
#
# System initialization is started by /etc/init/rcS.conf
#
# Individual runlevels are started by /etc/init/rc.conf
#
# Ctrl-Alt-Delete is handled by /etc/init/control-alt-delete.conf
#
# Terminal gettys are handled by /etc/init/tty.conf and /etc/init/serial.conf,
# with configuration in /etc/sysconfig/init.
#
# For information on how to write upstart event handlers, or how
# upstart works, see init(5), init(8), and initctl(8).
#
# Default runlevel. The runlevels used are:
#   0 - halt (Do NOT set initdefault to this)
#   1 - Single user mode
#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)
#   3 - Full multiuser mode
#   4 - unused
#   5 - X11
#   6 - reboot (Do NOT set initdefault to this)
# 
id:5:initdefault:

 /inittab 文件详解 文件格式:id:run-levels:action:process,共包含4项,用冒号分隔

id  标识符,一般为两位字母或数字,该标识符唯一,在配置文件中不能重复。

run-level    指定系统运行级,即执行登记项的init级别。用于指定相应的登记项适用于哪一个运行级,即在哪一个运行级中被处理。如果该字段为空,那么相应的登记项将适用于所有的运行级。在该字段中,可以同时指定一个或多个运行级,其中各运行级分别以数字0 1 2 3 4 5 6或字母a、b、c 表示,且无需对其进行分隔。

Linux有7个运行级,如下:

0-halt 关机,让init关闭所有进程并关机

1-Single user mode 单用户字符界面,通常又称为s或S

2-Multiuser,without NFS 不具备网络文件系统功能的多用户字符界面

3-Full multiuser mode 具备网络文件系统功能的多用户字符界面

4-unused 保留不用

5-X11 具备网络功能的图形用户界面

6-reboot 关闭所有运行的进程并重新启动系统

除此之外还有ABC三个运行级别,但在Linux都没有意义。

action
指定运行动作,用于指定init(M)命令或进程对相应进程(在“process”字段定义)所实施的动作,有以下几种:

行为 描述
respawn
 一旦第4项指定的process命令中止,便重新运行该命令。
wait
执行第4项指定的process,并等其结束后再运行其它命令。
once
执行第4项指定的process,不等待它执行完成,继续运行其它命令。
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。
powerfail
当出现电源错误时执行第4项指定的process命令,不等待其结束。
ctrlaltdel
当用户按下【Ctrl+Alt+Del】时执行第4项指定的 process。
kbrequest
当用户按下特殊的组合键时执行第4项指定的process,此组合键需在keymaps文件定义。

 


 process  指定要运行的Shell脚本/命令。

 其实在/etc目录下还有一个init目录,里面存放的是init的其它一些配置文件

[[email protected] ~]# cd /etc/init
[[email protected] init]# ll
total 68
-rw-r--r--. 1 root root  260 Jan  9 19:13 control-alt-delete.conf
-rw-r--r--. 1 root root  130 Jun 22  2012 init-system-dbus.conf
-rw-r--r--. 1 root root  316 Jan  9 19:13 kexec-disable.conf
-rw-r--r--. 1 root root  409 Jan  9 19:13 plymouth-shutdown.conf
-rw-r--r--. 1 root root  217 Jan  9 19:13 prefdm.conf
-rw-r--r--. 1 root root  358 Jan  9 19:13 quit-plymouth.conf
-rw-r--r--. 1 root root  281 Jan  9 19:13 rc.conf
-rw-r--r--. 1 root root  909 Jan  9 19:13 rcS.conf
-rw-r--r--. 1 root root  283 Jan  9 19:13 rcS-emergency.conf
-rw-r--r--. 1 root root  580 Jan  9 19:13 rcS-sulogin.conf
-rw-r--r--. 1 root root 2915 Aug 23  2010 readahead-collector.conf
-rw-r--r--. 1 root root 1559 Aug 23  2010 readahead.conf
-rw-r--r--. 1 root root  726 Aug 23  2010 readahead-disable-services.conf
-rw-r--r--. 1 root root 1162 Jan  9 19:13 serial.conf
-rw-r--r--. 1 root root  643 Jan  9 19:13 splash-manager.conf
-rw-r--r--. 1 root root  329 Jan  9 19:13 start-ttys.conf
-rw-r--r--. 1 root root  198 Jan  9 19:13 tty.conf

我们可以看到,这里面有许多的配置文件,我们可以根据自己的需要修改其里面的内容,这样init进程启动时就会去执行里面的功能。

我们通过 runlevel 命令可以查看我们当前的以及上一次的启动级别:

[[email protected] init]# runlevel
N 5

N表示没有上一个启动级别,5表示当前的启动级别.

通过init命令我们可以修改当前的系统运行级别,例如输入  init 3,此时操作系统就会进入到命令行模式技术分享

通过statx命令  或者init 5 命令就可以回到运行级别5的模式;

每个运行级别启动时的对应启动服务都是保存在了 /etc/rc.d/rc[0123456].d中,例如我们当前的运行级别是5,则操作系统的启动服务就是在 /etc/rc.d/rc5.d这个目录下,里面都是运行级别5所需启动的服务。

[[email protected] rc.d]# ls
init.d  rc0.d  rc2.d  rc4.d  rc6.d     rc.sysinit
rc      rc1.d  rc3.d  rc5.d  rc.local

本段内容摘自并修改了xiaoluo501395377Linux学习之CentOS(二十一)--Linux系统启动详解,十分感谢!!!  

6.inittab配置文件

     通过/etc/inittab文件进行初始化,Init的工作是根据/etc/inittab来执行相应的脚本,进行系统初始化,如设置键盘、字体、装载模块,设置网络等。

   6.1  /etc/rc.d/rc.sysinit  在init的配置文件中有如下一行:

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

       rc.sysinit是由init执行的第一个脚本,它主要完成一些系统初始化的工作。rc.sysinit是每一个运行级别都要首先运行的重要脚本,它主要完成的工作有:激活交换分区、检查磁盘、加载硬件模块以及其他一些需要优先执行的任务。/etc/rc.d/ rc.sysinit主要完成各个运行模式中相同的初始化工作。包括:设置初始的$PATH变量;配置网络;为虚拟内存启动交换;调协系统的主机名;检查root文件系统,以进行必要的修复;检查root文件系统的配额;为root文件系统打开用户和组的配额;以读/写的方式重新装载root文件系统;清除被装载的文件系统表/etc/mtab;把root文件系统输入到mtab;使系统为装入模块做准备;查找模块的相关文件;检查文件系统,以进行必要的修复;加载所有其他文件系统;清除/etc/mtab、/etc/fastboot和/etc/nologin;删除UUCP和lock文件;删除过时的子系统文件;删除过时的pid文件;设置系统时钟;激活交换分区;初始化串行端口;装入模块

  6.2  /etc/rc.d/rcX.d/[KS]

       在rc.sysinit执行后,将返回init,继续执行/etc/rc.d/rc程序。以运行级别5为例,init将执行配置文件inittab中的以下内容:

15: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启动脚本有着类似的用法,它们一般能接受stat、stop、restart、status等参数。/etc/rc.d/rc5.d中的rc启动脚本通常是以K或S开头的链接文件,以S开头的启动脚本将以start参数来运行。如果发现相应的脚本也存在K打头的链接,而且已经处于运行状态了(以/var/lock/subsys下的文件作为标志),则将首先以stop为参数停止这些已经启动了的守护进程,然后再重新运行。这样做是为了保证当init改变运行级别时,所有相关的守护进程都将重启。至于在每个运行级中将运行哪些守护进程,用户可以通过chkconfig来自行设定。

常见的守护进程如下:

amd:自动安装NFS守护进程。

apmd:高级电源管理守护进程。

arpwatch:记录日志并构建一个在LAN接口上看到的以太网地址和IP地址对应的数据库。

outofs:自动安装管理进程automount,与NFS相关,依赖于NIS。

crond:Linux系统下计划任务的守护进程。

named:DNS服务器。

netfs:安装NFS、Samba和Netware网络文件系统。

network:激活已配置网络接口的脚本程序。

nfs:打开NFS服务。

portmap:RPCportmap管理器,它管理基于RPC服务的连接。

sendmail:邮件服务器sendmail。

smb:Samba文件共享/打印服务。

syslog:一个让系统引导时启动syslog和klogd系统日志守候进程的脚本。

xfs:X Window字型服务器,为本地和远程X服务器提供字型集。

Xinetd:支持多种网络服务的核心守护进程,可以管理wuftp、sshd、telnet等服务。

 这些守护进程启动完毕,rc程序也就执行完了,然后又返回init继续下一步。

  6.3 执行/etc/ec.d/rc.local

     RHEL 4中的运行模式2、3、5都把/etc/rc.d/rc.local做为初始化脚本中的最后一个,所以用户可以自己在这个文件中添加一些需要在其他初始化工作之后、登录之前执行的命令。在维护Linux系统时一般会遇到需要系统管理员对开机或关机命令脚本进行修改的情况。如果所做的修改只在引导开机的时候起作用,并且改动不大的话,可以考虑简单地编辑一下/etc/rc.d/rc.local脚本。这个命令脚本程序是在引导过程的最后一步被执行的。

 7.执行/bin/login程序

   login程序会提示使用者输入账号及密码,接着编码并确认密码的正确性,如果账号与密码相符,则为使用者初始化环境,并将控制权交给shell,即等待用户登录。login会接收mingetty传来的用户名作为用户名参数,然后login会对用户名进行分析。如果用户名不是root,且存在/etc/nologin文件,login将输出nologin文件的内容,然后退出。这通常用来在系统维护时防止非root用户登录。只有在/etc/securetty中登记了的终端才允许root用户登录,如果不存在这个文件,则root可以在任何终端上登录。/etc/usertty文件用于对用户作出附加访问限制,如果不存在这个文件,则没有其他限制。在分析完用户名后,login将搜索/etc/passwd以及/etc/shadow来验证密码以及设置账户的其他信息,比如:主目录什么、使用何种shell。如果没有指定主目录,则将主目录默认设置为根目录;如果没有指定shell,则将shell类型默认设置为/bin/bash。

    Login程序成功后,会向对应的终端再输出最近一次登录的信息(在/var/log/lostlog中有记录),并检查用户是否有新邮件(在/usr/spool/mail的对应用户名目录下),然后开始设置各种环境变量。对于bash来说,系统首先寻找/etc/profile脚本文件并执行它;然后如果用户的主目录中存在.bash_profile文件,就执行它,在这些文件中又可能调用了其他配置文件,所有的配置文件执行后,各种环境变量也设好了,这时会出现大家熟悉的命令行提示符,至此整个启动过程就结束了。


  休息一下……明天再看


 

 二、Linux的GRUB详解

   1.GRUB简介

    现在 GRand Unified Boot loader 已经取代LILO在引导加载程序方面的统治地位,GNU GRUB基于原来的GRUB程序,正在有自由软件基金会进行积极的开发;GRUB不仅可以对各种发行的版本Linux进行引导,也能够正常引导PC上其他常见的操作系统。启动引导器是计算机启动过程中运行的第一个真正的软件,计算机启动时在通过BISO自检后读取并运行硬盘主引导扇(MBR)中的启动引导器程序,启动引导器在负责加载启动硬盘分区中的操作系统。如果启动引导器不能正常工作,将导致操作系统不能正常启动,从而整个计算机瘫痪。通常,每个操作系统在安装过程中都要将自带的启动器写在硬盘(MBR),以便能过进行自身的引导。

  2.GRUB引导系统

   两种方式:

  1,直接引导方式
   GRUB同时支持linux,openbsd,freebsd,netbsd等系统
   通常步骤如下:
  (1)通过‘root‘指令来设置GRUB的主设备指向操作系统映像文件所存储的地方
  (2)通过‘kernel‘命令来载入该操作系统的核心映像.如需参数,在后面添加
  (3)如果需要模块,通过‘module‘命令来加载模块
  (4)运行命令‘boot‘启动系统
  2,链式引导方式
   如果你要启动一个不被GRUB直接支持的操作系统(例如:xp),可以通过链式引导启动一个操作系统.将
   开机的指针直接指向装有该操作系统分区的bootsector(即该分区的第一扇区),使其激活.
   主要步骤如下:
  (1)通过‘rootnoverify‘命令设置GRUB的主设备指向一个扇区(同‘root‘区别是不挂入分区)
  (2)通过‘makeactive‘命令来设置在扇区上的‘active’标志位
  (3)通过‘chainloader‘ 命令来加载引导程序.‘+1‘表明GRUB需要从起始分区读一个扇区
  (4)运行命令‘boot‘启动系统  

  3.GURB的界面

   启动菜单界面:当你正确安装Linux之后,就可以从硬盘引导系统进入GRUB;

   菜单编辑界面:“e”进入该界面;

   GURB的命令行方式:有两种方法进入命令行界面;

   一种是从GURB启动菜单进入命令行界面,

   另一种从shell状态下使用grub命令进入命令行界面(有限制);

   4.GURB的配置文件gurb.conf

     默认的配置文件“boot/gurb/gurb.conf”,在GURB成功安装到硬盘主引导扇区(MBR)后,只要编辑该文件就可以实现对GRUB的配置,不需要重新写GRUB到MBR。为了保持与其他系统的兼容性和文件的一致性,系统分别在“boot/gurb”和“/etc“两个目录中建立了名为gurb.conf的符号链接文件,指向真正的配置文件”/boot/gurb/menu.lst“。首先来看一下/boot/grub/menu.lst中的内容:

# grub.conf generated by anaconda
#
# Note that you do not have to rerun grub after making changes to this file
# NOTICE: You do not have a /boot partition. This means that
#          all kernel and initrd paths are relative to /, eg.
#          root (hd0,0)
#          kernel /boot/vmlinuz-version ro root=/dev/hda1
#          initrd /boot/initrd-version.img
#boot=/dev/hda
default=0
timeout=5
splashimage=(hd0,0)/boot/grub/splash.xpm.gz
hiddenmenu
title Fedora Core (2.6.18-1.2798.fc6)
       root (hd0,0)
       kernel /boot/vmlinuz-2.6.18-1.2798.fc6 ro root=LABEL=/ rhgb quiet
selinux=0
       initrd /boot/initrd-2.6.18-1.2798.fc6.img
title Windows XP
rootnoverify (hd0,3)
chainloader +1

default 0:grub的默认启动项

timeout 5: 指定一个超时值,单位为秒,若用户在grub等待的超时时间范围内没有任何操作,则启动默认项

hidemenu: 开机时是否显示多选项菜单,若被设置则启动的时候默认不显示选项菜单,否则grub启动时自动显示选项菜单

color white/blue: 指定grub菜单的默认颜色

password --md5 $1$etSG6$LlxT8irAfAv5vYQn6tZUw1: 指定一个密码,启用grub的密码保护,这个命令需要放置在title下第一行。为安全起见,一般使用md5值,这个值可以使用grub-md5-crypt或者在grub shell中使用md5crypt生成,也可以直接使用字母或者数字。当要修改加密的启动项时,需要按p键,然后输入密码。需要注意的是为了放置点击e,进入编辑模式,然后删除密码字段,再按下b启动系统,这时可以将密码设置设置在整体上,而不是放置在某一个title下,相对应的title下增加一行lock <==多了死锁的功能

产生MD5密码命令示例如:

#grub-md5-crypt

Password: <==输入密码

Retype password: <==再输入一次

$1$kvlI0/$byrbNgkt/.REKPQdfg287. <==这就是产生的md5 密码!

root:根文件系统的位置。

ro:可读写,当启动分区是JFS等格式时需要使用此参数使得系统可以在启动是存放日志。

quiet:安静模式,不显示核心检测的信息。

splash:显示徽标。

locale:指定locale

vga:指定终端的显示模式。

chainloader +1 :告诉GRUB使用一个链式加载程序来加载这个OS,加载Windows时需要这个选项。

  5.GURB的初始引导过程

    1/ 明确三个阶段:

    Stage1

 这是一个基本必须的用来启动GRUB的映像文件.通常,这个文件是被装载到MBR或者启动扇区所在的分区.由于PC的启动扇区的大小为512字节,所以这个映像文件编译以后也必须为512字节.Stage1的全部的工作是从本地磁盘把Stage 2或者Stage 1.5装载进来.由于对stage1大小的限制,它通过分程序表的形式来编码Stage 2或者Stage 1.5的位置,所以在stage1是不能识别任何文件系统.

    Stage2

这是GRUB的核心映像.它几乎做了除启动它本身以外的所有事情.通常,它被存放为某一种文件系统     下,但并非是必须的.

   Stage1.5

做为stage1与stage2之间的桥梁,也就是说,stage1载入stage1.5,然后stage1.5载入stage2;stage1与stage1.5之间的区别是,前者是不识别任何文件系统的但后者识别文件系统(例如
e2fs_stage1_5识别ext2fs).所以你可以安全的移动stage2位置,即使是GRUB安装完以后.

注: 在我的系统中.stage1被安装到了mbr,也就是硬盘第一扇区,而stage1.5被安装到了mbr以后的扇区,根据大小完全复制进去,并且stage1.5的类型为/boot分区的文件系统类型
   

     2/ GRUB引导操作系统的简要流程

    (1)BIOS 执行INT 0x19,载MBR至0x7c00并跳转执行如果你安装GRUB到MBR,GRUB的安装程序会把 Stage1(512B)拷贝到MBR.视Stage2的大小,安装程序会在Stage1中嵌入Stage1_5或者Stage2的磁盘位置信息.
    (2)Stage1开始执行,它在进行直接加载Stage1_5或者Stage2并跳转执行.不论是哪种情况,这一步的结果都是Stage2开始运行.
    (3)Stage2这个小型的操作系统终于开始正式运行了!它会把系统切入保护模式,设置好C运行环境(主要是BSS).他会先找config文件(就是我们的menulist),如果没有的话就执行一个Shell,等待我们输入命令.然后Grub的工作就是输入命令-解析命令-执行命令的循环,当然Stage2本身是为加载其他操作系统而存在的,所以如果情况允许,在他执行Boot命令以后就会把控制权转交出去.

    与LILO类似,GRUB在初始加载时,从MBR加载第一阶段程序,加载后。它进入第一阶段和第二阶段引导加载程序之间的中间阶段。之所以存在中间阶段是为了能够对/boot/gurb中的GRUB配置文件进行常规的文件系统访问,而不是访问磁盘块。然后进入引导加载程序的第二阶段,GRUB加载gurb.conf文件。现在应该能够看到GRUB的图形界面;
     在GRUB图形界面中,按下任何键都会停止超时的计时。然后按下"P"键,可以输入GRUB密码,并获得对GRUB交互引导选项的完全访问权限。按下以下任何一个键,应该能够使用三个选项之中的一个:

     * 要在引导之前编辑命令,请按下"E"键。这将让用户能够为当前选中的OS编辑具体的选项。GRUB会显示出与那个OS的引导相关的选项,然后可以恰当地进行编辑。当为root文件系统指定了错误的HDD时,这尤其有用。如果需要单用户模式访问机器(不需要指定密码就能够让用户获得root访问权限),那么在GRUB主屏幕上选择LINUX OS。然后与前面一样,按下"E"键 ,并移到内核那一行。然后在那一行最后添加single,并按下"B"键来使用修改过的gurb.conf进行引导。在编辑模式下所做的任何修改都不会保存到gurb.conf文件中。

     *  要修改内核参数,请按下"A"键。如果你是一位经验丰富的Linux用户,可以根据需要调整内核参数。

     *  要获得类似于BASH的命令行界面,请按下"C"键。这个小型的命令行界面允许你在系统中查找GRUB配置文件,加载另外的配置文件,编辑配置文件中的行,以及直接输入GRUB命令。如果配置的变化(比如删除了某个分区)让系统无法引导,那么可能会用到这个界面。如果需要将系统引导为但用户模式,或者要让运行级别为3而不是普通的运行级别,也可能会用到它。
   

  6、GRUB命令参考     

一、菜单命令

菜单命令只能用于grub配置文件的全局配置部分,不能用在grub命令行交互界面,菜单命令在配置文件中应放在其它命令之前。

1default //设置默认启动的菜单项        2、fallback //设置启动某菜单项失败后反回的菜单项

3、hiddenmenu //隐藏菜单界面             4、timeout //设置菜单自动启动的延时时间        5、title //开始一个菜单项

二、常规命令

常规命令可以应该于配置文件和grub命令行交互界面,可使用的常规命令有

1、bootp //通过bootp初始化网络设备     2、color //设置菜单界面的颜色         3、device //指定设备文件作为驱动器

4、dhcp //通过DHCP初始化网络设备       5、hide //隐藏某分区                  6、ifconfig //手工配置网络设备

7、pager //改变内部页程序的状态        8、partnew //新建一个主分区           9、parttype //改变分区的类型

10、password 为菜单界面设置口令        11、rarp //通过RARP初始化网络设置     12、serial //设置串口设备

13、setkey //设置键盘映射              14、splashimage //设置GRUB启动时的背景图片文件    

15、termainal //选择终端类型           16、tftpserver //指定TFTP服务器       17、unhide //还原某隐藏分区

三、命令行和菜单项命令

命令行和菜单项命令可应该于GRUB配置文件的菜单项设置中,也可以用在GRUB命令交互界面。

1、bolcklist //显示某文件所在分区位置(block list notation)       2、boot //启动操作系统

3、cat //显示文件内容                         4、chainloader //把启动控制权软交给另外的启动引导器

5、cmp //比较两个文件                         6、configfile //加载已存在的GRUB配置文件

7、debug //设置为debug模式                    8、displayapm //显示APM BIOS信息

9、displaymem //显示内存配置                  10、embed //嵌入Stage 1.5文件

11、find //查找包括某文件的所有设备           12、fstest //测试文件系统

13、geometry //显示某驱动器的物理信息         14、halt //停止计算机运行(软件关机)

15、help //显示GRUB的命令帮助信息             16、impsprobe //查询对称多处理器(SMP)的信息

17、initrd //加载initrd文件                   18、install //安装GRUB

19、ioprobe //查询某驱动器的输入输出(I/O)端口           20、kernel //引导操作系统内核

21lock //锁定某GRUB导菜单项,使其输入密码后才可启动     22、makeactive //激活某主分区

23、map //虚拟映射某驱动器                    24、md5crypt //使用MD5加密口令

25、module //加载模块                         26、modulenounzip //加载模块不进行解压

27、pause //暂停并等待按键                    28、quit //退出GRUB

29、reboot //重新启动计算机                   30、read //读取内存中的内容

31、root //设置GRUB的root设备                 32、rootnoverify //设备GRUB的root设备但不装载文件系统

33、savedefault //保存当前的启动菜单项为默认启动      34、setup //自动安装GRUB

35、testload //从文件系统中测试读取某文件             36、testvbe //测试VESA BIOS EXTENSION

37、uppermem //强制设置主机上位内存的大小             38、vbeprobe //查询VESA BIOS EXTENSION信息

 

























以上是关于Linux如何启动流程?Linux启动流程详解的主要内容,如果未能解决你的问题,请参考以下文章

Linux启动流程详解

一点一滴,成材之基!Linux系统启动流程详解

24Linux启动流程和grub详解

Linux启动流程详解转载

Linux启动流程详解

Linux系统移植:U-Boot 启动流程(下)