linux系统的启动流程

标签:linux 启动过程 grub bootloader MBR

原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://chrinux.blog.51cto.com/6466723/1192004

一、linux系统的启动流程

关于linux系统的启动流程我们可以按步进行划分为如下:

POST加电自检-->BIOS(Boot Sequence)-->加载对应引导上的MBR(bootloader)-->主引导设置加载其BootLoader-->Kernel初始化-->initrd—>/etc/init进程加载/etc/inittab,其进程流程图如下:

图像 148

二、剖析详细启动过程

⑴、

POST开机自检:电脑主机打开电源的时候,随后会听到滴的一声,系统启动开始了开机自检(POST-power on self test)自检开始),这个过程中主要是检测计算机硬件设备比如:CPU,内存,主板,显卡,CMOS等设备是否有故障存在,如果有硬件故障的话将按两种情况理:对于严重故障(致命性故障)则停机,此时由于各种初始化操作还没完成,不能给出任何提示或信号;对于非严重故障则给出提示或声音报警信号,等待用户处理),如果没有故障,POST完整自己的接力任务,将尾部工作交接给BIOS处理。

⑵、

BIOS:计算机加电自检完成后第一个读取的地方就是就是BIOS(Basic Input Output System,基础输入输出系统),BIOS里面记录了主机板的芯片集与相关设置,如CPU与接口设备的通信频率、启动设备的搜索顺序、硬盘的大小与类型、系统时间、外部总线、各种接口设备的I/O地址、已经与CPU通信的IRQ中断信息,所以,启动如果要顺利启动,首先要读取BIOS设置。

⑶、

按照BIOS所设定的系统启动流程,如果检测通过,则根据引导次序(Boot Sequence)开始在第一台设备上支持启动程序,我们的启动设备主要包括硬盘、USB、SD等,我们一般用的是硬盘,然后进行读取第一个设备就是硬盘,第一个要读去的就是该硬盘的主引导记录MBR(Master Boot Record),然后系统可以根据启动区安装的引导加载程序(Boot Loader)开始执行核心识别的工作。【在此插一句:MBR程序只是找到只是硬盘分区内最前面的446个字节的Boot Loader】然后查找相关配置和定义。

⑷、

Boot Loader 加载Grub程序       在这个过程中主要靠Grub的引导开始的,Grub分为连个阶段:        stage1:主要是Boot loader        stage 1.5:过渡       stage2:主要是/boot/grub

图像 149

通过上面我们可以发现linux的内核VMLnuz,grub、initrd都在/boot目录下

图像 150

在/boot/grub/下面我们看到了熟悉的stage1,stage2及grub工具的配置文件 grub.conf,那么grub.conf内都定义了什么呐??

图像 151

⑸、Kernel

 

 根据Grub内的定义,grub读取完毕后就把下面的工作交个内核了。kernel主要是完成系统硬件探测及硬件驱动的初始化,并且以读写的方式挂载根文件系统(根切换),那么这里就出现了一个“先有鸡还是先有蛋的文件了”,具体是什么那?        要想访问真正的根文件系统(rootfs)的话,就必须加载根文件系统中的设备,这时根文件系统又没有挂载,要挂载根文件系统又得加载根文件系统中的驱动程序,哪怎么办呢?为了解决这个问题,这是就用到了initrd文件了。  在来说下kernel初始化所要工作的内容做下简单总结:         探测硬件->加载驱动(initrd)->挂载根文件系统->rootfs(/sbin/init)

⑹、

到此止内核空间的相关工作已经完成,内核空间的任务开始向用户空间转移,内核空间通过一个间接的initrd(微型linux)向用户空间的/sbin/init过度,所以gurb开始引导内核转向initrd。       initrd:一个虚拟的文件系统,里面有lib、bin、sbin、usr、proc、sys、var、dev、boot等一些目录,其实你会发现里面的目录有点像真的/对吧,所以我们称之为虚拟的根文件系统,作用就是将kernel和真的根文件系统建立关联关系,让kernel去initrd中加载根文件系统所需要的驱动程序,并以读写的方式挂载根文件系统,并让执行用户当中第一个进程init。

图像 152

下面我们看下init脚本内的内容:

图像 153

 

图像 154

图像 155

从上面的脚本内容我们可以看到init进程的主要工作:

 

挂载 :将initrd中的/proc, /sys  /dev 挂载到当前的主分区中的相应目录  创建目录:/dev/mapper  通过mknod完成block or character special files的创建  相关模块的挂载  创建root设备  挂载 /sysroot  最后完成根切换

⑺、init执行完毕以后会启动系统内的/etc/inittab文件,来完成系统系统的初始化工作。下面我们来介绍一下inittab这个配置文件内的详细内容

图像 156

图像 157

 

各个级别的定义:

默认运行级别

0:halt                      //关机  1: single user mode    //单用户维护模式)  2:multi user mode, without NFS  //不支持NFS功能  3: multi user mode, text mode     //字符界面  4:reserved   //系统保留  5: multi user mode, graphic mode   //图形化界面  6: reboot   //重启

/etc/inittab格式及语法(:)
 

[选项]:[runlevel]:[行为]:[命令]  行为:                     initdefault:代表默认运行级别                     sysinit:代表系统初始化操作选项                     ctrlaltdel:代表重启的相关设置                     wait:代表上一个命令执行结束后方可执行下面的操作                     respawn:代表后面字段可以无限制再生(reboot)  命令选项                 一些命令,不过通常都是脚本

 

下面说下inittab内定义的初始化脚本:rc.sysinit --/etc/rc.d/rc.sysinit

图像 158

图像 159

 

 

