ac3165 linux驱动_一文读懂Linux系统启动流程

Linux启动管理

11.1 CentOS 6.x系统启动过程详解

CentOS 6.x系统启动过程发生了较大的变化,使用Upstart启动服务取代了原先的System V init启动服务。Upstart启动服务的效率更高,启动速度更快。我们学习Linux的启动过程,有助于了解Linux系统的结构,也对系统的排错有很大的帮助。

11.1.1 CentOS 6.x基本启动流程

启动过程比较复杂,我们先整理一下基本的启动过程, 有一个整体的印象,然后再进一步说明。目前CentOS 6.x的启动流程是这样的:

  • 服务器加电,加载BIOS信息,BIOS进行系统检测。依照BIOS设定找到第一个可以启动的设备(一般是硬盘)。
  • 读取第一个启动设备的MBR (主引导记录),加载MBR中的Boot Loader (启动引导程序,最为常见的是GRUB)。
  • 依据Boot Loader的设置加载内核,内核会再进行一遍系统检测。系统一般会采用内核检测硬件的信息,而不一定采用BIOS的自检信息。内核在检测硬件的同时,还会通过加载动态模块的形式加载硬件的驱动。
  • 内核启动系统的第一个进程,也就是/sbin/init
  • /sbin/init进程调用/etc/init/rcS.conf配置文件,通过这个配置文件调用/etc/rc.d/rc.sysinit配置文件。而/etc/rc.d/rc.sysinit配置文件是用来进行系统初始化的,主要用于配置计算机的初始环境。
  • 还是通过/etc/init/rcS.conf配置文件调用/etc/inittab配置文件。通过/etc/inttab配置文件来确定系统的默认运行级别。
  • 确定默认运行级别后,调用/etc/init/rc.conf配置文件。
  • 通过/etc/init/rc.conf配置文件调用并执行/etc/rc.d/rc脚本,并传入运行级别参数。
  • /etc/rc.d/rc确定传入的运行级别,然后运行相应的运行级别目录/etc/rc[0-6].d/中的脚本。
  • /etc/rc[0-6].d/目录中的脚本依据设定好的优先级依次启动和关闭。
  • 最后执行/etc/rc.d/rc.local中的程序。
  • 如果是字符界面启动,就可以看到登录界面了。如果是图形界面启动,就会调用相应的X Window接口。

简单来看启动过程就是这样的,接下来分别介绍每步启动过程。

11.1.2 BIOS自检

BIOS (Basic Input Output System,基本输入/输出系统)是固化在主板上一个ROM (只读存储器)芯片上的程序,主要保存计算机的基本输入/输出信息、系统设置信息、开机自检程序和系统自启动程序,用来为计算机提供最底层和最直接的硬件设置与控制。

BIOS在系统的启动过程中会加载这些主机信息,并完成第一次系统的自检(第二次自检由内核完成),我们把BIOS的自检过程称作POST (Power On Self Test,加电自检)。自检完成之后,开始执行硬件的初始化,之后定义可以启动的设备的顺序,然后从第一个可以启动的设备的MBR (Main Boot Record,主引导记录)中读取Boot Loader (启动引导程序)。Linux中最常见的Boot Loader就是GRUB程序。

11.1.3 MBR的结构

MBR也就是主引导记录,位于硬盘的0磁道、0柱面、1扇区中,主要记录了启动引导程序和磁盘的分区表。我们通过图11-1来看看MBR的结构。

ac3165 linux驱动_一文读懂Linux系统启动流程_第1张图片

图11-1 MBR的结构

MBR共占用了一个扇区,也就是512 Byte。其中446 Byte安装了启动引导程序,其后64 Byte描述分区表,最后的2 Byte是结束标记。我们已经知道,每块硬盘只能划分4个主分区,原因就是在MBR中描述分区表的空间只有64 Byte。其中每个分区必须占用16Byte,那么64 Byte就只能划分4个主分区。每个分区的16字节的规划如表11-1所示。

存储字节 数据内容及含义
第1个字节 引导标志;
第2个字节 本分区的起始磁道号;
第3个字节 本分区的起始扇面号;
第4个字节 本分区的起始柱面号;
第5个字节 分区类型,可以识别主分区和扩展分区;
第6个字节 本分区的结束磁道号;
第7个字节 本分区的结束扇面号;
第8个字节 本分区的结束柱面号;
第9~12个字节 本分区之前已经占用的扇区数;
第13~16个字节 本分区的总扇区数;

大家注意到了吧,MBR中最主要的功能就是存储启动引导程序。

11.1.4 启动弓|导程序的作用

BIOS的作用就是自检,然后从MBR中读取出启动引导程序。那么,启动引导程序最主要的作用就是加载操作系统的内核。当然,每种操作系统的启动引导程序都是不同的。

每种操作系统的文件格式不同,因此,每种操作系统的启动引导程序也不一样。不同的操作系统只有使用自己的启动引导程序才能加载自己的内核。如果我的服务器上只安装了一个操作系统,那么这个操作系统的启动引导程序就会安装在MBR中。BIOS调用MBR时读取出启动引导程序,就可以加载内核了。但是在有些时候,我的服务器中安装了多个操作系统,而MBR只有一个,那么在MBR中到底安装哪个操作系统的启动引导程序呢?

