RHCE考试笔记1----------------------------------系统的启动全部过程详解

 

 

    要了解系统是如何启动的,首先要知道文件系统和文件结构。只有了解了什么是文件系统以及文件结构,才能知道计算机是如何识别这些文件并从磁盘中的相应位置读取,因而执行相应的功能模块,从而一步步的进行引导,识别,挂载,最终让用户进入到系统的操作界面的。

而这一切过程,并不需要用户来介入操作,启动过程中每个步骤相互关联,其中每一个环节出现问题就会引起系统的不能启动。而工程师针对出现不能启动的系统停留在哪个环节,可以排查出相应的文件问题,进而对系统进行修复。

 

1. 什么是文件系统

       文件系统是对一个存储设备上的数据和元数据进行组织的机制。定义得非常广泛,不容易理解。我们可以分开来解析,首先什么是存储设备,通俗来讲,存储设备即是计算机里存放数据的硬件。如:内存,硬盘等。而我们所要关注的是硬盘,硬盘的型号有很多种,SCISATA。在linux下硬盘型号的表示在/dev目录下,SCSI硬盘表示为sda,IDE表示为hda。然后,数据和元数据,数据我的理解就是一切计算机能读到的信息,01的各种组合,而元数据则是一组说明这些数据的信息,包括文件类型,文件权限,一些ID号,时间戳等等。总得说来,文件系统就是一组规则,这些规则包括文件组织结构,和文件的附加信息,计算机读取到的文件,通过这些规则来进行翻译和理解。而这些规则就是ext2,ext3,fat32,ntfs等,这些规则是各个操作系统所支持的,而格式化就是对磁盘进行规则约束的过程。因而可以解释了为何在将ext3格式化成FAT32时要将磁盘数据全部重置,因为规则不一样,所读取的数据也不一样,所以必须进行删除丢弃。(ext3ext2的基础上增加了日志系统,所以规则不变,数据也得以保留)

 

2.什么是文件结构

    文件都是散落在磁盘的各个空间,而系统读取文件需要具体的地址,知道文件存储在硬盘的具体位置,所以就要有一定的文件结构告诉计算机去哪寻找文件,像在windows中,磁盘被划分为CDEF这些分区,而每个分区都有自己各自的文件结构,如系统装在C盘,系统文件必须存放在C盘的windows文件夹下,需要读取系统文件,便要告知系统去C:/windows文件夹下的哪个子文件夹读取,所以总得说来文件结构就是一组目录结构,便于系统读取文件数据。

 

linux的文件系统和文件结构

    在RHEL5支持的文件系统ext3,etx2,fat32等等,而默认使用的是ext3文件系统。RHEL5的文件结构和windows大不一样。首先我们要理解根分区(root),即/分区,注意/只是个卷标,用tune2fs l /dev/sdaX 查看,根分区即是所有分区的根分区,也就是说系统在启动时候必须先找到根分区才能找到其他的分区。也可以用e2label来对根分区的卷标进行改变,sdaX中的X是安装系统时所分配的。df可以用来查看各个分区的情况。各个分区如/home,/etc/dev/var等都是在根分区下并列的关系,就像windows下的C D EF 盘,另外在根分区下/root分区为root账号的主目录,其他账号则在/home目录下。

 

系统的启动

    开机第一个界面便是BIOS的初始化界面,我们可以在这个界面上按F2进入BIOS设置界面,boot选项选择系统是从光驱还是网络,还是本地硬盘进行引导。通过了这个界面也就是bios的工作(检查外围设备,选择引导设备)完成了,即将把控制权交给MBRMBR是本机第一块硬盘的第一个扇面的前512字节,包括了GRUB和分区表,其中GRUB446B,分区表占64B。如果只是GRUB损坏我们可以利用grub-install /dev/sda来进行修复,如果是MBR损坏了,必须要在之前有备份在光盘或者其他除本机外的存储设备上,才能进行修复,备份命令如下dd if=/dev/sda of=MBR bs=512 count=1 。而GRUB的任务是加载扇区,加载启动分区,引导启动程序。如果bios找到了GRUB,则会进入GRUB选择界面,在此界面GRUB根据/boot/grub/grub.conf文件里的配置信息进行工作(读秒,默认选择从第几个系统启动,背景图片,隐藏菜单,标题等等),我们可以在此界面进入grub>交互界面输入命令,进入方法是在grub选择界面按C,或者按E进行编辑,修改grub.conf参数,当然这些参数只是对本次开机操作有效。现在我们再来看下grub.conf文件。

