Linux(RHEL6)启动过程详解
Linux(RHEL6)启动过程详解
Linux(红帽RHEL6)启动过程详解:
RHEL的一个重要和强大的方面是它是开源的,并且系统的启动过程是用户可配置的。用户可以自由的配置启动过程的许多方面,包括可以指定启动时运行的程序。同样的,系统关机时所要终止的进程也是可以进行组织和配置的,即使这个过程的自定义很少被需要。
理解系统的启动和关机过程是如何实现的不仅可以允许自定义,而且也可以更容易的处理与系统的启动或者关机相关的故障。
1.启动过程
以下是启动过程的几个基本阶段:
① 系统加载并允许boot loader。此过程的细节取决于系统的架构。例如:
●基于BIOS的x86系统这第一个运行boot loader的阶段是先从主硬盘的MBR开始的,然后再额外加载一个boot loader即GRUB。
●基于UEFI的x86系统要挂载一个包含GRUB boot loader的EFI系统分区。EFI的启动管理器以一个EFI应用程序的形式来加载并运行GRUB 引导程序。
●对于Power Systems服务器来说,需要挂载一个包含Yaboot boot loader的PPC PReP分区。并由系统管理服务(SMS)启动管理器来加载并运行yaboot 引导程序。
●对于IBM System z(IBM大型机)来说,它会从一个DASD或者FCP-connected设备上运行z/IPL boot loader。
② boot loader 将内核加载到内存中,然后,依此加载任何必需的模块并以只读的方式将挂载根分区。
③ 内核将启动过程的控制权转交给/sbin/init程序。
④ /sbin/init程序加载所有的服务和用户空间工具,并挂载在/etc/fstab中列出的所有分区。
⑤ 出现登录界面,用户登录新启动的系统。
2. 启动过程的细节
启动过程的最初阶段根据硬件平台的不同会出现差异。然而,一旦内核被boot loader发现并加载,那么之后的启动过程在所有的架构平台上都是相同的。以下内容主要是以x86架构平台来讲述。
㈠ 固件接口
①基于BIOS的x86系统
BIOS是一个不仅控制着启动过程的第一步,而且也是为外围设备提供了最底层接口的固件接口。在装有BIOS的x86系统设备上,BIOS程序被写入只读并可永久存储的存储器中(即ROM),并一直保持可用。当系统启动的时候,处理器(即cpu)从内存的最后(即最高)地址段读取BIOS程序并运行它。
一旦BIOS程序被加载,BIOS就会检验系统,查找并检测外围设备,然后再定位一个可以有效启动系统的设备。通常,它会先检查光驱或者是USB设备是否可以引导,如果检查失败,然后再检测系统硬盘。在大多数情况下,可启动驱动器的查找顺序是由在BIOS中的相关设定来控制的。在IDE设备中,它会查看主IDE总线上的主IDE设备是否可以启动系统。在SATA设备中,它会查看哪个SATA设备上设置了启动标记。然后,BIOS将相应启动设备上第一扇区中保存的程序(称作MBR,即主引导记录)加载到内存。MBR仅有512字节的大小,其中包含启动机器的机器代码指令,被称为boot loader,同时也包含了分区表。一旦BIOS将boot loader找到并加载到内存中,那么BIOS就会把启动过程的控制权转交给它。
第一阶段的boot loader是一小段在MBR上的二进制机器代码。它的唯一作用是定位第二阶段的boot loader(GRUB),并将它(GRUB)的第一部分加载到内存中。
(注释:当机器一加电BIOS程序就会被加载到主存中一个被称为Shadow RAM的内存保留区当中,因为Shadow RAM中的地址是ROM BIOS地址空间的映射,两者的地址空间完全相同,所以CPU直接对Shadow RAM进行访问即可,而且速度比直接访问ROM要快的多。)
② 基于UEFI的x86系统
UEFI(即,Unified Extensible Firmware Interface,通用固件接口)像BIOS一样,它是被设计用来控制启动过程(通过启动服务来提供)并提供一个系统固件和操作系统之间的接口(通过runtime服务来提供)。和BIOS不一样的是它有自己的体系架构,不依赖与CPU,它有自己的设备驱动。UEFI可以挂载分区并读取某些文件系统。
当一个装有UEFI的x86计算机启动的时候,UEFI将会查找一个使用GUID(全局唯一标识符)标明的系统存储分区,并把这个分区标记为ESP(即,EFI System Partition)。这个分区包含被编译为EFI架构的应用程序,这些应用程序包含系统的bootloader和实用软件。UEFI系统包含一个EFI启动管理器,这个管理器可以从一个默认的配置中来启动系统,或者提示用户选择一个系统来启动。当一个系统被选择时,不管是手动的还是被动的,UEFI都会将对应的bootloader读入内存并将启动过程的控制权转交给bootloader。
㈡ 引导加载程序——The Boot Loader
① x86系统架构的引导加载程序GRUB
系统加载GRUB到内存中,GRUB是如何被加载如内存中的:一是在装有BIOS的机器中由第一阶段的bootloader直接引导至GRUB;或者是在装有UEFI的机器中直接从EFI系统分区读取。
在启动的时候GRUB bootloader可以读取ext2,ext3,ext4文件系统的分区,并加载其配置文件——/boot/grub/grub.conf(对于基于BIOS的)或者/boot/efi/EFI/redhat/grub.conf(对于UEFI的)。
(注:在RHEL6中,GRUB bootloader 支持ext2,ext3,ext4文件系统。它不支持其他的像VFAT,Btrfs或者XFS,也不支持LVM,也就是说包含/boot目录的分区的文件系统必须是ext2,ext3,ext4文件系统,其他的是不可以的。)
一旦第二阶段的bootloader进入内存后,它就会在屏幕上以图形化的方式显示需要不同的操作系统,或者内核,来让用户选择要启动的系统或内核(注:当更新内核的时候,bootloader的配置文件会被自动的更新)。
一旦第二阶段的bootloader确定要启动哪个内核。它就会在/boot目录里查找对应的内核二进制文件。内核二进制文件的命名格式是:/boot/vmlinuz-<kernel-version>。其中<kernel-version>只要和/boot/grub/grub.conf中,指定的一样即可。
然后,bootloader在将initramfs镜像放入内存中。 initramfs是被内核所使用的,用来加载启动系统所必需的驱动和模块。这个镜像文件对于存有SCSI或者使用ext3,ext4文件系统的计算机非常的重要。
一旦内核和initramfs镜像被加载到内存,bootloader就会将启动过程的控制权转交给内核。随后,内核在再把启动过程的控制权转交给init命令。
② 关于其他系统架构的引导加载程序
除了被用于查找和加载内核的引导程序不一样外,其他的启动过程完全一样。
㈢ 内核
当内核加载后,它会立即初始化并配置计算机的内存,配置各种依附于系统的硬件,包括CPU,I/O子系统和存储设备等。然后查找initramfs镜像文件并加载其进入内存,然后将其直接解压到/sysroot/,并加载所有必需的驱动。接下来,它会初始化和文件系统相关的设备,例如LVM和软RAID。再然后,内核创建一个根设备,并以只读的方式挂载。到此,内核已经基本完成所有的工作,并可以进行运作。但是,因为此时还不允许用户进行输入操作,所以还不能进行其他跟多的操作。所以,为了设置用户环境,内核开始执行/sbin/init程序。
㈣ /sbin/init 程序
/sbin/init程序完成余下的启动过程并配置用户环境。
当init命令启动的时候,它会成为所有自动启动的进程的父进程。首先,它运行/etc/rc.d/rc.sysinit脚本,此脚本的作用是:设置环境变量,启动swap,检查文件系统,执行所有系统初始化所必须的其他步骤。例如,大多数系统要使用的时钟,rc.sysinit也会读取/etc/sysconfig/clock配置文件来初始化硬件的时钟。再如,如果有比较特殊的串口进程需要初始化,那么,rc.sysinit也会执行/etc/rc.serial文件等。
然后,init命令会处理/etc/event.d目录下的作业,此目录是用来描述系统是如何对每个Sysv init的运行级别进行设置的。Runlevel是一种被在/etc/rc.d/rc<x>.d/目录中列出的各种服务所定义的状态或者模式,其中<x>表示运行的级别。紧接着,init命令设置源函数库——/etc/rc.d/init.d/functions,此文件是用来配置如何启动,停止程,并确定程序PID的。
init程序通过在/etc/inittab中指定的运行级别,找对应的的rc目录,然后启动对应的目录下的所有后台进程。例如,如果/etc/inittab中的运行级别是5,那么init程序就会找到/etc/rc.d/rc5.d目录,然后根据/etc/rc.d/rc5.d目录的列表来决定要启动或停止哪些进程。其实,/etc/rc.d/rc5.d目录下并不存在启动或停止服务的真实脚本,在/etc/rc.d/rc5.d目录下的所有文件只是/etc/rc.d/init.d目录下对应文件的符号链接罢了。其中,每个符号链接文件都是以‘K’或‘S’ 开头的。以‘K‘开头的链接文件是在对应运行级别上不启动的。而以‘S’开头的链接文件是在对应运行级别上要启动的。
init命令首先是通过发送/etc/rc.d/init.d/<command> stop 命令来停止所有对应运行级别的目录中以‘K’开头的所有符号链接文件,其中,<command> 是指要需要停止的服务或进程。然后,再通过发送/etc/rc.d/init.d/<command> start 来启动对应运行级别的目录中所有以‘S‘开头的符号链接文件。
每个符号链接文件的启动顺序是根据’K‘或‘S’后面的数字来决定的。数字越低,启动的越早。如果数字相同,那么就按照数字后面字母的顺序来依次启动。我们可以通过修改数字的大小来决定服务或进程启动的先后顺序。
注:init程序最后要执行的文件之一是/etc/rc.d/rc.local文件。这个文件主要用来给用户自定义使用的。
在init命令处理完对应运行级别的rc目录中所有服务后,init就会立即为每一个虚拟控制台调用一个/sbin/mingetty程序,并分配给在/etc/event.d目录下所定义的对应运行级别。运行级别2-5有六个虚拟控制台。运行级别1有一个,运行级别0和6没有。/sbin/mingetty进程是开启了同tty设备进行通信的路径,通过此进程就可以设置tty设备的模式,打印登陆提示符,接收用户的用户名和密码,并初始化登陆过程。而在运行级别5上,init会运行一个叫做/etc/X11/prefdm的脚本,然后此脚本就会根据文件/etc/sysconfig/desktop中所配置的内容来启动X显示管理器(gdm,kdm,xdm)。
㈤ Job 定义
在以前,sysvinit包会为init守护进程提供默认的配置。当系统启动的时候,init守护进程就会运行/etc/inittab脚本,并运行对应运行级别上的服务进程。而现在的init守护进程的默认配置使用的是事件驱动的形式,由upstart包提供。无论什么时候发生了特殊事件,init守护进程都会对存储在/etc/event.d目录下的作业进行处理。init守护进程会把系统的启动作为一个事件来识别。
通常每个作业指定一个程序,并且以触发init的事件的形式来运行或停止此程序。有些作业像是批处理任务,执行动作并直到再发生另一个触发事件触发此作业的时候在终止。有些作业像是服务,一直处于运行状态,直到另一个事件或用户停止它。
本文出自 “一切皆有可能” 博客,请务必保留此出处http://noican.blog.51cto.com/4081966/1656582
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。