很明显,一个MBR是不够用的。每块硬盘只能有一个MBR是不能更改的,所以不可能增加MBR的数量。系统只能在每个文件系统(可以看成分区)中单独划分出一个扇区,称作引导扇区(Boot Sector)。在每个分区的引导扇区中也能安装启动引导程序,也就是说,在MBR和每个单独分区的引导扇区中都可以安装启动引导程序。这样多个操作系统才能安装在同一台服务器中(每个操作系统要安装在不同的分区中),而且每个操作系统都是可以启动的。

但是还有一个问题: BIOS只能找到MBR中的启动引导程序,而找不到在分区的引导扇区中的启动引导程序。那么,要想完成多系统启动,我们的方法是增加启动引导程序的功能,让安装到MBR中的启动引导程序(GRUB)可以调用在分区的引导扇区中的其他启动引导程序。所以启动引导程序就拥有了以下功能:

  • 加载操作系统的内核。这是启动引导程序最主要的功能。
  • 拥有一个可以让用户选择的菜单,来选择到底启动哪个系统。大家如果在服务器上安装过双Windows系统,就应该见过类似的选择菜单,不过这个选择菜单是由Windows的启动引导程序提供的,而不是GRUB。

可以调用其他的启动引导程序,这是多系统启动的关键。不过需要注意的是,Windows的启动引导程序不能调用Linux的启动引导程序,所以我们一般建议先安装Windows,后安装Linux,是为了将Linux的启动弓|导程序安装到MBR中,覆盖Windows的启动引导程序。当然这个安装顺序不是绝对的,就算最后安装了Windows,我们也可以通过手工再安装一遍GRUB的方法,来保证MBR中安装的还是Linux的启动引导程序。

我们画一张示意图来看看启动引导程序的作用,如图11-2所示。

ac3165 linux驱动_一文读懂Linux系统启动流程_第2张图片

图11-2 启动引导程序的作用

11.1.5 加载内核,内核重新自检并加载内核模块

  1. 内核的加载和内核模块

GRUB加载了内核之后,内核首先会再进行一次系统的自检,而不一定使用BIOS检测的硬件信息。这时内核终于开始替代BIOS接管Linux的启动过程了。内核完成再次系统自检之后,开始采用动态的方式加载每个硬件的模块,这个动态模块大家可以想象成硬件的驱动(默认Linux硬件的驱动是不需要手工安装的,如果是重要的功能,则会直接编译到内核当中;如果是非重要的功能,比如硬件驱动会编译为模块,则在需要时由内核调用。不过,如果没有被内核识别的硬件,要想驱动,就需要手工安装这个硬件的模块了。具体的安装方法我们在11.3节中介绍)。

那么,Linux的内核到底放在了哪里呢?当然是/boot的启动目录中了,我们来看看这个目录下的内容吧。

# ls /boot/

我们已经知道,Linux会把不重要的功能编译成内核模块,在需要时再调用,从而保证了内核不会过大。在多数Linux中,都会把硬件的驱动程序编译为模块,这些模块保存在/lib/modules/目录中。常见的USB、SATA和SCSI等硬盘设备的驱动,还有一些特殊的文件 系统(如LVM、RAID等)的驱动,都是以模块的方式来保存的。

如果Linux安装在IDE硬盘之上,并且采用的是默认的ext3/4文件系统,那么内核启动后加载根分区和模块的加载都没有什么问题,系统会顺利启动。但是如果Linux安装在SCSI硬盘之上,或者采用的是LVM文件系统,那么内核(内核加载入内存是启动引导程序GRUB调用的,并不存在硬盘驱动不识别的问题)在加载根目录之前是需要加载SCSI硬盘或LVM文件系统的驱动的。而SCSI硬盘和LVM文件系统的驱动都是放在硬盘的/lib/modules/目录中的,既然内核没有办法识别SCSI硬盘或LVM文件系统,那怎么可能读取/lib/modules/目录中的驱动呢?Linux给出的解决办法是使用initramfs这个虚拟文件系统来处理这个问题。

  1. initramfs虚拟文件系统

CentOS 6.x中使用initramfs虚拟文件系统取代了CentOS 5.x中的initrd RAM Disk。它们的作用类似,可以通过启动引导程序加载到内存中,然后会解压缩并在内存中仿真成一个根目录,并且这个仿真的文件系统能够提供一个可执行程序,通过该程序来加载启动过程中所需的内核模块,比如USB、SATA、SCSI硬盘的驱动和LVM、RAID文件系统的驱动。也就是说,通过initramfs虚拟文件系统在内存中模拟出一个根目录,然后在这个模拟根目录中加载SCSI等硬件的驱动,就可以加载真正的根目录了,之后才能调用Linux的第一个进程/sbin/init