A. boot hd00

加载启动分区,hd=hard disk

B. kernel /vmlinuz-2.6.18-164.el5 ro root=LABEL=/ 

加载内核,并以只读的方式去寻找根分区,另外还可以给内核传递参数rhgb queit..

C. initrd /initrd2.6.18-164.el5.img

加载RAMdisk文件

grub界面下可以直接修改管理员密码,交互界面下选择单用户模式1。所以为了安全起见,我们要为grub设置MD加密密码,并把密码放在grub.conf文件的title行上,格式为password md5 密码位 。

 

鸡和蛋的问题

    内核文件:vmlinuz-2.6.18-164.el5  vmlinuz为可引导的压缩的内核vm表示virtual memory,是linux使用硬盘空间作为虚拟内存,vmlinuz是可执行的内核,是一个软链接。2.6是它的大版本号,一般为偶数号,奇数则表示是测试版,18为次版本号。164是补丁号,el5则是红帽封装。默认情况下通常安装的是标准内核,有一些其他的超大型内核运用在小型机等高端机器。

现在问题来了,竟然我已经加载了内核,并且已经识别了根分区,那么系统是不是就能自动挂载文件系统分区了呢?我们来做个试验:

RHCE考试笔记1(系统启动与排错)_RHCE

现在启动

RHCE考试笔记1(系统启动与排错)_系统启动_02

    这个时候问题来了,cannot open root device LABEL=/ or unknown-block(0,0),系统告诉我们不能打开根分区,或者不能识别的块设备(0,0),让我们输入一个正确的根分区,但是前面我在kernel命令下明明告知了系统真确的根分区就是在LABEL=/下啊,我们继续看Unable to mount root fs on unknown-block(0,0),不能够将不能识别的块设备(0,0)挂载到根分区上。这时的问题来了,为什么我不写initrd /initrd2.6.18-164.el5.img就不行呢,这个RAMdisk文件到底是什么作用?想想我们刚刚提到的文件系统结构,rhel5采用的是ext3文件系统,那么我们硬盘的驱动程序也是存放在硬盘中的,系统是不是需要首先驱动硬盘也就是错误提示里的(unknown block)才能正确驱动硬盘?才能够将硬盘挂载到根分区?但是我的驱动就存放在硬盘里,这个是不是就是现有鸡还是先有蛋的问题?那么linux是怎么解决这个棘手的问题呢?为了解决这个矛盾,于是出现了initrd(boot loader initialized RAM disk)initrd是一个被压缩过的小型根目录,这个目录中包含了启动阶段中必须的驱动模块,可执行文件和启动脚本。也就是系统在挂载根分区之前就先利用initrd文件自动将所需的设备进行驱动,从而顺利加载了根分区。那么initrd /initrd2.6.18-164.el5.img文件仅仅就只是上面所说的那些作用吗?

回到开机过程,内核被加载,硬盘被驱动,根分区被挂载,现在系统要做什么?还有为什么内核要以只读的形式挂载根文件系统?带着这些问题我们来关注下内核的具体功能,内核被加载后,首先内核本身带有设备驱动程序,它试图寻找和他们对应的设备,并初始化这些设备,并将输出记录在内核信息缓存中,这里的驱动是编译在内核里的,并不是以模块形式(*.ko)而其他必要的驱动程序则编译成模块存放在/lib/modules里面,而内核则是如何装载这些驱动模块的呢?答案很显然,通过initrdInitrd究竟是个什么东西呢?想个办法得让系统停留在initrd的生存期内,于是修改了fstab文件,重启,系统自动进入了repair模式,也就是所谓的修复模式,如下图,

