详解linux系统的启动过程及系统初始化
一、linux系统的启动流程
关于linux系统的启动流程我们可以按步进行划分为如下:
POST加电自检-->BIOS(Boot Sequence)-->加载对应引导上的MBR(bootloader)-->主引导设置加载其BootLoader-->Kernel初始化-->initrd—>/etc/init进程加载/etc/inittab,其进程流程图如下:
二、剖析详细启动过程
⑴、
-
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
通过上面我们可以发现linux的内核VMLnuz,grub、initrd都在/boot目录下
在/boot/grub/下面我们看到了熟悉的stage1,stage2及grub工具的配置文件 grub.conf,那么grub.conf内都定义了什么呐??
⑸、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。
下面我们看下init脚本内的内容:
从上面的脚本内容我们可以看到init进程的主要工作:
-
挂载 :将initrd中的/proc, /sys /dev 挂载到当前的主分区中的相应目录
-
创建目录:/dev/mapper
-
通过mknod完成block or character special files的创建
-
相关模块的挂载
-
创建root设备
-
挂载 /sysroot
-
最后完成根切换
⑺、init执行完毕以后会启动系统内的/etc/inittab文件,来完成系统系统的初始化工作。下面我们来介绍一下inittab这个配置文件内的详细内容
各个级别的定义:
默认运行级别
-
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
-
如上图所示:rc.sysinit脚本内定义了一些与系统初始化的定义
-
设定主机名
-
检测并挂载/etc/fstab中其他文件系统
-
启动swap分区
-
/etc/sysctl.conf设定内核参数
-
装载键映射-->键盘上每个键的功能
-
然后根据系统运行级别运行相关的服务脚本:/etc/rc.d/init.d/脚本和/etc/rc.d/rc#d
-
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文件中的/proc/ /sys/ /dev/ 目录的挂载 及根的切换
-
/etc/inittab 脚本
-
/etc/rc.d/rc.sysinit 脚本 等
这些重要的脚本和目录,还有其他重要的目录和文件,脚本等。由此篇我们可以详细了解linux系统的启动和初始化过程,然后我们可以根据linux系统启动的过程和所用到的命令自己动手DIY一个微型linux系统,关于“DIY微型linux系统”会再后两至三天内发表博文,到时候我们在一起探讨探讨linux系统的组成部分等更详细的相关
信息!!!
Linux系统开机启动流程介绍
一、linux系统进程启动流程图:
二、简单概括描述linux系统从开机到登陆界面的启动过程
1.开机BIOS自检
2.MBR引导
3.grub引导菜单
4.加载内核
5.启动init进程
6.读取inittab文件执行rc.sysinit、rc等脚本
7.启动mingetty进入系统登录界面
三、详细剖析linux系统启动过程
1.POST开机自检
电脑主机打开电源的时候随后会听到滴的一声响系统启动开始了开机自检POST-power on self
Test自检开始这个过程中主要是检测计算机硬件设备比如CPU内存主板显卡等设备是否有故障存在。如果有硬件故障的话将按两种情况理对于严重故障(致命性故障)则停机此时由于各种初始化操作还没完成不能给出任何提示或信号对于非严重故障则给出提示或声音报警信号等待用户处理如果没有故障POST完成自己的接力任务将尾部工作交接给BIOS处理。
2.加载BIOS并读取设置
计算机加电自检完成后第一个读取的地方就是就是BIOSBasic Input Output System基础输入输出系统BIOS里面记录了主机板的芯片集与相关设置如CPU与接口设备的通信频率、启动设备的搜索顺序、硬盘的大小与类型、系统时间、外部总线、各种接口设备的I/O地址、已经与CPU通信的IRQ中断信息所以启动如果要顺利启动首先要读取BIOS设置。
3.读取MRB:
按BIOS设定的系统启动流程检测通过则根据引导次序(Boot Sequence)开始在第一台设备上支持启动程序我们的启动设备主要包括硬盘、usb、sd等我们一般用的是硬盘然后进行读取第一个设备就是硬盘第一个要读去的就是该硬盘的主引导记录MBRMaster Boot Record然后系统可以根据启动区安装的引导加载程序Boot Loader开始执行核心识别的工作。
硬盘上第0柱面0磁道1扇区被称为MBR,也就是Master Boot Record,即主引导记录它的大小是512字节里面存放了预启动信息、分区表信息及分区标志等。分为两部分第一部分为(PRE-BOOT)引导区,占了446个字节第二部分为分区表(PARTITION PABLE),共66个字节记录硬盘的分区信息(其中前64字节是分区表信息后2个字节是分区结束的标志)。
预引导区的作用之一是找到标记为活动(ACTIVE)的分区并将活动分区的引导区读入内存。
系统找到BIOS所指定的硬盘的MBR后就会将其复制到0x7c00地址所在的物理内存中。其实被复制到物理内存的内容就是Boot Loader,而具体到Linux系统那就是grub了。
4.Boot Loader加载Grub程序。
Boot Loader就是在操作系统内核运行之前运行的一小段程序。通过这小段程序我们可以初始化硬件设备、简历内存空间的映射图从而将系统的软硬件环境带到一个合适的状态以便为最终调用操作系统内核做好一切准备。通常Boot Loader是严重地依赖于硬件实现的不同体系结构的系统存在着不同的BootLoader。
在这个过程中主要靠Grub的引导开始的Grub分为两个阶段
stage1主要是Boot loader
stage1.5:过渡
stage2:主要是/boot/grub
5.内核初始化
根据Grub内的定义grub读取完毕后就把下面的工作交给内核了。kernel主要是完成系统硬件探测及硬件驱动的初始化并且以读写的方式挂载根文件系统根切换那么这里就出现了一个“先有鸡还是先有蛋的文件了”具体是什么呢要想访问真正的根文件系统rootfs的话就必须加载根文件系统中的设备这时根文件系统又没有挂载要挂载根文件系统又得加载根文件系统中的驱动程序哪怎么办呢为了解决这个问题这是就用到了initrd文件了。
再来说下kernel初始化所要工作的内容做下简单总结
探测硬件->加载驱动initrd)->挂载根文件系统->rootfs(/sbin/init)
6.init进程依据inittab文件来设定运行级别
内核被加载后内核空间的任务开始向用户空间转移内核空间通过一个间接的initrd(微型linux)向用户空间的/sbin/init过度所以gurb开始引导内核转向initrd。
initrd一个虚拟的文件系统里面有lib、bin、sbin、usr、proc、sys、var、dev、boot等一些目录其实你会发现里面的目录有点像真的/对吧所以我们称之为虚拟的根文件系统作用就是将kernel和真的根文件系统建立关联关系让kernel去initrd中加载根文件系统所需要的驱动程序并以读写的方式挂载根文件系统内核被加载后第一个运行的程序是/sbin/init在引导linux系统的过程中”/sbin/init”是内核第一个加载的程序因此init进程对应的PID号永远为“1“。
此时该文件会读取/etc/inittab文件并依据此文件来进行初始化工作。其实/etc/inittab文件最主要的作用就是设定Linux的运行等级其设定形式是”:id:3:initdefault:”,这就表明linux需要运行在等级3上。Linux的运行等级设定如下
默认运行级别
0halt //关机
1:single user mode //单用户维护模式)
2multi user mode, without NFS //不支持NFS功能
3:multi user mode, text mode //字符界面
4reserved //系统保留
5:multi user mode, graphic mode //图形化界面
6:reboot //重启
/etc/inittab格式及语法(:)
[选项]:[runlevel]:[行为]:[命令]
行为
initdefault代表默认运行级别
sysinit代表系统初始化操作选项
ctrlaltdel代表重启的相关设置
wait代表上一个命令执行结束后方可执行下面的操作
respawn代表后面字段可以无限制再生(reboot)
命令选项
一些命令不过通常都是脚本
7.init进程执行rc.sysinit
在设定了运行等级后linux系统执行的第一个用户层文件就是/etc/rc.d/rc.sysinit脚本程序它做的工作非常多包括设定PATH、设定网络配置(/etc/sysconfig/network)、启动swap分区、设定/proc等等。线程init的最终完成状态是能够使得一般的用户程序可以正常地被执行从而真正完成可供应用程序运行的系统环境。它主要进行的操作有
-
1. 执行函数do_basic_setup(),它会对外部设备进行全面地初始化。
-
2. 构建系统的虚拟文件系统目录树挂载系统中作为根目录的设备。
-
3. 打开设备/dev/console,并通过函数sys_dup()打开的连接复制两次是的文件号0,1,2全部指向控制台。这三个文件连接就是通常所说的“标准输入“stdin,”标准输出”stdout和”标准出错信息“stderr这三个标准I/0通道。
-
4. 准备好以上一切之后系统开始进入用户层的初始化阶段。内核通过系统调用execve()加载执行相应的用户层初始化程序一次尝试加载程序”/sbin/initl”,”/sbin/init”和“/bin/sh”。
只要其中有一个程序加载获得成功那么系统就将开始用户层的初始化而不会再回到init()函数段中。至此init()函数结束Linux内核的引导部分也到此结束。
8.启动内核模块
具体是依据/etc/modules.conf或/etc/modules.d目录下的文件来装载内核模块。
9.执行不同运行级别的脚本程序
根据运行级别的不同系统会运行rc0.d到rc6.d中的相应的脚本程序来完成相应的初始化工作和启动相应的服务。
10.执行/bin/login程序启动mingetty,进入登录状态
系统已经进入到了等待用户输入username和password的时候了已经可以用自己的账号登入系统了到此为止linux系统启动全部完成。