Initramfs虚拟文件系统主要有以下优点:

  • initramfs随着其中数据的增减自动增减容量。
  • 在initramfs和页面缓存之间没有重复数据。
  • initramfs重复利用了Linux caching的代码,因此几乎没有增加内核尺寸,而caching的代码已经经过良好测试,所以initramfs的代码质量也有保证。
  • 不需要额外的文件系统驱动。

其实大家只需要知道initramfs是为了在内核中建立一个模拟根目录,这个模拟根目录是为了可以调用USB、SATA、SCSI LVM、RAID等硬盘接口或文件系统的驱动模块,加载了驱动模块后才可以加载真正的系统根目录。我们可以通过示意图11-3来表示这个过程。

ac3165 linux驱动_一文读懂Linux系统启动流程_第3张图片

图11-3 内核启动流程

那么既然initramfs是一个仿真根目录 那么我们是否可以看看这个仿真根目录中到底是什么样子的呢?当然可以,命令如下:

# mkdir /tmp/initramfs

11.1.6 调用/sbin/init进程

在内核加载完毕,并完成硬件检测与驱动程序加载后,主机硬件已经准备完毕,内核会主动呼叫第一个进程,也就是/sbin/init/sbin/init最主要的功能就是准备软件执行的环境,包括系统的主机名、网络设定、语言、文件系统格式及其他服务的启动等。这里和CentOS 5.x系统相比也有较大变化。在CentOS 5.x系统中,主要是通过init进程的配置文件/etc/inittab来设定系统,并启动Linux的。但是在CentOS 6.x系统中,由于用Upstart启动服务来替换以前的init,所以在/etc/inittab配置文件中只能定义系统的默认运行级别,而其他的功能是靠/etc/init/目录中的其他配置文件实现的。大家可以把/etc/init/目录中的配置文件看成以前/etc/inittab这个文件功能的分拆。

11.1.7 调用/etc/init/rcS. conf配置文件

加载/sbin/init进程后,由init进程调用/etc/init/rcS.conf配置文件。这个配置文件的主要功能如下:

  • 调用/etc/rc.d/rc.sysinit,由/etc/rc.d/rc.sysinit配置文件进行Linux系统初始化。
  • 调用/etc/inittab,由/etc/inittab配置文件确定系统的默认运行级别。

11.1.8 由/etc/rc.d/rc.sysinit配置文件进行Linux系统初始化

/etc/init/rcS.conf配置文件会先调用/etc/rc.d/rc.sysinit配置文件,如果我们查看这个配置文件,就会发现这个配置文件主要进行了以下几项工作:

  1. 获得网络环境。
  2. 挂载设备。
  3. 开机启动画面Plymouth (代替了以往的RHGB)。
  4. 判断是否启用SELinux。
  5. 显示开机过程中的欢迎画面。
  6. 初始化硬件。
  7. 用户自定义模块的加载。
  8. 配置内核的参数。
  9. 设置主机名。
  10. 同步存储器。
  11. 设备映射器及相关的初始化。
  12. 初始化软件磁盘阵列(RAID) 。
  13. 初始化LVM的文件系统功能。
  14. 检验磁盘文件系统(fsck) 。
  15. 设置磁盘配额(quota) 。
  16. 重新以可读写模式挂载系统磁盘。
  17. 更新quota (非必要)。
  18. 启动系统虚拟随机数生成器。
  19. 配置机器(非必要)。
  20. 清除开机过程中的临时文件。
  21. 创建ICE目录。
  22. 启动交换分区(swap) 。
  23. 将开机信息写入/var/log/dmesg文件中。

我们可以查询/var/log/dmesg文件或使用dmesg命令查看系统的初始化信息。当然,我们也可以通过这个命令来看看Linux服务器的硬件信息。

11.1.9 由/etc/inittab配置文件确定系统的默认运行级别

  1. 运行级别

接下来/etc/init/rcS.conf配置文件会再调用/etc/inittab配置文件,在CentOS 6.x中,这个配置文件只能用来设置系统的默认运行级别。那么,什么是运行级别呢?其实Linux是通过运行级别来确定系统启动时到底启动哪些服务的。Linux默认有7个运行级别,具体如表11-2所示。

运行级别 含义
0 关机;
1 单用户模式,可以想象为 windows 的安全模式,主要用于系统修复;
2 不完全的命令行模式,不含 NFS 服务;
3 完全的命令行模式,就是标准字符界面;
4 系统保留;
5 图形模式;
6 重启动;

在Linux系统中可以使用runlevel命令来查看系统的运行级别,命令如下:

# runlevel 

在这个命令的结果中,N3 中的N代表在进入这个级别前,上一个级别是什么; 3代表当前级别。N就是None的意思,也就是说,系统是开机直接进入3运行级别的,没有上一个运行级别。那如果从图形界面切换到字符界面,再查看运行级别,就应该是这样的:

# runlevel 

那么,可以手工改变当前的运行级别吗?当然可以了,只需使用init命令(注意这不是init进程) 即可,命令如下:

# init 5