RHCE考试笔记1(系统启动与排错)_笔记_03

    我们来看下这些系统信息,明显系统内核已经被成功加载,并且已经进入欢迎界面,大大的红字Red Hat已经告诉我们内核引导工作已经结束,现在是init进程正在忙碌,但是到了检查文件系统时出现了错误,并且这个错误无法正常的启动系统(废话),unable to resolve LABEL=/boot3,这个boot3是我改的,也就是说此时系统依然停留在刚才识别根分区的阶段,文件系统依然是ro,输入密码我们来看下是否和我们的猜想一样:

RHCE考试笔记1(系统启动与排错)_系统启动_04

 

    在我把boot3修改成boot的时候出现系统提示错误,说文件时只读的,返回进入etc目录,找到fstab文件,文件权限是可写的啊,而且我是使用root管理员账户登录的:

RHCE考试笔记1(系统启动与排错)_职场_05

    这说明此时系统停留的这个阶段正式刚才的那个根分区,并且只有一个分区,就是/分区(使用df查看),我们再来查看这个根分区里的文件:

RHCE考试笔记1(系统启动与排错)_系统启动_06

    这不就是我们的根分区嘛?目录文件都一样,而且文件都能访问,只是都是只读的,不能进行编辑和修改,那么是不是重新挂载下根目录将它变成可读的那我们就能使用系统了啊?试试看:

RHCE考试笔记1(系统启动与排错)_笔记_07

这次修改成功了,启动个服务试试看:

RHCE考试笔记1(系统启动与排错)_笔记_08

失败了,说明现在系统还没到完全可以使用的阶段,还需要进一步做其他剩下的任务,我们退出,重新启动。

    回到系统的启动过程,我们再来理解initrd /initrd2.6.18-164.el5.img这条命令的意义,在网上寻找了很多有关initrd的说明,个人认为这个最有说服力:

初始 RAM 磁盘(initrd)是在实际根文件系统可用之前挂载到系统中的一个初始根文件系统。initrd 与内核绑定在一起,并作为内核引导过程的一部分进行加载。内核然后会将这个 initrd 文件作为其两阶段引导过程的一部分来加载模块,这样才能稍后使用真正的文件系统,并挂载实际的根文件系统。

initrd 中包含了实现这个目标所需要的目录和可执行程序的最小集合,例如将内核模块加载到内核中所使用的 insmod 工具。

在桌面或服务器 Linux 系统中,initrd 是一个临时的文件系统。其生存周期很短,只会用作到真实文件系统的一个桥梁。在没有存储设备的嵌入式系统中,initrd 是永久的根文件系统。

RHCE考试笔记1(系统启动与排错)_笔记_09

RHCE考试笔记1(系统启动与排错)_笔记_10

而查看这些生成的目录发现里面什么都没有,所以我们就理解了为什么把initrd文件说成是一个映像文件,这里有趣的是我们发现了一个在现实根目录下没有的init文件,用vim编辑打开:

RHCE考试笔记1(系统启动与排错)_系统启动_11

是一个脚本,是在将initrd映像解压到RAM磁盘中被调用的,并成为系统启动的第一个进程。这就解释了系统在完成内核加载后系统是如何将控制权交给init进程的。虽然里面的过程还有很多(如:怎么样创建映像,怎么解压initrd文件之类的工作),但是现在我们应该基本清楚了系统从开机到bios启动,然后grub引导,一直到init进程的启动中间的环节。现在来做个小结:

首先是bios检测外围设备以及选择引导设备,然后把控制权交给了MBR上的grubgrub根据grub.conf中的配置信息,选择并寻找到根分区,并由initr映像在RAMdisk上的一个只读的根文件系统,启动init进程,由init进程完成下面的工作。

 

现在我们来具体看init有关的文件:/etc/inittab   /etc/rc.d/rc.sysinit  /etc/rc.d/rc  /etc/rc.d/rc.local  /etc/fstab

 