如上图所示:rc.sysinit脚本内定义了一些与系统初始化的定义  设定主机名  检测并挂载/etc/fstab中其他文件系统  启动swap分区  /etc/sysctl.conf设定内核参数  装载键映射-->键盘上每个键的功能  然后根据系统运行级别运行相关的服务脚本:/etc/rc.d/init.d/脚本和/etc/rc.d/rc#d

图像 161

 

rc0-rc6目录下脚本:  K*     ##只要是以K开头的文件均执行stop工作  S*     ##只要是以S开头的文件均执行start工作  0-99  (执行次序,数字越小越先被执行)  用户自定义开机启动程序(/etc/rc.d/rc.local)  可以根据自己的需求将一些执行命令或是脚本写到/etc/rc.d/rc.local里,当开机时,就可以加载啦

三、总结

系统初始化的大致内容总结如下:

 

硬件的初始化,图像界面启动的初始化(如果设置了默认启动基本)  主机RAID的设置初始化,device mapper 及相关的初始化,  检测根文件系统,以只读方式挂载  激活udev和selinux  设置内核参数 /etc/sysctl.conf  设置系统时钟  启用交换分区,设置主机名  加载键盘映射  激活RAID和LVM逻辑卷  挂载额外的文件系统 /etc/fstab  等等  最后根据mingetty程序调用login让用户登录->用户登录(完成系统启动)  在系统启动过程中主要的脚本和目录有哪些呢?我们可以概括一下  boot 目录  /grub 目录  /boot/grub/grub.conf 脚本  /boot/initrd+内核版本 文件  /initrd文件中的init文件  /initrd文件中的/proc/  /sys/    /dev/ 目录的挂载 及根的切换  /etc/inittab  脚本  /etc/rc.d/rc.sysinit  脚本  这些重要的脚本和目录,当然还有其他重要的目录和文件,脚本等暂不列举啦。由此篇我们可以详细了解linux系统的启动和初始化过程,然后我们可以根据linux系统启动的过程和所用到的命令自己动手DIY一个微型linux系统,关于“DIY微型linux系统”会再后两至三天内发表博文,到时候我们在一起探讨探讨linux系统的组成部分等更详细的相关信息!!!

 

自己总结的内容不够严谨,还望各位大虾们指正~~~


*******************************************************************************************


一.BIOS自检

计算机在接通电源之后首先由BIOS进行POST自检,然后依据BIOS内设置的引导顺序从硬盘、软盘或CDROM中读入引导块。Linux系统是人BIOS中的地址oxFFFF0处开始引导的。BIOS的第1个步骤是加电POST自检。POST的工作是对硬件进行检测。BIOS的第2个步骤是进行本地设备的枚举和初始化。BIOS由两部分组成:POST代码和运行时的服务。当POST完成之后,它被从内存中清理出来,但是BIOS运行时服务依然保留在内存中,目标操作系统可以使用这些服务。

BIOS运行时会按照CMOS的设置定义的顺序来搜索处于活动状态并且可以引导的设备。引导设备可以是软盘、CD-ROM、硬盘上的某个分区、网络上的某个设备甚至是USB闪存。通常,Linux系统都是从硬盘上引导的,其中主引导记录(MBR)中包含主引导加载程序。MBR是一个512字节大小的扇区,位于磁盘上的第一个扇区(0道0柱面1扇区)。当MBR被加载到RAM中之后,BIOS就会将控制权交给MBR。

如果要查看MBR的内容,用户需要以root用户的身份运行如下命令:

#dd if=/dev/had of=mbr.bin bs=512 count=1
读入了1+0个块
输出了1+0个块
#od �Cxa mbr.bin
… …

它从/dev/had(第一个IDE盘)上读取前512个字节的内容,并将其写入mbr.bin文件中。od命令会以十六进制和ASCII码格式打印这个二进制文件的内容。

 

二.启动GRUB/LILO

GRUB和LILO都是引导加载程序。引导加载程序用于引导操作系统启动。当机器引导它的操作系统时,BIOS会读取引导介质上最前面的512字节(主引导记录)。在单一的MBR中只能存储一个操作系统的引导记录,所以当需要多个操作系统时就会出现问题,需要更灵活的引导加载程序。

所有引导加载程序都以类似的方式工作,满足共同的目的,但LILO和GRUB之间也有很多不同之处:

LILO没有交互式命令界面,而GRUB拥有;
LILO不支持网络引导,而GRUB支持;
LILO将可以引导操作系统的信息存储在MBR中。

如果修改了LILO配置文件,必须将LILO第一阶段引导加载程序重写到MBR。相对于GRUB,这是一个更为危险的选择,因为错误配置的MBR可能会让系统无法引导。使用GRUB时,如果配置文件配置错误,则只是默认转到GRUB命令行界面。

 

三.加载内核

接下来的步骤就是加载内核映像到内存中,内核映像并不是一个可执行的内核,而是一个压缩过的内核映像。通常它是一个zImage(压缩映像,小于512KB)或是一个bzImage(较大的压缩映像,大于512KB),它是提前使用zlib压缩过的。在这个内核映像前面是一个例程,它实现少量硬件设置,并对内核映像中包含的内核进行解压缩,然后将其放入高端内存中。如果有初始RAM磁盘映像,系统就会将它移动到内存中,并标明以后使用。然后该例程会调用内核,并开始启动内核引导的过程。

 

四.执行init进程

init进程是系统所有进程的起点,内核在完成核内引导以后,即在本进程空间内加载init程序,它的进程呈是1。Init进程是所有进程的发起者和控制者。因为在任何基于Linux的系统中,它都是第一个运行的进程,所以init进程的编号(PID)永远是1。

init进程有以下两个作用。

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

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

 

伍.通过/etc/inittab文件进行初始化

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

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文件;
设置系统时钟;
激活交换分区;
初始化串行端口;
装入模块。

 

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继续下一步。

 

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

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

 

六.执行/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)