`

第二十二章 Boot Loader: Grub

 
阅读更多
在看完了前面的整个启动流程,以及核心模块的整理之后,你应该会发现到一件事情, 那就是『 boot loader 是加载核心的重要工具』啊!没有 boot loader 的话,那么 kernel 根本就没有办法被系统加载的呢!所以,底下我们会先谈一谈 boot loader 的功能, 然后再讲一讲现阶段 Linux 里头最主流的 grub 这个 boot loader 吧!

boot loader 的两个 stage

我们在第一小节启动流程的地方曾经讲过,在 BIOS 读完资讯后,接下来就是会到第一个启动装置的 MBR 去读取 boot loader 了。这个 boot loader 可以具有菜单功能、直接加载核心文件以及控制权移交的功能等, 系统必须要有 loader 才有办法加载该操作系统的核心就是了。但是我们都知道, MBR 是整个硬盘的第一个 sector 内的一个区块,充其量整个大小也才 446 bytes 而已。 我们的 loader 功能这么强,光是程序码与配置数据不可能只占不到 446 bytes 的容量吧?那如何安装?

为了解决这个问题,所以 Linux 将 boot loader 的程序码运行与配置值加载分成两个阶段 (stage) 来运行:

Stage 1:运行 boot loader 主程序:
第一阶段为运行 boot loader 的主程序,这个主程序必须要被安装在启动区,亦即是 MBR 或者是 boot sector 。但如前所述,因为 MBR 实在太小了,所以,MBR 或 boot sector 通常仅安装 boot loader 的最小主程序, 并没有安装 loader 的相关配置档;

Stage 2:主程序加载配置档:
第二阶段为透过 boot loader 加载所有配置档与相关的环境参数文件 (包括文件系统定义与主要配置档 menu.lst), 一般来说,配置档都在 /boot 底下。
那么这些配置档是放在哪里啊?这些与 grub 有关的文件都放置到 /boot/grub 中,那我们就来看看有哪些文件吧!

[root@www ~]# ls -l /boot/grub
-rw-r--r--  device.map              <==grub 的装置对应档(底下会谈到)
-rw-r--r--  e2fs_stage1_5           <==ext2/ext3 文件系统之定义档
-rw-r--r--  fat_stage1_5            <==FAT 文件系统之定义档
-rw-r--r--  ffs_stage1_5            <==FFS 文件系统之定义档
-rw-------  grub.conf               <==grub 在 Red Hat 的配置档
-rw-r--r--  iso9660_stage1_5        <==光驱文件系统定义档
-rw-r--r--  jfs_stage1_5            <==jfs 文件系统定义档
lrwxrwxrwx  menu.lst -> ./grub.conf <==其实 menu.lst 才是配置档!
-rw-r--r--  minix_stage1_5          <==minix 文件系统定义档
-rw-r--r--  reiserfs_stage1_5       <==reiserfs 文件系统定义档
-rw-r--r--  splash.xpm.gz           <==启动时在 grub 底下的背景图示
-rw-r--r--  stage1                  <==stage 1 的相关说明
-rw-r--r--  stage2                  <==stage 2 的相关说明
-rw-r--r--  ufs2_stage1_5           <==UFS 的文件系统定义档
-rw-r--r--  vstafs_stage1_5         <==vstafs 文件系统定义档
-rw-r--r--  xfs_stage1_5            <==xfs 文件系统定义档


从上面的说明你可以知道 /boot/grub/ 目录下最重要的就是配置档 (menu.lst) 以及各种文件系统的定义! 我们的 loader 读取了这种文件系统定义数据后,就能够认识文件系统并读取在该文件系统内的核心文件罗。 至於 grub 的配置档档名,其实应该是 menu.lst 的,只是在 Red Hat 里面被定义成为 /boot/grub.conf 而已。 鸟哥建议您还是记忆 menu.lst 比较好喔!

所以从上面的文件来看, grub 认识的文件系统真的非常多喔!正因为如此,所以 grub 才会取代 Lilo 这个老牌的 boot loader 嘛!好了,接下来就来瞧瞧配置档内有啥配置值吧!

grub 的配置档 /boot/grub/menu.lst 与菜单类型

grub 是目前使用最广泛的 Linux 启动管理程序,旧的 Lilo 这个启动管理程序现在已经很少见了, 所以本章才会将 Lilo 的介绍舍弃的说。grub 的优点挺多的,包括有:

认识与支持较多的文件系统,并且可以使用 grub 的主程序直接在文件系统中搜寻核心档名;
启动的时候,可以『自行编辑与修改启动配置项目』,类似 bash 的命令模式;
可以动态搜寻配置档,而不需要在修改配置档后重新安装 grub 。亦即是我们只要修改完 /boot/grub/menu.lst 里头的配置后,下次启动就生效了!
上面第三点其实就是 Stage 1, Stage 2 分别安装在 MBR (主程序) 与文件系统当中 (配置档与定义档) 的原因啦! 好了,接下来,让我们好好了解一下 grub 的配置档: /boot/grub/menu.lst 这玩意儿吧! 要注意喔,那个 lst 是 LST 的小写,不要搞错罗!

硬盘与分割槽在 grub 中的代号

安装在 MBR 的 grub 主程序,最重要的任务之一就是从磁碟当中加载核心文件, 以让核心能够顺利的驱动整个系统的硬件。所以罗, grub 必须要认识硬盘才行啊!那么 grub 到底是如何认识硬盘的呢? 嘿嘿! grub 对硬盘的代号配置与传统的 Linux 磁碟代号可完全是不同的!grub 对硬盘的识别使用的是如下的代号:

(hd0,0)

够神了吧?跟 /dev/hda1 风马牛不相干~怎么办啊?其实只要注意几个东西即可,那就是:

硬盘代号以小括号 ( ) 包起来;
硬盘以 hd 表示,后面会接一组数字;
以『搜寻顺序』做为硬盘的编号,而不是依照硬盘排线的排序!(这个重要!)
第一个搜寻到的硬盘为 0 号,第二个为 1 号,以此类推;
每颗硬盘的第一个 partition 代号为 0 ,依序类推。

所以说,第一颗『搜寻到的硬盘』代号为:『(hd0)』,而该颗硬盘的第一号分割槽为『(hd0,0)』,这样说了解了吧? 反正你要记得,在 grub 里面,他开始的数字是 0 而不是 1 就是了!

所以说,整个硬盘代号为:

硬盘搜寻顺序 在 Grub 当中的代号
第一颗 (hd0) (hd0,0) (hd0,1) (hd0,4)....
第二颗 (hd1) (hd1,0) (hd1,1) (hd1,4)....
第三颗 (hd2) (hd2,0) (hd2,1) (hd2,4)....

这样应该比较好看出来了吧?第一颗硬盘的 MBR 安装处的硬盘代号就是『(hd0)』, 而第一颗硬盘的第一个分割槽的 boot sector 代号就是『(hd0,0)』第一颗硬盘的第一个逻辑分割槽的 boot sector 代号为『(hd0,4)』了了吧!

/boot/grub/menu.lst 配置档:

了解了 grub 当中最麻烦的硬盘代号后,接下来,我们就可以瞧一瞧配置档的内容了。先看一下鸟哥的 CentOS 内的 /boot/grub/menu.lst 好了:

[root@www ~]# vim /boot/grub/menu.lst
default=0     <==默认启动选项,使用第 1 个启动菜单 (title)
timeout=5     <==若 5 秒内未动键盘,使用默认菜单启动
splashimage=(hd0,0)/grub/splash.xpm.gz <==背景图示所在的文件
hiddenmenu    <==读秒期间是否显示出完整的菜单画面(默认隐藏)
title CentOS (2.6.18-92.el5)    <==第一个菜单的内容
        root (hd0,0)
        kernel /vmlinuz-2.6.18-92.el5 ro root=LABEL=/1 rhgb quiet
        initrd /initrd-2.6.18-92.el5.img


在 title 以前的四行,都是属於 grub 的整体配置,包括默认的等待时间与默认的启动项目, 还有显示的画面特性等等。至於 title 后面才是指定启动的核心文件或者是 boot loader 控制权。 在整体配置方面的项目主要常见的有:

default=0
这个必须要与 title 作为对照,在配置档里面有几个 title ,启动的时候就会有几个菜单可以选择。 由於 grub 启始号码为 0 号,因此 default=0 代表使用『第一个 title 项目』来启动的意思。 default 的意思是,如果在读秒时间结束前都没有动到键盘, grub 默认使用此 title 项目 (在此为 0 号) 来启动。

timeout=5
启动时会进行读秒,如果在 5 秒钟内没有按下任何按键,就会使用上面提到的 default 后面接的那个 title 项目来启动的意思。如果你觉得 5 秒太短,那可以将这个数值调大 (例如 30 秒) 即可。此外,如果 timeout=0 代表直接使用 default 值进行启动而不读秒,timeout=-1 则代表直接进入菜单不读秒了!

splashimage=(hd0,0)/grub/splash.xpm.gz
有没有发现你的 CentOS 在启动的时候背景不是黑白而是有色彩变化的呢?那就是这个文件提供的背景图示啦(注3)!不过这个文件的实际路径写法怎么会是这样啊?很简单啊~上述的意思是:在 (hd0,0) 这个分割槽内的最顶层目录中,底下的 grub/splash.xpm.gz 那个文件的意思。 由於鸟哥将 /boot 这个目录独立成为 /dev/hda1 ,因此这边就会写成『在 /dev/hda1 里面的 grub/splash.xpm.gz 』的意思啦!想一想,如果你的 /boot 目录并没有独立成为一个分割槽, 这里会写成如何?

hiddenmenu
这个说的是,启动时是否要显示菜单?目前 CentOS 默认是不要显示菜单, 如果您想要显示菜单,那就将这个配置值注解掉!
整体配置的地方大概是这样,而底下那个 title 则是显示启动的配置项目。如同前一小节提到的,启动时可以选择 (1)直接指定核心文件启动或 (2)将 boot loader 控制权转移到下个 loader (此过程称为 chain-loader)。每个 title 后面接的是『该启动项目名称的显示』,亦即是在菜单出现时,菜单上面的名称而已。 那么这两种方式的配置有啥不同呢?

直接指定核心启动

既然要指定核心启动,所以当然要找到核心文件啦!此外,有可能还需要用到 initrd 的 RAM Disk 配置档。但是如前说的, 尚未启动完成,所以我们必须要以 grub 的硬盘识别方式找出完整的 kernel 与 initrd 档名才行。 因此,我们可能需要有底下的方式来配置才行!


1. 先指定核心文件放置的 partition,再读取文件 (目录树),
   最后才加入文件的实际档名与路径 (kernel 与 initrd);
   鸟哥的 /boot 为 /dev/hda1 ,因此核心文件的配置则成为:
root    (hd0,0)          <==代表核心文件放在那个 partition 当中
kernel  /vmlinuz-2.6.18-92.el5 ro root=LABEL=/1 rhgb quiet
initrd  /initrd-2.6.18-92.el5.img


上面的 root, kernel, initrd 后面接的参数的意义说明如下:

root :代表的是『核心文件放置的那个 partition 而不是根目录』喔!不要搞错了! 以鸟哥的案例来说,我的根目录为 /dev/hda2 而 /boot 独立为 /dev/hda1 ,因为与 /boot 有关, 所以磁碟代号就会成为 (hd0,0) 罗。

kernel :至於 kernel 后面接的则是核心的档名,而在档名后面接的则是核心的参数。 由於启动过程中需要挂载根目录,因此 kernel 后面接的那个 root=LABEL=/1 指的是『Linux 的根目录在哪个 partition 』的意思。 还记得第八章谈过的 LABEL 挂载功能吧? 是的,这里使用 LABEL 来挂载根目录。至於 rhgb 为色彩显示而 quiet 则是安静模式 (萤幕不会输出核心侦测的资讯)。

initrd :就是前面提到的 initrd 制作出 RAM Disk 的文件档名啦!

2. 直接指定 partition 与档名,不需要额外指定核心文件所在装置代号
kernel  (hd0,0)/vmlinuz-2.6.18-92.el5 ro root=LABEL=/1 rhgb quiet
initrd  (hd0,0)/initrd-2.6.18-92.el5.img


老实说,鸟哥比较喜欢这种样式的档名写法,因为这样我们就能够知道核心文件是在哪个装置内的某个档名, 而不会去想到我们的根目录 (/, root) 啦!让我们来想想 /boot 有独立分割与无独立分割的情况吧!

initrd 的重要性与创建新 initrd 文件

我们在本章稍早之前『 boot loader 与 kernel 加载』的地方已经提到过 initrd 这玩意儿,他的目的在於提供启动过程中所需要的最重要核心模块,以让系统启动过程可以顺利完成。 会需要 initrd 的原因,是因为核心模块放置於 /lib/modules/$(uname -r)/kernel/ 当中, 这些模块必须要根目录 (/) 被挂载时才能够被读取。但是如果核心本身不具备磁碟的驱动程序时, 当然无法挂载根目录,也就没有办法取得驱动程序,因此造成两难的地步。

initrd 可以将 /lib/modules/.... 内的『启动过程当中一定需要的模块』包成一个文件 (档名就是 initrd), 然后在启动时透过主机的 INT 13 硬件功能将该文件读出来解压缩,并且 initrd 在内存内会模拟成为根目录, 由於此虚拟文件系统 (Initial RAM Disk) 主要包含磁碟与文件系统的模块,因此我们的核心最后就能够认识实际的磁碟, 那就能够进行实际根目录的挂载啦!所以说:『initrd 内所包含的模块大多是与启动过程有关,而主要以文件系统及硬盘模块 (如 usb, SCSI 等) 为主』的啦!

一般来说,需要 initrd 的时刻为:

根目录所在磁碟为 SATA、U盘 或 SCSI 等连接介面;
根目录所在文件系统为 LVM, RAID 等特殊格式;
根目录所在文件系统为非传统 Linux 认识的文件系统时;
其他必须要在核心加载时提供的模块。

一般来说,各 distribution 提供的核心都会附上 initrd 文件,但如果你有特殊需要所以想重制 initrd 文件的话, 可以使用 mkinitrd 来处理的。这个文件的处理方式很简单, man mkinitrd 就知道了! ^_^。 我们还是简单的介绍一下去!

[root@www ~]# mkinitrd [-v] [--with=模块名称] initrd档名 核心版本
选项与参数:
-v  :显示 mkinitrd 的运行过程
--with=模块名称:模块名称指的是模块的名字而已,不需要填写档名。举例来说,
       目前核心版本的 ext3 文件系统模块为底下的档名:
       /lib/modules/$(uname -r)/kernel/fs/ext3/ext3.ko
       那你应该要写成: --with=ext3 就好了 (省略 .ko)
initrd档名:你所要创建的 initrd 档名,尽量取有意义又好记的名字。
核心版本  :某一个核心的版本,如果是目前的核心则是『 $(uname -r) 』

范例一:以 mkinitrd 的默认功能创建一个 initrd 虚拟磁碟文件
[root@www ~]# mkinitrd -v initrd_$(uname -r) $(uname -r)
Creating initramfs
Looking for deps of module ehci-hcd
Looking for deps of module ohci-hcd
....(中间省略)....
Adding module ehci-hcd  <==最终加入 initrd 的就是底下的模块
Adding module ohci-hcd
Adding module uhci-hcd
Adding module jbd
Adding module ext3
Adding module scsi_mod
Adding module sd_mod
Adding module libata
Adding module pata_sis

[root@www ~]# ll initrd_*
-rw------- 1 root root 2406443 Apr 30 02:55 initrd_2.6.18-92.el5
# 由於目前的核心版本可使用 uname -r 取得,因此鸟哥使用较简单的命令来处理罗~
# 此时 initrd 会被创建起来,你可以将他移动到 /boot 等待使用。

范例二:添加 8139too 这个模块的 initrd 文件
[root@www ~]# mkinitrd -v --with=8139too initrd_vbirdtest $(uname -r)
....(前面省略)....
Adding module mii
Adding module 8139too  <==看到没!这样就加入了!


initrd 创建完成之后,同时核心也处理完毕后,我们就可以使用 grub 来创建菜单了!底下继续瞧一瞧吧!

转自:http://vbird.dic.ksu.edu.tw/linux_basic/0510osloader_3.php
分享到:
评论
发表评论

文章已被作者锁定,不允许评论。

相关推荐

    grub4dos-V0.4.6a-2017-02-04更新

    3.two variables boot_drive and install_partition can be preset to a value before transferring control to grub4dos. (tinybit) 4.修正屏蔽 map 信息。(yaya) 2014-10-09(yaya) 1.屏蔽 map 信息。 2014...

    Linux系统加载过程

    MBR通常位于硬盘的第一个扇区(通常是第0号扇区),它包含了引导加载程序(Boot Loader)的代码以及磁盘分区表信息。 - **步骤四:** MBR中的引导加载程序(Boot Loader)负责加载操作系统的核心部分。常见的Boot Loader...

    嵌入式 BootLoaders

    U-Boot 由 PPCboot 演变而来,支持数十种 PowerPC 设备。 通过上述分析可以看出,不同架构下 Bootloader 的选择和使用有着明显的差异。在选择合适的 Bootloader 时,开发者需要考虑目标硬件的具体需求、操作系统的...

    xinhua_3.zip

    一、简单介绍 RHEL 开机时的先后顺序 二、BIOS 初始化时主要的三个任务 三、介绍 Boot Loader 中的主要工作 四、介绍 GRUB 和 和 grub.conf 这个配置文件的内容 五、介绍 Kernel 初始化时所做的工作 六、介绍 init ...

    微处理器系统结构与嵌入式系统第十一章PPT学习教案.pptx

    第二阶段(Stage2)则多用C语言实现,进行更复杂的硬件初始化、内存检测、内核和文件系统镜像的加载,以及设置内核启动参数。 在具体的微处理器系统中,比如三星的S3C2440,可以通过OM[1:0]引脚设置启动方式,支持从...

    Linux-startup-process.rar_linux_linux 启动_linux 培训_linux内核_startu

    引导装载程序(Boot Loader)如GRUB(Grand Unified Bootloader)是Linux启动的关键部分。BIOS从硬盘的主引导记录(MBR)加载GRUB。GRUB提供了一个交互式的菜单,允许用户选择要启动的操作系统或内核版本。 三、...

    \Linux一句话精彩回答.pdf

    - **命令**: `sudo systemd-boot-update --boot-loader=grub --boot-mode=uefi --timeout=1` - **描述**: 调整GRUB引导装载器的超时时间可以加快查看开机硬件检测的速度。上述命令将GRUB的等待时间设置为1秒。 ### ...

    自己动手写操作系统(含源代码).part2

     本书从只有二十行的引导扇区代码出发,一步一步地向读者呈现一个操作系统框架的完成过程。书中不仅关注代码本身,同时关注完成这些代码的思路和过程。本书不同于其他的理论型书籍,而是提供给读者一个动手实践的...

    自己动手写操作系统(含源代码).part1

     本书从只有二十行的引导扇区代码出发,一步一步地向读者呈现一个操作系统框架的完成过程。书中不仅关注代码本身,同时关注完成这些代码的思路和过程。本书不同于其他的理论型书籍,而是提供给读者一个动手实践的...

    H3CNE题库GB-190含详细答案解析

    - 为了指定下次启动时使用的操作系统软件,可以使用`boot-loader`命令,它用于配置引导加载器,如GRUB或LILO。 7. **检测线路MTU**: - 使用`ping`命令的`-f`参数可以检测线路的最大传输单元(MTU),这个参数...

    美化Ubuntu桌面

    **GRUB**(Grand Unified Boot Loader)是GNU/Linux系统中常用的多重启动管理器。在安装了多操作系统的计算机上,GRUB会显示一个菜单让用户选择启动哪个系统。美化GRUB背景可以提升整体体验。 1. **安装Startup ...

    运维人员面试试题.pdf

    2. Linux 内核引导时,从`/boot/grub/grub.cfg`或`/boot/loader/entries/*.conf`(取决于所用的引导加载器)中读取要加载的文件系统信息。 3. 在Linux文件系统中,每个文件用i节点来唯一标识。i节点包含了文件的...

Global site tag (gtag.js) - Google Analytics