首先是/etc/inittab文件:

RHCE考试笔记1(系统启动与排错)_系统启动_12

它是init初始化的配置文件,18行的脚本说明了系统运行的默认级别,2329列出了这些级别应该对应级别的脚本目录:

RHCE考试笔记1(系统启动与排错)_笔记_13

 

21行是系统初始化脚本,我们再看完inittab文件后再来具体讨论/etc/rc.d/rc.init这个文件

 

32行是系统重启所捕获的键盘输入,停留3秒。

 

3841行定义了UPS电源中断和恢复的脚本

RHCE考试笔记1(系统启动与排错)_RHCE_14

4550行定义了各个级别在虚拟控制台生成getty

53行定义了运行级别5时初始化X服务

下面说说系统的运行级别,一共七个级别,分别是06,0是关机,6是重启,1为单用户,2不带网络的多用户,3是多用户,主要用于服务器,4是保留,5是图形界面,另外还有备用的单用户模式s,虽然也是单用户模式,但是和1有明显差别,因为s模式的话是无法读取rc.d下相应级别脚本目录。而我们刚刚修改fstab文件后进入的修复模式则是另外一个启动级别:emergency(紧急救援模式),之所以刚才根分区还是ro的,是因为在启动过程中绕过了我们下面要来讨论的/rc.d/rc.sysinit文件。

 

/etc/rc.d/rc.sysinit文件:

它的主要任务有很多,包括加载卷标和selinux,设定计算机名,设定系统时钟,激活raid和逻辑卷LVM,启动磁盘配额等等,而我们最关心的则是检查并重新挂载根文件系统这个任务,打开vim编辑器,我们寻找到了如下脚本:

RHCE考试笔记1(系统启动与排错)_笔记_15

这更说明了为什么刚才说到的紧急救援模式进入的是只读的系统。

 

 

/etc/rc.d/init.d目录:

RHCE考试笔记1(系统启动与排错)_职场_16

我们发现里面都是一些很熟悉的脚本,如vsftpxinetd,用vim编辑器查看vsftp

RHCE考试笔记1(系统启动与排错)_职场_17

仔细发现这段说明文档正是vsftp服务启动和停止的脚本,现在我们再来进入到刚刚inittab文件里提到的/etc/rc.d/rc X脚本目录,我们以当前级别5作为示例,进入到/etc/rc.d/rc5.d目录下,发现里面清一色的链接文件,用ll命令查看发现所链接的文件正是我们刚刚在/etc/rc.d/init.d目录下的脚本,说明刚才在inittab文件里配置的级别,是根据所在文件夹下链接文件不同来启动和禁用各种服务和进程的。S链接表示启动,K表示结束,数字越小表示越先被启动,越晚被终止,数字越大表示越晚被启动,越早被终止。

 

/etc/rc.d/rc.local则是用户进行自定义运行的开机脚本。

 

/etc/fstab关于这个关键文件的说明我从国外的一个网站找到了一些详细的解释:

The fstab (/etc/fstab) (or file systems table) file is a system configuration file commonly found on Unix systems. The fstab file typically lists all available disks and disk partitions, and indicates how they are to be initialized or otherwise integrated into the overall system's file system. fstab is still used for basic system configuration, notably of a system's main hard drive and startup file system, but for other uses has been superseded in recent years by automatic mounting.

我们用mount命令查看所有的挂载信息,发现所有不管硬件设备还是目录结构的详细信息,而fstab正是这张对应的表格,在系统启动时候告诉系统所挂载的设备名称它的挂载点在哪,什么文件类型,有哪些特性,等等信息,系统正是根据这张表来找到对应设备需要挂载在哪,如我们刚才看到的sysint文件里的脚本mount o remount /,系统如何知道/是要挂载硬盘的那个分区,是sda1还是sda2?在英文解释中很明确的告诉了我们fstab是整个linux系统文件列表的最关键文件,一旦损坏或者丢失,系统将无法正确启动!