不过要注意,使用init命令关机和重启并不是太安全,容易造成数据丢失。所以推荐大家使用shutdown命令进行关机和重启。

  1. 系统默认运行级别

知道了运行级别的作用,我们回到系统启动过程中来。/etc/init/rcS.conf配置文件调用/etc/inittab配置文件的目的就是确定系统的默认运行级别,也就是系统一开机后会进入那个运行级别。这个文件的内容如下:

# vim /etc/inittab

注意这里的默认运行级别只能写3或5,其他的级别要么就是关机重启,要么就是保留或单用户,都不能作为系统默认运行级别。

11.1.10 先调用/etc/init/rc.conf,再调用/etc/rc.d/rc脚本文件

一旦确定了默认运行级别,系统就会调用/etc/init/rc.conf配置文件,传入默认级别作为参数。而/etc/init/rc.conf配置文件的作用是调用/etc/rc.d/rc脚本文件。

运行级别参数传入/etc/rc.d/rc这个脚本文件之后,由这个脚本文件按照不同的运行级别启动/etc/rc[0-6].d/目录中相应的程序。而/etc/rc[0-6].d/目录中的程序已经设定好了优先级顺序,按照优先级顺序依次启动相应的程序即可。比如我们的默认运行级别是3,那么这个默认运行级别会先传入/etc/init/rc.conf配置文件,然后再传入/etc/rc.d/rc脚本文件,由此脚本文件调用/etc/rc3.d/目录中所有的程序。这个目录中的程序一般如下:

  • /etc/rc3.d/k??开头的文件(??是数字),会按照数字顺序依次关闭。
  • /etc/rc3.d/S??开头的文件(??是数字),会按照数字顺序依次启动。

这些数字就是设定好的优先级,按照数字顺序依次启动和关闭相应的程序,系统就会启动。另外,/etc/rc3.d/目录中的程序都是链接文件,例如:

# ll /etc/rc3.d/S10network 

所以,启动了这些文件,实际上启动了/etc/init.d/目录中的系统服务。

11.1.11 调用/etc/rc.d/rc.local文件

/etc/rc[0-6].d/目录中的程序启动之后,系统的启动就已经完成。不过我们总有一些程序是需要在系统启动之后随着系统一起启动的。这时我们并不需要自己把需要启动的服务链接到/etc/rc3.d/目录中,因为系统给我们准备了/etc/rc.d/rc.local配置文件。

这个配置文件会在用户登录之前读取,这个文件中写入了什么命令,在每次系统启动时都会执行一次。也就是说,如果有任何需要在系统启动时运行的工作,则只写入/etc/rc.d/rc.locall配置文件即可。这个文件的内容如下:

# ll /etc/rc.local 

Linux的启动过程基本上就是这样的,我们把启动流程图完整,如图11-4所示。

ac3165 linux驱动_一文读懂Linux系统启动流程_第4张图片

图11-4 Linux启动流程

系统的启动过程就是这样的,最终我们就能登录字符界面的Linux了。不过,如果需要启动图形界面的Linux,则还需要调用XWindow接口。

在启动过程中还有一个配置文件会生效,就是/etc/init/start-ttys.conf,这个文件主要定义了Linux支持的1~6个本地终端(tty[1-6])。如果在本机,则可以使用快捷键Alt+F1 ~F6来切换这6个本地终端;如果安装并启动了图形界面,则可以使用快捷键Ctrl+Alt+F7来切换图形终端。

至此,字符界面的启动过程就介绍完了。是不是非常复杂?如果你是初学者,则只需了解,不需要彻底掌握。但是掌握了Linux系统的启动过程,会更加了解Linux的结构。当然,如果你非常自信,则可以尝试安装gentoo Linux这个版本,因为这个Linux版本到目前为止还是纯源码安装的,如果能够安装成功,就会对Linux系统的结构及启动过程有更深入的理解。

11.2 启动引导程序(Boot Loader)

在刚刚的启动过程中,我们已经知道启动引导程序(Boot Loader,也就是GRUB)会在启动过程中加载内核,之后内核才能取代BIOS接管启动过程。如果没有启动引导程序,那么内核是不能被加载的。我们接下来就来看看启动引导程序加载内核的过程,当然initramfs这个虚拟文件系统也是要靠启动引导程序调用的。在CentOS 6.x中,启动引导程序默认是GRUB,GRUB是现在最为流行的启动引导程序,我们也用GRUB来说明启动引导程序的作用。

早期的LILO引导程序已经不是很常见了,GRUB相比来讲有很多优势,主要有:

  • 支持更多的文件系统。
  • GRUB的主程序可以直接在文件系统中查找内核文件。
  • 在系统启动时,可以利用GRUB的交互界面编辑和修改启动选项。
  • 可以动态修改GRUB的配置文件,这样在修改配置文件之后不需要重新安装GRUB,而只需重新启动就可以生效了。

11.2.1 GRUB加载内核的过程

