详细到每个过程系统做了哪些事情
启动过程 (PC架构)
POST –> Boot Sequence(BIOS) –> Boot Loader (MBR)–>GRUB—> Kernel(ramdisk) –> rootfs –> switchroot –> /sbin/init–>(/etc/inittab, /etc/init/*.conf) –> 设定默认运行级别> 系统初始化脚本 –> 关闭或启动对应级别下的服务 –> 启动终端
第一步:加电自检(POST)
系统加电之后,首先进行的硬件自检,一但通电后主板会自动读取ROM(只读)中的程序,进行加载,计算机会首先加载BIOS信息,BIOS信息是如此的重要,以至于计算机必须在最开始就找到它。检查各种硬件设备是否完整存在,如内存,硬盘,显示,IO设备等。如果有硬件故障的话将按两种情况理:对于严重故障(致命性故障)则停机,此时由于各种初始化操作还没完成,不能给出任何提示或信号;对于非严重故障则给出提示或声音报警信号,等待用户处理),如果没有故障,POST完成自己
的接力任务,将尾部工作交接给BIOS处理。
第二步:系统引导过程Boot Sequence(BIOS)
POST 过程结束后,系统的控制权从 BISO 转交到 boot loader。Boot loader 一般存储在系统的硬盘上(传统的 BIOS/MBR 系统),这个时候机器不能获取外部的存储或者网络信息,一些重要的值(日期、时间、其他外部值)都是从CMOS里读取.
POST(POST-power on self test)—>ROM->CMOS(互补金属氧化物)->BIOS (Basic Input Output System,基础输入输出系统)
BIOS(Basic Input/Output System)启动初始化硬件的工作,包括屏幕和键盘,内存检测,这个过程也被成为 POST(Power On Self Test),通过ROM加载自检程序,然后按照 CMOS RAM 中设置的启动设备查找顺序,来寻找可启动设备 。注:BIOS 程序嵌在主板的 ROM 芯片上的。
第三步:启动加载器阶段Master Boot Loader(MBR)
硬盘上第0磁道第一个扇区被称为MBR,也就是Master Boot Record,即主引导记录,决定启动介质按照BIOS所设定的系统启动流程,根据引导次序(Boot Sequence)自上而下的寻找对应存储设备上操作系统的MBR。它的大小仅有512字节,但里面却存放了预启动信息、分区表信息。可分为两部分:
第一部分为引导(PRE-BOOT)区,占了 446个字节;
第二部分为分区表(PARTITION TABLE),共有64个字节,每个主分区占用16字节,记录硬盘的分区信息。(这就是为什么一块硬盘只能有4个主分区)分区表有效性标记会占用2字节。
预引导区的作用之一是找到标记为活动(ACTIVE)的分区,并将活动分区的引导区读入内存。剩余两个字节为结束标记。寻找 grub,读取配置文件/etc/grub.conf,决定默认启动项根据MBR所指引的活动分区上寻找系统分区中的 bootloader.在bootloader当中配置了所要引导操作系统的内核所在的位置,因此BIOS被载入内存以后,当它实现将控制权限转交给bootloader以后,bootloader接收整个系统的控制权限,而后根据用户的选择去读取相应操作系统中的内核,并将内核装载入内存的某个空间位置,解压缩,这时kernel就可以在内存中活动,并根据kernel本身功能在内存当中探索硬件并加载硬件驱动程序并完成内核初始化,bootloader会将控制权限转交给内核。
第四步:引导加载器阶段(GRUB加载器)
对于GRUB来说,一个比较好的方面就是它包含了linux文件系统的支持。GRUB能够从ext2或者ext3文件系统中加载linux内核。一旦Bootloader的第一阶段已完成MBR(启动加载器阶段),并能找到实际的引导加载程序位置,第1阶段启动加载器加载引导程序到内存中开始第二阶段。GRUB引导加载器阶段它是通过将本来两阶段的boot loader转换成三个阶段的boot loader。
stage1个阶段 :BIOS加载MBR里面的GRUB(属于第1阶段的文件),由于只有GRUB只占用446字节所以不能实现太多的功能,所以就有此阶段里面的文件来加载第1.5阶段的文件(/boot/grub下的文件)
stage1.5个阶段:这个阶段里面的就是加载识别文件系统的程序,来识别文件系统,不加载就无法识别文件系统,进而就找不到boot目录,由于GRUB是无法识别LVM,所以你不能把/boot分区设置为LVM,所以必须要把/boot单独分区
stage2个阶段:这里面才是正在的开始寻找内核的过程,然后是启动内核
(当stage1.5的boot loader被加载并运行时,stage2 的boot loader才能被加载。)
当stage2被加载时,GRUB能根据请求的情况显示一个可选内核的清单(在 /etc/grub.conf 中进行定义,同时还有几个软符号链接 /etc/grub/menu.lst 和 /etc/grub.conf)。你可以选择一个内核,修改其附加的内核参数。同时,你可以选择使用命令行的shell来对启动过程进行更深层次的手工控制。
GRUB的配置文件中的配置哪些信息
在第二阶段boot loader加载到内存中后,就可以对文件系统进行查询了,同时,默认的内核镜像以及初始化内存盘镜像也被加载到内存中。
根据grub设定的内核映像所在路径,系统读取内存映像,并进行解压缩操作。此时,屏幕一般会输出“Uncompressing Linux(解压内核中)”的提示。当解压缩内核完成后,屏幕输出“OK, booting the kernel(正在启动内核)”。
第五步:加载kernel
GRUB把内核加载到内存后展开并运行,此时GRUB的任务已经完成,接下来内核将会接管并完成:
探测硬件—>加载驱动—>挂载根文件系统—>切换至根文件系统(rootfs)—>运行/sbin/init完成系统初始化
内核一般都是压缩的,所以它的首要任务是解压缩,然后检查和分析系统的硬件并初始化内核里的硬件驱动程序。内核刚加载到内存的时候,文件系统还不能使用,它使用的是 Boot Loader 加载进内存的 initramfs。系统将解压后的内核放置在内存之中,并调用start_kernel()函数来启动一系列的初始化函数并初始化各种设备,完成Linux核心环境的建立。至此,Linux内核已经建立起来了,基于Linux的程序应该可以正常运行了。
第六步:初始化initrd /etc/inittab
在核心加载完毕,进行完硬件侦测与驱动程序加载后,内核会启动第一个进程/sbin/init, init进程将会读取/etc/inittab,init进程是系统所有进程的起点,你可以把它比拟成系统所有进程的老祖宗,没有这个进程,系统中任何进程都不会启动。
/etc/inittab最主要的功能就是准备软件运行的环境,包括系统的主机名称、网络配置、语系处理、文件系统格式及其他服务的启动等,而所有的动作都根据在/etc/inittab中的配置.将会执行/etc/inittab来设定系统运行的默认级别,
init进程首先会读取/etc/inittab文件,根据inittab文件中的内容依次执行
设定系统运行的默认级别(id:3:initdefault:)
执行系统初始化脚本文件(si::sysinit:/etc/rc.d/rc.sysinit)
执行在该运行级别下所启动或关闭对应的服务(l3:3:wait:/etc/rc.d/rc 3)
启动6个虚拟终端
0-6:7个级别的定义
0:关机, shutdown
1:单用户模式(singleuser),root用户,无须认证;维护模式;
2:多用户模式(multiuser),会启动网络功能,但不会启动NFS;维护模式;
3:多用户模式(mutliuser),完全功能模式;文本界面;
4:预留级别:目前无特别使用目的,但习惯以同3级别功能使用;
5:多用户模式(multi user),完全功能模式,图形界面;
6:重启,reboot
许多程序需要开机启动。它们在Windows叫做”服务”(service),在Linux就叫做”守护进程”(daemon)。init进程的一大任务,就是去运行这些开机启动的程序。但是,不同的场合需要启动不同的程序,比如用作服务器时,需要启动Apache,用作桌面就不需要。
Linux允许为不同的场合,分配不同的开机启动程序,这就叫做”运行级别”(runlevel)。也就是说,启动时根据”运行级别”,确定要运行哪些程序。
要访问根文件系统必须要加载根文件系统所在的设备,而这时根文件系统又没有挂载,要挂载根文件系统有需要根文件系统的驱动程序,这是一个典型的先有鸡先有蛋的问题!为解决这个问题,GRUB在加载内核同时,也把initrd加载到内存中并运行.那么initrd又起到了什么作用哪?
initrd展开后的文件
linux中/下的文件
我们可以看到,其实initrd文件其实是一个虚拟的根文件系统,里面有bin、lib、lib64、sys、var、etc、sysroot、dev、proc、tmp等根目录,它的功能就是讲内核与真正的根建立联系,内核通过它加载根文件系统的驱动程序,然后以读写方式挂载根文件系统,至此,内核加载完成。
第七步:运行/sbin/init,进行系统初始化
/sbin/init 最主要的功能就是准备软件运行的环境,包括系统的主机名称、网络配置、语系处理、文件系统格式及其他服务的启动等,而所有的动作都根据在/etc/inittab中的配置.init首先运行/etc/init/rcS.conf脚本
第八步:启动系统服务/etc/rc.d/rc.sysinit
可以看到,init进程通过执行/etc/rc.d/rcS.conf首先调用了/etc/rc.d/rc.sysinit,对系统做初始化设置,设置好整个系统环境。我们来看看这个脚本都是做了些什么哪?
事实上init执行/etc/rc.d/rc.sysinit的初始化将会做很多设置:
1 | 1、获得网络环境 |
第九步:启动配置文件/etc/rc.d/rc.n
设定完系统默认运行级别以后,接着调用/etc/rc.d/rc脚本,/etc/rc.d, 里面存放了rc.local, rc.sysinit, init.d, rcX.d (X包括0-6对应相对runlevel).这个脚本接收默认运行级别参数后,依脚本设置启用或停止/etc/rc.d/rc[0-6].d/中相应的程序。
/etc/rc.d/rc3].d/下的脚本文件在系统初始化阶段,脚本名字以K开头的,表示STOP动作(关闭),名字以S开头,表示Start动作(启动),文件名K/S 后面的的数字代表优先级,名称中的数字表示执行次序(优先级),数字越小表示越先执行,优先级越高
第十步:用户自定义开机启动程序 (/etc/rc.d/rc.local)
系统根据runlevel启动完rcX.d中的脚本之后,会调用rc.local脚本,如果你有一个脚本命令不论在3和5都想开机启动,那么就添加于此,免去rc3.d和rc5.d分别增加启动脚本工作量.最后,将执行/etc/rc.d/rc.local脚本,可以根据自己的需求将一些执行命令或者脚本写到其中,当开机时就可以加载。
第十一步:打印登录提示符
系统初始化完成后,init给出用户登录提示符(login)或者图形化登录界面,用户输入用户和密码登陆后,系统会为用户分配一个用户ID(uid)和组ID(gid),这两个ID是用户的身份标识,用于检测用户运行程序时的身份验证。登录成功后,整个系统启动流程运行完毕!