我们已经知道了GRUB的作用有以下几个:第一,加载操作系统的内核;第二,拥有一个可以让用户选择的菜单,来选择到底启动哪个系统;第三,可以调用其他的启动引导程序,来实现多系统引导。按照启动流程,BIOS在自检完成后,会到第一个启动设备的MBR中读取GRUB。在MBR中用来放置启动引导程序的空间只有446Byte,那么GRUB可以放到这里吗?答案是空间不够,GRUB的功能非常强大,MBR的空间是远不够使用的。那么Linux的解决办法是把GRUB的程序分成了三个阶段来执行。

  • Stage 1:执行GRUB主程序。 第一阶段是用来执行GRUB主程序的,这个主程序必须放在启动区中(也就是MBR或者引导扇区中)。但是MBR太小了,所以只能安装GRUB的最小的主程序,而不能安装GRUB的相关配置文件。这个主程序主要是用来启动Stage 1.5和Stage 2阶段的。

  • Stage 1.5:识别不同的文件系统。 Stage 2比较大,只能放在文件系统中(分区),但是Stage 1阶段不能识别不同的文件系统,所以不能直接加载Stage 2阶段。这时需要先加载Stage 1.5阶段,由Stage 1.5来加载不同文件系统中的Stage 2。不过还是有问题,Stage 1.5难道不是放在文件系统中的吗?如果是,那么Stage 1同样不能找到Stage 1.5。其实Stage 1.5还真没有放在文件系统中,而是在安装GRUB时,直接安装到紧跟MBR之后的32 KB的空间中,这段硬盘空间是空白无用的,而且是没有文件系统的,所以Stage 1可以直接读取Stage 1.5。读取了Stage 1.5就能识别不同的文件系统,才能加载Stage 2。

  • Stage 2:加载GRUB的配置文件。 Stage 2阶段主要就是加载GRUB的配置文件/boot/grub/grub.conf,然后根据配置文件中的定义,加载内核和虚拟文件系统。接下来内核就可以接管启动过程,继续自检与加载硬件模块了。

11.2.2 /boot/grub/目录

Stage 2阶段会加载GRUB的配置文件,而GRUB的配置文件主要放置在/boot/grub/目录中。我们来看看这个目录下到底有哪些文件。

# cd /boot/grub/

其实,这个目录中主要就是GRUB的配置文件和各种文件系统的Stage 1.5文件。不过GRUB的配置文件有两个:/boot/grub/grub.conf/boot/grub/menu.lst,这两个配置文件是软链接,所以修改哪一个都可以。

11.2.3 GRUB的配置文件

  1. 在GRUB中分区的表示方法

我们已经知道Linux系统分区的设备文件名的命名是有严格规范的,类似于/dev/sda1 代表第一块SCSI硬盘的第一个主分区。但是在GRUB中分区的表示方法却完全不同,采用了类似hd(0,0)的方式来表示分区。其实也很好理解,其中:

  • hd代表硬盘,不再区分是SCSI接口硬盘,还是IDE接口硬盘,都用hd代表。
  • 第一个0代表Linux系统查找到的第一块硬盘,第二块硬盘为1,以此类推。
  • 第二个0代表这块硬盘的第一个分区,以此类推。

也就是说,hd(0,0)代表的是第一块硬盘的第一个分区,和Linux系统中/dev/sda1的含义类似,只是不再区分是SCSI硬盘还是IDE硬盘。我们用表11-3来说明一下Linux系统对分区的描述和GRUB中对硬盘的描述。

硬盘 分区 Linux中的设备文件名 GRUB中的设备文件名
第一块SCSI硬盘 第一个主分区 /dev/sda1 hd(0,0)
第二个主分区 /dev/sda2 hd(0,1)
扩展分区 /dev/sda3 hd(0,2)
第一个逻辑分区 /dev/sda5 hd(0,4)
第二块SCSI硬盘 第一个主分区 /dev/sdb1 hd(1,0)
第二个主分区 /dev/sdb2 hd(1,1)
扩展分区 /dev/sdb3 hd(1,2)
第一个逻辑分区 /dev/sdb5 hd(1,4)

在这张表中要注意,逻辑分区不能占用主分区与扩展分区的分区号,所以第一个逻辑分区在Linux系统中应该用/dev/sda5表示,在GRUB中应该用hd(0,4)表示。还要注意GRUB的表示方式只在GRUB的配置文件中生效,一旦离开了GRUB的配置文件,就要使用Linux中的设备文件名来表示分区了。

  1. GRUB配置文件的内容

接下来我们就来看看GRUB的配置文件/boot/grub/grub.conf中到底写了什么。命令如下:

# vim /boot/grub/grub.conf

这个文件的内容可以分成两部分:前4行为GRUB的整体设置;title以下4行为要启动的CentOS系统的具体配置。这里只安装了一个系统,如果多系统并存,那么每个系统都会有类似的title行存在(不一定都是4行) 。我们先看整体设置。

  • default=0:默认启动第一个系统。也就是说,如果在等待时间结束后,用户没有选择进入哪个系统,那么系统会默认进入第一个系统。如果有多系统并存,那么每个系统都会有自己的title字段,如果想要默认进入第二个系统,这里就可以设为default=1
  • timeout=5:等待时间,默认是5秒。也就是在进入系统时,如果5秒内用户没有按下任意键,那么系统会进入default字段定义的系统。当然,也可以手工修改这个等待时间,如果timeout=0, 则不会等待直接进入系统;如果timeout=-1, 则会一直等待用户输入,而不会自动进入系统。
  • splashimage=(hd0,0)/grub/splash.xpm.gz:用来指定GRUB启动时的背景图像的保存位置。记得CentOS 6.x启动时后台的蓝色图像吧,就是这个文件的作用。不过这个文件具体在哪里呢?我们已经说过,hd(0,0)代表第一块硬盘的第一个分区,而我的系统在安装时/boot分区就是第一个分区,所以这个背景图像的实际位置就是/boot/grub/splash.xpm.gz
  • hiddenmenu:隐藏菜单。启动时默认只能看到读秒,而不能看到菜单。如果想要看到菜单,则需要按任意键。如果注释了这句话,那么启动时就能直接看到菜单了。

再来绍CentOS系统的具体配置。

  • title CentOS(2.6.32-279.el6.i686):title就是标题的意思,也就是说,在title后面写入的是什么,系统启动时在GRUB的启动菜单中看到的就是什么。

  • root (hd0,0):是指启动程序的保存分区。这里要注意,这个root并不是管理员。在我的系统中,/boot分区是独立划分的,而且设备文件名为/dev/sda1,所以在GRUB中就被描述为hd(0,0)。

  • kernel /vmlinuz-2.6.32-279.e16.i686 ro root=UUID=b9a7a1a8-767f- 4a87-8a2b-a535edb362c9 rd_ NO_ LUKS KEYBOARDTYPE=pC KEYTABLE=uS rd_ NO_ _MD crashkernel=auto CN.UTF-8rd_ NO_ _LVM rd_ NO_ _DM rhgb quiet

    # cat /etc/fstab |grep "/"

    可以看到/分区的UUID和kernel行中的UUID是匹配的。注意一下grep后的/,在/后是有空格的。

    以上禁用都只是在启动过程中禁用,是为了加速系统启动的。

    • KEYBOARDTYPE=pc KEYTABLE=us:键盘类型;
    • crashkernel=auto:自动为crashkernel预留内存;
    • LANG=zh_CN.UTF-8:语言环境;
    • Rhgb:(redhat graphics boot)用图片来代替启动过程中的文字信息。启动完成之后可以使用dmesg命令来查看这些文字信息;
    • Quiet:隐藏启动信息,只显示重要信息。
    • rd_NO_LUKS:禁用LUKS。LUKS用于给磁盘加密;
    • rd_NO_MD:禁用软RAID;
    • rd_NO_DM:禁用硬RAID;
    • rd_NO_LVM:禁用LVM;
    • /vmlinuz-2.6.32-279.el6.i686:指定了内核文件的位置,这里的/是指/boot分区。
    • ro:启动时以只读方式挂载根文件系统,这是为了不让启动过程影响磁盘内的文件系统。
    • root=UUlD=b9a7a1a8-767f-4a87-8a2b-a535edb362c9:指定根文件系统的所在位置。这里和以前的Linux版本不太一样了,不再通过分区的设备文件名或卷标号来指定,而是通过分区的UUID来指定的。那么,如何查询分区的UUID呢?方法有很多种,最简单的办法就是查询/etc/fstab文件。命令如下:
  • Initrd /initramfs-2.6.32-279.el6.i686.img:指定了initramfs虛拟文件系统镜像文件的所在位置。

GRUB的配置文件的内容就是这样的,主要是kernel行较为复杂。不过,在这个/boot/grub/grub.conf配置文件中,只启动了一个Linux系统。如果在服务器中既安装了Linux系统,又安装了Windows系统,那么GRUB的配置文件又是什么样子的呢?

  1. 多系统启动

其实每个系统都是用title字段来表示的,如果在服务器中又多了一个Windows系统,那么在GRUB的配置文件中只不过就是多了一个title字段而已。不过要注意,我们一般建议先安装Windows系统,后安装Linux系统。原因是Windows系统的启动引导程序无法把启动过程转交到Linux系统的GRUB中,自然就不能启动Linux系统了。如果我们后安装Linux系统,GRUB就会安装到MBR中,覆盖Windows系统的启动引导程序。而GRUB是可以把启动过程转交到Windows系统的启动引导程序中的,所以Windows系统和Linux系统都可以顺利启动(当然,如果真的是后安装Windows系统,则也可以通过手工再安装一次GRUB来覆盖MBR中的Windows系统的启动引导程序,具体方法见11.2.4节)。

那么我们就来看看Windows和Linux双系统并存的GRUB的配置文件是什么样子的。命令如下:

# vi /boot/grub/grub.conf

配置文件的变化主要是多了WinXP这一段。rootnoverify(hd0,0)字段说明这个分区不检测,同时标称了Windows系统的启动分区在第一块硬盘的第一个分区中。也就是Windows系统的C:盘在第一块硬盘的第一个分区中。Chainloader +1的意思是,GRUB会把启动过程转交到位于这个分区的第一个扇区(启动扇区)中的引导程序中。我们已经知道,为了实现多系统启动,除MBR中可以安装启动引导程序外,每个分区的第一个扇区也可以安装启动引导程序。在这个例子中,Windows系统的启动引导程序就被安装到了C:盘所在分区的启动扇区中,chainloader +1就是GRUB把启动过程交给了Windows系统的启动引导程序,所以可以启动Windows系统。

11.2.4 手工安装GRUB

需要手工安装GRUB主要有两种情况:一是Linux系统原先不是使用GRUB作为引导程序,而现在想要使用GRUB来作为引导程序;二是MBR中的引导程序被覆盖,需要在MBR中重新安装GRUB,如先安装了Linux系统,后安装了Windows系统。我们分别介绍这两种情况如何手工安装GRUB引导程序。

  1. 系统中没有GRUB,需要手工安装

我们先来讲第一种情况,就是Linux系统中没有安装GRUB,我们需要重新安装GRUB;或者打算把不是启动分区的某个分区变成启动分区。比如我的系统中新建了一个分区/dev/sdb1,并挂载到了/tdisk/目录上(写入fstab文件),我们查看一下新建立的分区,命令如下:

# df -Th

这个分区是我手工建立的,当然不是系统的默认启动分区(系统默认启动分区是/boot分区)。我们用这个分区模拟一个不是采用GRUB作为默认弓|导程序的Linux硬盘,在这个分区中手工安装GRUB引导程序。也就是说,这个实验成功后,/boot分区可以启动系统,/tdisk分区也可以启动系统,具体安装步骤如下:

Step1:使用grub-install命令在要启动的分区中安装GRUB相关文件。

在/boot分区中有一个/boo/grub/目录,这个目录中保存的就是GRUB的相关文件(如文件系统的Stage 1.5文件)。我们查看一下/boot分区中的这个目录,如下:

# ls /boot/grub/

但是在/tdisk目录中并不存在这些文件,所以第一步就是要在/tdisk目录中安装这些GRUB相关文件,具体采用grub-install命令。 这个命令的格式如下:

# grub-install [选项] 设备文件名
选项 说明
--root-directory=DIR DIR为实际目录,也就是手工指定GRUB相关文件的安装目录

例子:命令标准格式(举例而已,这里的实验不需要执行)

# grub-install /dev/sda

查看一下/tdisk/boot/grub目录下文件是否安装上了,命令如下:

# ll /tdisk/boot/grub/

GRUB的相关文件已经安装到/tdisk/boot/grub/目录中。当然,这些文件还是需要GRUB的配置文件来读取的。大家注意到了吗?/tdisk/boot/grub/目录中没有grub.confmenu.lst配置文件,这些配文件还是需要依赖/boot/grub/目录的。

注意:如果系统中没有grub-install命令,则说明没有GRUB软件,这时可以源码包安装,也可以YUM包安装。

Step2:修改GRUB的配置文件。

在我们的实验中,GRUB是已经安装好的,所以可以直接修改/boot/grub/grub.conf配置文件。但如果是没有安装过GRUB的Linux系统手工安装GURB,就需要自己建立GRUB配置文件了。那么我们修改/boot/grub/grub.conf配置文件如下:

# vim /boot/grub/grub.conf

title CentOS tdisk段中不能指定内核镜像和initramfs虚拟文件系统,因为在/tdisk/boot/目录中只有grub目录,而没有内核镜像文件和initramfs虚拟文件系统的镜像文件,所以需要通过chainloader来调用启动扇区。

Step3:安装GRUB到/dev/sdb1分区的启动扇区中。

刚刚通过GRUB配置文件中的chainloader来调用启动扇区,但是/dev/sdb1这个分区是新建立的,它的启动扇区中并没有GRUB程序。所以最后一步就是要在/dev/sdb1分区的启动扇区中安装GRUB。这时就要利用GRUB交互模式了,如下:

# grub

这时GRUB安装完成了,可以重新启动试验一下了。重启后可以看到如图11-5所示的界面。

ac3165 linux驱动_一文读懂Linux系统启动流程_第5张图片 图11-5 GRUB界面

当然/tdisk分区中并没有真正的内核,所以最终还是要靠/boot分区启动。如果是多内核并存的,就可以真正启动了。总结一下,在Linux系统中安装GRUB,或者在新分区中安装GRUB的步骤如下:

  • 第一步:需要在Linux系统的指定分区中安装GRUB的相关文件。这是通过grub-install命令实现的。
  • 第二步:需要按照要求修改GRUB的配置文件,也就是/boot/grub/grub.conf
  • 第三步:需要在分区的启动扇区中安装GRUB,这是通过grub命令的交互模式实现的。
  1. MBR中的GRUB被覆盖,需要重新安装GRUB

这种情况最常见的就是先安装了Linux系统,后安装了Windows系统,导致MBR中的GRUB被覆盖。而Windows系统的启动引导程序又不能识别Linux系统,从而导致Linux系统不能正常启动。其实这种情况解决起来比第一种情况要简单得多,因为不需要安装GRUB的相关文件和修改GRUB的配置文件,也就是第一种情况的第一步和第二步不需要再执行,因为这是已经安装和修改好的。只需要执行第三步,覆盖MBR中的启动引导程序即可。

但是这里的问题是,应该在什么地方启动GRUB的交互模式呢?第一种情况是,我们是在Linux的命令行中执行grub命令,来启动GRUB交互模式的。第二种情况是已经不能正常启动Linux系统了,当然也就没有Linux的命令行了。在这种情况下,我们需要先利用Linux的光盘修复模式,使用光盘来启动Linux,进入Linux的命令行,再指定grub命令。Linux的光盘修复模式将在11.4节中介绍。我们先假设已经进入了光盘修复模式中的Linux命令行,那么只需执行如下命令即可:

#grub

重启系统之后,就可以发现熟悉的GRUB界面又回来了。这种安装GRUB的方式要比第一种情况简单,因为这并不是全新安装,而仅仅是覆盖安装而已。

11.2.5 GRUB加密

Linux在启动时,在GRUB管理界面中是可以通过按e 键进入编辑模式,修改启动选项的。如图11-5所示,每个启动选项都支持按e键进入编辑模式。在编辑模式中可以修改启动模式,比如进入单用户模式(单用户模式主要用于破解密码,我们将在11.4节中讲解)。有时候,我们不想让用户进入编辑模式,就需要给GRUB菜单加密了。那么,如何生成加密的密码串呢?可以通过命令grub-md5-crypt来实现。命令如下:

# grub-md5-crypt 

这样就可以生成加密的密码串,这个字符串是采用MD5加密的,我们会利用这个加密的密码串来加密GRUB配置文件。

GRUB的加密有两种模式:第一种是给每个启动菜单加密,如果不输入正确的密码,则系统不能正常启动;第二种是给GRUB菜单整体加密,如果想进入编辑模式,则必须输入正确的密码。

  1. 给每个启动菜单加密

如果给每个启动菜单加密,那么系统在启动时进入相应的启动菜单,必须输入正确的密码,否则系统不能启动。具体的方法如下:

# vim /boot/grub/grub.conf 

这样就能加密CentOS启动菜单了,在启动时如果不输入正确的密码,否则是不能启动系统的。需要注意的是,password选项一定要在title下面第一行。

  1. 给GRUB菜单整体加密

如果只是加密单个启动菜单,那么GRUB的编辑模式是不能被锁定的,仍然可以按e键进入编辑模式。而且在进入编辑模式后,是可以删除password字段的,再按b(boot 启动)键就可以不用密码直接进入系统。这时就需要给GRUB菜单整体加密了。在整体加密后,如果想进入GRUB编辑界面,则必须输入正确的密码。加密方法其实只是把password字段换一个位置而已,具体方法如下:

# vim /boot/grub/grub.conf 

这样就会把GRUB界面整体加密,想要进入GRUB的编辑界面,必须先输入正确的密码,如题11-6所示。

ac3165 linux驱动_一文读懂Linux系统启动流程_第6张图片 图11-6 GRUB整体加密

注意到了吗?在GRUB界面中已经看不到e 键了,必须输入p键,并输入正确的密码才能进入编辑界面。但是这样加密,在启动CentOS时,是不需要密码就能正常启动的。如果既需要GRUB的整体加密,又需要系统启动时输入正确的密码,那应该怎么做呢?很简单,方法如下:

# vim /boot/grub/grub.conf 

只要在GRUB整体配置中加入password选项,在title中加入lock选项,就可以既加密GRUB编辑界面,又加密系统启动过程了。是不是很简单?

11.2.6 纯字符界面调整分辨率

如果安装了Linux的图形界面,则使用图形界面修改分辨率非常方便也很简单。但是如果只安装了字符界面,难道就不能修改分辨率了吗?当然是可以的,只要利用GRUB的配置文件就可以完成。当然需要确定内核是否支持CONFIG_FRAMEBUFFER_CONSOLE功能,如果没有开启这项功能,则需要重新编译内核。查询方法如下:

# grep "CONFIG_FRAMEBUFFER_CONSOLE" /boot/config-2.6.32-642.el6.x86_64 

在字符界面下支持的分辨率列表如表11-4所示。

色深 640x480像素 800x600像素 1024x768像素 1280x1024像素
8位 769 771 773 775
15位 784 787 790 793
16位 785 788 791 794
32位 786 789 792 795

如果想把字符界面的分辨率设置为1024像素x768像素,色深为16位,则只需要修改GRUB的配置文件,在kernel行最后加入下面的内容:

# vim /boot/grub/grub.conf

然后重新启动系统,就会发现分辨率已经改变了。有些Linux的版本需要将vga的值写成十六进制的,可以先试试表11-4中的数字,如果不行则可以尝试十六进制数。

你可能感兴趣的:(ac3165,linux驱动,centos,aria2开机启动)