GNU GRUB中文手册
修订次数:1
不保证含义准确仅供参考。若发现有谬误之处可发送邮件到:grub2_cn_manual@https://www.wendangku.net/doc/178574886.html,
邮件主题必须以grub2:开始,否则系统不接收。
针对grub版本v1.99 info手册翻译,并且添加插图和注解。
Permission is granted to copy, distribute and/or modify this
document under the terms of the GNU Free Documentation License,
Version 1.2 or any later version published by the Free Software
Foundation; with no Invariant Sections.
译者:三寸断梁
1 grub前言
搭建GRUB2 LINUX实验环境。由于GRUB是启动加载器,因此你修改配置文件后需要重启电脑才能看到改变,为了避免反复重启。在这里推荐使用VirtualBox虚拟机。
本人实验配置是:Fedora 16-i386-DVD完全安装,VirtualBox 4.2.2 for linux。Grub 1.99。syslinux 4.05 ,你的linux主机应该安装有grub2。下文所述,在我的机器3个镜像成功加载。
1.准备虚拟机。如果你发现鼠标消失了,按下右ctrl。
? ? 从https://https://www.wendangku.net/doc/178574886.html,/wiki/Linux_Downloads下载VirtualBox 4.2.2。我选择的是All distributions。80M左右的体积。
新建一个虚拟机,操作简单直接下一步下一步。设置为使用128M内存,使用虚拟硬盘文
件,512M硬盘。显存23M。不要启动虚拟机,完成下面的步骤。
2.准备memdisk
? ? ? 使用syslinux是因为实验中的实例需要memdisk,它是包括在syslinux中的。可以用来
加载一些Win下的img镜像,比如:Ghost82.img MaxDOS.img读者可到网下载这
两个文件。
从ftp://https://www.wendangku.net/doc/178574886.html,/pub/linux/utils/boot/syslinux/下载syslinux-4.05.tar.gz它是
syslinux源代码。新版本syslinux中的memdisk能自动计算镜像文件的c h s参数。解压
源代码到某个路径例如主目录~
编译memdisk(我们只需要memdisk)。编译需要nasm编译器,执行如下命令:cd ~/syslinux-4.05/memdisk
make
1
它会生成名为memdisk的文件。这个文件可以在GRUB2中使用linux16加载。
3.准备用来创建光盘镜像的iso目录
? ? mkdir -p ~/iso/boot/grub{,2}
在~/iso/boot/grub下建立配置文件grub.cfg内容如下:
set root="(cd)"
menuentry 'Ghost82.img' {
linux16 /boot/memdisk
initrd16 /Ghost82.img
}
menuentry 'MaxDos.img' {
linux16 /boot/memdisk
initrd16 /MaxDOS.img
}
menuentry 'win7pe-cn.iso' {
linux16 /boot/memdisk iso
initrd16 /Win7PE-CN.iso
#你需要自己准备一个Win iso,使用memdisk在虚拟机中加载ISO需要等待较长时间。而且需要大量内
存。我们最初设置的128M不够用。所以正文没有提及。
}
set timeout=-1
?复制Ghost82.img MaxDOS.img到~/iso;复制~/syslinux-4.05/memdisk/memdisk到~/iso/boot/;复制所有GRUB2模块到~/iso/boot/grub2。GRUB2模块在i386
/usr/lib/grub2/i386-pc/。
4.创建grub.iso,这个文件将用虚拟机加载。
?在主目录下执行命令:grub2-mkrescue -o grub.iso iso
应该在:
因为当前处在主目录下,命令中的iso就指向~/iso目录。创建的grub.iso光盘,包含:
~/iso/*下的所有文件,并且包含有GUB2启动区块。这个iso可以写入CD。如果希望写入U 盘需要使用grub2-install命令。
5.在虚拟机的镜像列表中添加grub.iso,然后启动虚拟机。
当你修改了iso/boot/grub/grub.cfg配置文件,重新执行第四步,然后重启虚拟机就看以看到
改变。
2
如果你没有出错且幸运的话,虚拟机应该能够得到图。尝试前两个选项,她们应该能够正确运行。
1.1概论
简而言之:grub是一个引导加载器,即计算机系统启动时第一个运行的程序。它是为了加载操作系统和
转移控制权给操作系统内核。内核再继续启动完整的操作系统。
GNU GRUB是一个非常强大的引导加载器,它可以加载种类繁多的操作系统。还支持链式加载"chain- loading"。
GRUB最大的特性就是可扩展性。GRUB支持文件系统和内核可执行格式,因此你可以用很多方式加载
你的OS,而不用记录下OS在磁盘的物理地址。比如使用分区名,路径和文件名指定文件。
当GRUB加载系统时,可以使用命令行交互模式,也可以使用菜单选择模式。使用命令行模式你需要指
定内核的文件名和分区名。在菜单模式下,你只需要移动箭头来选择一个菜单然后按下enter。菜单使用
一个配置文件来说明。
1.2 GRUB的历史
略
1.3与以前版本的不同点
GRUB2是重写GRUB后的升级版本。二者有很多相同的特性。但是也有很多地方发生了改变。
1.新的配置文件名:/boot/grub/grub.cfg而不是/boot/grub/menu.lst or grub.conf ,配置文件有新
的语法。因此不能直接使用grub1的配置文件。
2. grub.cfg由grub2-mkconfig命令产生。它方便升级内核版本。
3.分区编号从1开始,而不是0.
3
4.配置文件现在是一个完整的脚本语言,它支持:变量,条件,循环。
5. save_env和load_env支持对启动状态的本地保存。
6. GRUB2拥有更加聪明的算法用来找寻它所需要的文件。使用search命令你可以通过卷标或者
UUID来选择磁盘。
7. GRUB2支持多找其他类型的系统:PC EFI,PC coreboot,PowerPC,SPARC,MIPS ..
8.支持多种文件系统,不仅仅限于:ext4,HFS+,NTFS
9. GRUB2可以直接从LVM和RAID中读取文件。
10.支持图形终端和菜单系统。
11. GRUB2交互界面可以被翻译,包括菜单项的名字。
12.镜像文件,发生变化。
13. GRUB2有动态加载的模块可用于支持更多的文件系统和其他功能。
2加载器的作用
引用自Gordon Matzigkeit,GRUB爱好者:
大多数人在谈论电脑的时候总是讨论操作系统和内核。因此她们总是说"GNU/linux" 或者"GNU/Hurd" 。
其他多数人认为内核是系统中最重要的部分,因此他们把GNU OS 称作Linux 系统。
我个人认为那种看法是非常片面的,因为启动加载器才是所有软件最重要的。我过去常常把以上的系统称
1
作:"LILO" 和GRUB 系统
可惜的是没人支持我的见解,因此我现在只用GNU 指代GRUB。
因此如果你听到有人说GNU 系统,那你一定要想到那其实是围绕这GRUB 展开的。
作为GRUB的维护者,我们并不支持Gordon这种程度的发烧友。但是他的话可以帮助理解GRUB的
作用。
2.1命名规范
GRUB为用的设备语法相对与以前发生了重要变化。
(fd0)
首先GRUB需要设备名称被扩在圆括号内,fd表示软盘,数字0表示编号为0的设备(第一个软盘设备),编号从零开始计数。
(hd0,msdos2)
hd意思是硬盘,数字0代表设备号,意味着是第一块硬盘。Msdos指出了分区类型,数字2代表分区编号。分区编号从1开始计数,而不是0。因此面的代码指定了第一个硬盘的第二个分区为msdos格式。当你选择了分区时GRUB会尝试解析文件系统,并从分区中读取资料。
LILO ,LInux LOader ,一个很多人使用但是很少有人喜欢的加载器。
1
4
(hd0,msdos5)
这指定了第一个硬盘的第一个扩展分区。由于主分区最多为4,所以扩展分区从5开始编号。
(hd1,msdos1,bsd1)
第2块硬盘的第一个BSD slice(BSD使用slice管理磁盘,概念类似于主分区)。
想让GRUB真实的访问磁盘和分区,你需要在命令行中按照述语法指定分区。例如:
set root=(fd0)
parttool (hd0,msdos3) hidden-
如果你不知道磁盘中的分区方法,可以使用grub的补全功能。只输入
set root=(
然后按下tab键,GRUB会自动显示设备列表,分区名,文件名。
注意GRUB不从SCSI识别IDE,它简单的从0开始给设备编号,而忽略设备类型。同差IDE设备的编
号小于SCSI设备。如果你在BIOS中改变了IDE和SCSI的引导顺序,那编号大小就说不准了。
现在考虑一个问题,如何指定一个文件
(hd0,msdos1)/vmlinuz
它在指定分区指定文件vmlinuz。依次类推,可以指定任意路径。
3安装GRUB
在类unix系统中安装GRUB请在root权限调用grub2-install程序。
命令参数比较简单,只需要指定目标磁盘设备文件名。
# grub2-install /dev/hda
在GNU/hurd系统下使用这个命令
# grub2-install /dev/hd0
面的两个命令会把GRUB镜像放置到/boot文件夹。如果你希望它把文件放到其他文件夹需要指定
--boot-directory参数。这里有个创造软盘启动的实例。
# mke2fs /dev/fd0
# mount -t ext2 /dev/fd0 /mnt
# mkdir /mnt/boot
# grub2-install --boot-directory=/mnt/boot /dev/fd0
# umount /mnt
有些BIOS在使用USB设备的第一个分区作为软盘时有bug。此时把USB设备当作硬盘来启动。俗称:USB-FDD启动。这种情况下你需要这样安装GRUB。:
# losetup /dev/loop0 /dev/sdb1
# mount /dev/loop0 /mnt/usb
# grub2-install --boot-directory=/mnt/usb/bugbios --force --allow-floppy /dev/loop0
这个安装方法不和标准方法冲突。因为她们被安装到其他文件夹里。
目前grub2-install只是一个shell脚本。脚本调用了grub2-mkimage和grub2-setup。你也可以直接使
用这两个命令。不建议这样做,非常熟悉grub者除外。安装引导加载器到正在运行的OS中可能导致严
重错误。
5
3.1创建GRUB引导的CD-ROM
GRUB支持El Torito 1非仿真模式。这也意味着你可以直接从cd-rom中使用GRUB启动,而不需要创
建启动软盘和硬盘镜像(它们可能导致启动失败)。
CD-ROM启动GRUB使用一个称作cdboot.img的镜像。此镜像被core.img包含。core.img镜像也必须包含iso9660和biosdisk模块。CD-ROM启动也需要包含grub.cfg和相关grub模块。
创建一个简单通用的GRUB救援光盘,你需要使用grub2-mkrescue程序:
# grub2-mkrescue -o grub.iso
你还需要在iso中包括其他的有用的文件。只需要在iso文件夹内放置你需要的文件即可。
# mkdir iso
# mkdir -p iso/boot/grub
你也许需要在boot/grub文件下包含grub.cfg用来提供启动菜单。把其他所有你需要的文件复制到iso文
件里面,你可以随意创建目录结构。
最后使用命令:
# grub2-mkrescue -o grub.iso iso
它会产生名为grub.iso的文件。它可以直接刻录到CD或者DVD光碟内。
根设备在进入grub.cfg之前自动设置,你可以在grub.cfg脚本中直接引用文件的路径,不需要指定设备名。自动设置root设备,可以工作在光驱和USB储存设备。
实际很多盗版系统光碟的启动菜单就是使用grub的。
El Torito 是可引导CD 的技术标准,它用于BIOS。
3.2映射BIOS设备和OS设备
grub2-mkdevicemap 程序用来创建设备映射文件。它通常由某些工具在没有找到设备映射文件时自动
调用,例如grub2-install。默认设备映射文件在/boot/grub2/device.map
如果设备映射文件存在,GRUB 工具集读取它并且映射BIOS 驱动器到OS 设备。这个文件内容如下:# this device map was generated by anaconda
#DEVICE FILE
(hd0) /dev/sda
(hd0,3) /dev/sda3
DEVICE是grub语法表示的磁盘设备,FILE是操作系统的设备文件。
映射文件的作用是:GRUB在配置文件中使用的设备名指代的设备(hd0)是根据BIOS的设备号得到的。如果BIOS设置变化而发生变化。如果你在BIOS中交换了IDE和SCSI设备的启动顺序GRUB会得到错误的设备号。
不幸的是此时OS设备名也不恒定。多启动的情况下:不同的Linux内核可能使用不同的顺序加载设备
驱动以及使用不同的设备名(/dev/hd*和/dev/sd*)。因此你可能需要频繁的更新设备映射文件。
1所有的启动光盘都遵循El Torito 这种格式,这是启动光盘的国际标准。
6
GRUB为了避免这个问题,在grub.cfg文件使用UUID或者文件系统卷标来指定分区。我们建议你自
己手写的grub.cfg也使用UUID或者卷标。如果设备映射文件不存在,grub工具集会设想一个临时的
映射文件。在单磁盘系统中它工作良好。
自动产生的设备映射文件也不总是合适的,某些情况下需要设备映射文件。如果grub2-mkdevicemap
命令产生错误,你可以手动建立映射文件。在映射文件中#开始的行被作为注释。
3.3 BIOS安装
3.3.1 MBR
在PC BIOS平台,使用的分区表格式通常称作MBR格式(主引导记录)。这个格式最多允许4个主
分区,和若干逻辑分区。在这种格式下有两种方法安装GRUB:
1.嵌入到MBR和第一个分区中,这个可嵌入区域它有多个名字:MBR,引导区,嵌入区它至少
要有31KiB的容量。
2. grub核心镜像可以被安装到文件系统中,GRUB启动程序被写入到第一个磁盘的第一个区块中。
这两个方法都有缺点。没有办法在尽量安全时在嵌入区域中保留空间。并且已知某些软件会使用这个区
域保留版权信息。磁盘在分区的时也可能在第一个分区前面没有保留足够的空间。另一方面,安装到文
件系统里意味着GRUB很脆弱。因为某些文件系统存在tail paking特性,会导致GRUB的区块发生移
动,导致MBR内的GRUB加载器无法找到GRUB核心镜像。使用这种方法,最好是/boot目录和
BIOS引导的设备是同一个磁盘。GRUB不用去猜测设备号。
GRUB开发者建议在第一个分区前嵌入GRUB。除非你有特殊需求。你必须保证第一个分区前存在至少
31KiB(63区块)的空间。在现代的磁盘中空间不再吃紧,因此最好分区时在第一个分区前保留1MiB
的空间。
3.3.2 GPT
一些新的系统使用GUID分区表(GPT)格式。这是EFI的一个特殊部分,如果你的软件支持,GPT
也可以在BIOS中使用。例如:GRUB和GNU/linux可以用在这种情况。在GPT格式下可以为
GRUB准备单独的分区,被称作BIOS引导分区。GRUB可以被嵌入到那个专用分区中,从而避免被其
他软件意外覆盖和文件系统导致的区块移动。
在GPT创建引导分区时,你需要确认分区至少有31KiB。GPT格式的磁盘通常不应该有这么小容量
的分区,所以我们建议你的引导分区容量大一点,比如1MiB,用来提供GRUB可能的扩展。你必须确
定boot分区有合适的类型。使用GNU parted程序:
# parted /dev/DISK set PARTITION-NUMBER bios_grub on
如果你使用gdisk程序,请将分区类型设置为:0xEF02。
警告:对将要操作的分区要多加小心!当GRUB在安装时使用了BIOS引导分区时,它会自动格式化整
个引导分区,并且把GRUB安装进去。请保证分区内不包含其他数据。
7
4引导过程
GRUB可以用恰当的方式加载多重引导1兼容内核(Multiboot-compliant kernel)。但是对于某些特殊OS,你需要使用特殊的方式。
4.1 OS如何引导
GRUB有两种引导方法。第一个是直接加载OS。另一个使用链式加载(chain-load),它可以加载其他的引导加载器。通常而言,GRUB有足够的能力从任何一块磁盘的任意分区加载OS。但对于某些操作系统必须使用OS自身的加载器(最常见的是windows xp)。
4.1.1如何直接引导OS
多重引导是GRUB天生的功能。它支持:Linux FreeBSD NetBSD OpenBSD。如果你希望加载其他
操作系统你需要使用链式加载。
对于DOS和Windows有一些特殊缘故,你需要特殊方法才能成功引导,这种情况称作系统特异性2。参见下文。
4.1.2链式加载OS
OS不支持多重启动,或者GRUB不能直接引导它时,你就需要使用chain-load链式加载。它用来调用OS自带的加载器。
chainloader命令用来运行链式加载。它通常需要某些GRUB模块,并且正确设置根设备(root)。你可以把这些指令放到一个菜单项里面。
menuentry "Windows" {
insmod chain
insmod ntfs
set root=(hd0,1)
chainloader +1
}
如果你有多个硬盘,你可能需要使用更多的命令设置更多东西。
链式加载只支持PC BIOS系统和EFI平台。
1 2
8 多重引导,也称作多启动。
系统特异性,不同的操作系统使用不同的引导方法,称作系统特异性。
4.2特异性加载可能出现的问题
4.2.1 GNU/Hurd
GNU/Hurd是多重引导兼容的,因此很容易加载它。但是别忘了在引导之前需要正确设置根设备为内核
所在分区。
1.设置GRUB根设备到GNU/Hurd的某个分区。search --file --set /boot/gnumach.gz命令很有
用。它会自动搜索/boot/gnumach.gz文件,并把存在此文件的分区设置为根设备。
2.加载内核和内核模块:
grub> multiboot /boot/gnumach.gz root=device:hd0s1
grub> module /hurd/ext2fs.static ext2fs --readonly \
--multiboot-command-line='${kernel-command-line}' \
--host-priv-port='${host-port}' \
--device-master-port='${device-port}' \
--exec-server-task='${exec-task}' -T typed '${root}' \
'$(task-create)' '$(task-resume)'
grub> module /lib/ld.so.1 exec /hurd/exec '$(exec-task=task-create)'
3.执行boot指令
4.2.2 GNU/Linux
用GRUB引导linux相对比较容易。因为它也是多重引导兼容的OS。
1.设置根设备到包含Linux内核的分区。search --file --set /boot/vmlinuz对你有用。
2.使用linux命令加载内核:
grub> linux /vmlinuz root=/dev/sda1
linux命令用来加载linux内核,并且设置根分区1。/vmlinuz用来在根设备中指定文件。
如果你希望添加内核参数直接把参数写到命令后面:
grub> linux /vmlinuz root=/dev/sda1 acpi=off
得到所有可用的内核参数,你需要查看内核源代码树。
3.如果你使用initrd 2还需要执行initrd命令。
grub> initrd /initrd
如果你使用linux16,你需要使用initrd16命令
grub> initrd16 /initrd
4.最后运行boot命令。
警告:如果你使用initrd指令,并且使用了mem=内核参数设置了小于实际的内存容量。你需要在
GRUB中设置相同的数值。在载入linux内核前,使用uppermem命令指定内存容量。
1 2 根分区和根设备不是一个含义,根分区是指文件系统根目录所在的分区。根设备是指GRUB 加载OS 内核时。一个名为root 的选项值,它指向内核所在分区的设备名。set root=(hd0,1)
Linux初始RAM磁盘(initrd)是在系统引导过程中挂载的一个临时根文件系统,用来支持两阶段
的引导过程。initrd文件中包含了各种可执行程序和驱动程序,它们可以用来挂载实际的根文件系统,然
后再将这个initrd RAM磁盘卸载,并释放内存。在很多嵌入式Linux系统中,initrd就是最终的根文
件系统。
9
4.2.3 DOS/Windows
GRUB不能直接引导DOS和WINDOWS。你必须使用chainloader命令。这是由于DOS和Win- dows内置加载器有严重缺陷。导致这些OS不能从非第一块硬盘里启动。如果你把DOS或者WIN安装到非第一块硬盘,你需要使用磁盘交换技术。drivemap命令。
drivemap -s (hd0) (hd1)
这个命令对你的第一和第二块硬盘执行了虚拟交换。
警告:虚拟交换只在OS使用BIOS访问磁盘时有效。如果它们使用自己的驱动程序访问磁盘则虚拟交
换不影响OS。
如果你安装了很多DOS/win到同一个磁盘里也可能发生问题。因为如果磁盘里有多个主分区,它们可能
会混淆。你应该避免安装多份DOS/win到同一个磁盘里。如果你确实遇到这种情况GRUB也提供了解
决办法。使用分区隐藏技术。
GRUB隐藏一个DOS/win分区时,DOS/win会忽略哪个分区。当GRUB取消隐藏某个DOS/win分区时,DOS/win OS会识别哪个分区。假设你安装了win在第一个硬盘的第一个分区和第二个分区你希
望加载第1个分区内的OS,执行如下命令:
parttool (hd0,1) hidden-
parttool (hd0,2) hidden+
set root=(hd0,1)
chainloader +1
parttool ${root} boot+
boot
5编写配置文件
5.1简单的配置文件
grub2-mkconfig用来产生grub.cfg文件。它可以用来升级你的配置文件,它可以自动检测可用的内核,并且产生对应的菜单项。
grub2-mkconfig有一些限制。当你希望在菜单项列表后面添加新的项目时你应该修改/etc/grub.d/
40_custom文件,或者创建/boot/grub2/custom.cfg文件。修改菜单项的顺序,需要修改/etc/grub.d/内的文件的前缀的数字。与/etc/init.d下面的脚本类似。数字决定运行的顺序,数字小的出现在前面。
[root@localhost] 0 /etc/grub.d # ll
总用量48
-rwxr-xr-x. 1 root root 6709 5月7 21:50 00_header
-rwxr-xr-x. 1 root root 5959 5月7 21:50 10_linux
-rwxr-xr-x. 1 root root 5875 5月7 21:50 20_linux_xen
-rwxr-xr-x. 1 root root 5963 5月7 21:50 30_os-prober
-rwxr-xr-x. 1 root root 214 5月7 21:50 40_custom
-rwxr-xr-x. 1 root root 95 5月7 21:50 41_custom
-rwxr-xr-x. 1 root root 1259 5月7 21:50 90_persistent
-rw-r--r--. 1 root root 483 5月7 21:50 README
/etc/grub.d/下面的文件都是shell脚本。使用脚本机制是为了普通用户能够简单的管理菜单项。如果你能
够自己写grub.cfg那么你可以不使用grub2-mkconfig.
10
文件/etc/default/grub控制grub2-mkconfig的行为。它也是shell脚本,所以应该使用POSIX shell
语法。通常,文件内只是定义了一系列的shell变量:
[root@localhost] 0 /etc/grub.d # cat /etc/default/grub
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR="Fedora"
GRUB_DEFAULT=saved
GRUB_CMDLINE_LINUX="rd.md=0 rd.lvm=0 rd.dm=0 KEYTABLE=us quiet rhgb
LANG=zh_CN.UTF-8 rd.luks=0"
可用的变量为:
GRUB_DEFAULT
默认菜单项的编号或者标题。编号从0开始。变量值为saved有特殊含义。当菜单启动时,光标会定位
到变量所指定的菜单项中。当输入等待超时时,自动进入所指定的菜单项。
实例:
假设你有一个菜单项:
menuentry 'Example GNU/Linux distribution' --class gnu-linux {
...
}
使用这个命令设置为默认:
GRUB_DEFAULT='Example GNU/Linux distribution'
GRUB_DEFAULT值为saved,那么默认菜单项为GRUB_SAVEDEFAULT和grub2-set-default或者
grub2-reboot。
默认值为0
可用的变量:
GRUB_SAVEDEFAULT
如果此选项值为"true" ,且GRUB_DEFAULT ="saved"时,那么手动进入一个菜单项后自动把它设置为下
一次启动时的默认菜单项。
GRUB_DEFAULT ="saved"命令不一定必须GRUB_SAVEDEFAULT="true"。也可以和grub2-set-
default或者grub2-reboot命令连用。
GRUB_TIMEOUT
值为一个数值,表示时间秒。显示菜单后,等待键盘输入。如果指定时间内没有键盘操作,那么自动加载
GRUB_DEFAULT变量所指定的菜单项。默认是5。如果值为0那么直接加载默认菜单项而不显示菜单。
如果为-1那么永远等待输入,不自动加载。
GRUB_HIDDEN_TIMEOUT
值为一个数值,表示时间秒。在显示菜单之前等待键盘输入,如果指定时间内没有键盘操作,那么自动加载
GRUB_DEFAULT变量所指定的菜单项。无默认值。
GRUB_HIDDEN_TIMEOUT_QUIET
与GRUB_HIDDEN_TIMEOUT连用。如果设置为"true"那么不显示倒计时。无默认值。
`GRUB_DEFAULT_BUTTON'
`GRUB_TIMEOUT_BUTTON'
`GRUB_HIDDEN_TIMEOUT_BUTTON'
`GRUB_BUTTON_CMOS_ADDRESS'
11
与没有_BUTTON后缀的变量对应,用来支持电源键。
`GRUB_DISTRIBUTOR'
由GRUB的发布者设置,用来鉴别GRUB。
`GRUB_TERMINAL_INPUT'
选择终端输入设备。变量值可以是用空格隔开的多个设备名。可用的名称依赖与你的硬件平台。可用名包括
console (PC BIOS和EFI控制台),serial (串行终端),ofconsole (open firmware控制台),at_keyboard ( PC AT键盘,对Coreboot 1也有用),usb_keyboard (使用HID启动协议的USB键盘)。默认值是当前平台的终端输入设备。
`GRUB_TERMINAL_OUTPUT'
选择输出终端。变量值可以是用空格隔开的多个设备名。可用名包括:console (PC BIOS和EFI控制台),serial (串行终端),gfxterm (图形模式输出),ofconsole (open firmware控制台),ga_text (VGA文本模式输出,对Coreboot有用)。默认值是当前平台的终端输出设备。
GRUB_TERMINAL
如果设置了这个选项,会把`GRUB_TERMINAL_INPUT'和`GRUB_TERMINAL_OUTPUT'设置为相同
值。
`GRUB_SERIAL_COMMAND'
这个命令配置串行终端的端口。
`GRUB_CMDLINE_LINUX'
对于linux内核添加的命令行参数。
`GRUB_CMDLINE_LINUX_DEFAULT'
除非GRUB_DISABLE_RECOVERY设置为true,否则为每个linux内核产生两个菜单项,一个是普通模式,一个是救援模式。在普通模式下linux内核参数会跟`GRUB_CMDLINE_LINUX'的值后再跟
GRUB_CMDLINE_LINUX_DEFAULT的值。
`GRUB_CMDLINE_NETBSD'
`GRUB_CMDLINE_NETBSD_DEFAULT'
类似与GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT,只不过用于NetBSD.
`GRUB_CMDLINE_XEN'
`GRUB_CMDLINE_XEN_DEFAULT'
类似与GRUB_CMDLINE_LINUX GRUB_CMDLINE_LINUX_DEFAULT,只不过用于linux和xen。`GRUB_DISABLE_LINUX_UUID'
通常grub2-mkconfig使用root=UUID=XXX内核参数,用UUID表示根文件系统。如果你希望关闭它设置这个选项值为"true"
`GRUB_DISABLE_RECOVERY'
如果此选项值为"true",那么不自动产生救援模式菜单。
`GRUB_VIDEO_BACKEND'
如果图形卡支持,并且正在使用gfxterm图形终端,或者设置了GRUB_GFXPAYLOAD_LINUX变量。
纳克grub2-mkconfig会加载所有可用的GREB图形驱动,然后使用最合适的那个。如果你希望改变这个行
1Coreboot 是一个以Linux 为基础的开源韧体,它的开发目的在于取代目前市售计算机都会看到的BIOS,而且它可以只在开机时运行特定的程序,从而节省系统资源。
12
为,你可以设置这个变量。在grub2-install执行后,可用的图形驱动名被放置到/boot/grub2/video.ist
`GRUB_GFXMODE'
设置gfxterm图形终端的分辨率。如果你的图形卡支持VBE(VESA BIOS Extensions)你可以使用这个模
式。本地LCD面板分辨率可能无效。默认是640x480
`GRUB_BACKGROUND'
设置gfxterm的背景图片。它的值必须是在GRUB启动时就能够读取到的文件。类型可以是.png .tga .jpg
.jpeg.(需要载入对应的png jpg tga模块)图像会被缩放到匹配屏幕分辨率。
`GRUB_THEME'
设置gfxterm图形终端的主题文件。
`GRUB_GFXPAYLOAD_LINUX'
1.设置为"text",强制linux内核以文本模式启动;
2. "keep"保持图形模式,使用GRUB_GFXMODE , WIDTHxHEIGHT[xDEPTH]的设置孤行模式相关参
数;
3.设置为逗号或者分号分割的列表,用来选择图形模式。
根据你的内核、发行版、你的显卡还有概率性问题,使用这个选项可能导致linux产生很多显示问题,特别
是在引导早期。如果你启动出了问题,请设置为text。
`GRUB_DISABLE_OS_PROBER'
通常grub2-mkconfig会使用外部程序os-prober。这个程序会发现电脑安装的其他系统。并且产生合适
的菜单项。设置此选项值为"true"可以关闭这个选项。
`GRUB_INIT_TUNE'
在GRUB启动时同步的在扬声器播放声音。这对于没有显示器的人有用。选项的值被直接传递到play命
令。
`GRUB_BADRAM'
如果开启了这个选项,GRUB会使用badram命令过滤掉错误的内存区域。
`GRUB_PRELOAD_MODULES'
选项值为用空格分割的一系列GRUB模块名。这些模块会在grub.cfg加载之前加载。
你可以从grub2-mkconfig的输出中看到更多信息。你可以修改/etc/grub.d目录下的脚本,
/etc/grub.d/40_custom通常用来添加某些菜单项。你可以把改动写到/etc/grub.d下的任意的脚本里,通
常使用40_custom来添加某些菜单项,请不要修改这个文件内的头两行。
5.2完整的配置文件
grub.cfg的文件内容使用grub内置的脚本语言。它的语法类似与bash。
单词words
word定义为一个连续的字符集合。一行字符串被元字符分割成若干word。元字符是在脚本中有特殊含
义的符号。元字符包括空格、tab、换行还有:
{ } | & $ ; < >
双引号和单引号扩住的字符串可以包含元字符。
保留字
13
保留字是在GRUB中有特殊含义的word1。以下word被识别为保留字:
! [[ ]] { }
case do done elif else esac fi for function
if in menuentry select then time until while
并不是所有保留字目前都有作用,它们中的某些为未来的扩展而保留。
引号
引号用来移除元字符和保留字的特殊含义,把它们变成普通字符。
有3种引用机制:转义序列,单引号,双引号
未被引号扩住的反斜线\是转义序列,它让下一个字符成为普通字符而不是元字符。它后面也可以直接是换行字符。
单引号字符串,保持在引号内的所有字符都是普通字符,而不是元字符。字符串中出现单引号需要被转义。除了单引号和反斜线自身,单引号字符串内不接受其他的转义序列。
双引号字符串,在字符串内可以使用\转义序列,可以使用$变量扩展。如果需要$ \ "以普通字符出现,需要将她们转义。反斜线紧接着换行,会当作续行符,它在进行语法解析前会从输入流中删除。例如:
line="OK\
_line2"
会产生字符串"OK_line2",续行符只是让脚本格式更好。
变量扩展
美元符号$用来做变量扩展。变量名可以被扩在花括号内,也可以省略。
var="_med_"
pre="P"
suf="S"
echo "$P${var}IL$suf"
输出P_med_ILS,如果你不使用花括号${var}IL,而是使用$varIL,那么系统会扩展搜索名为varIL的变量,
由于这个变量不存在因此会被扩展为空。
位置变量代指名为数字的变量。它们用来代指函数输入参数。例如:$1代表函数第一个参数,$2代表第二个参数,等等。。。
$?用来代指一个命令的退出状态。
$@代指所有的位置变量,扩展成这样:"$1" "$2" "$3" ... ...
$*代指所有的位置变量,扩展成这样:$1 $2 $3 ... ...
$#代指有效的位置变量的总数。
注释
以#开始的word到行尾都被当作是注释,直接被忽略。#出现在字符串里或者被转义时除外。
简单命令
1word被识别为保留字,前提是这个word没有被引号扩住,且出现在脚本语法可以出现保留字的地方比如命令的第一个word,for语句的第3个word。
14
一个简单命令是指一个word序列。其中第一个word被当作命令名,剩下的word被当作这个命令的参
数。分号可以用来在同一行内分割多个命令。
命令返回值是命令的退出状态。如果保留字!出现在命令前,那么对退出状态进行逻辑否运算。
复杂命令
复杂命令是包括选择循环在内的流程控制命令,以及函数和菜单命令。
for NAME in WORD ...; do LIST; done
NAME是任意变量名。WORD是单词的列表。循环会在列表中迭代,每次循环NAME的值为列表中的某
一元素。for语句的退出状态为最后一个执行的命令的退出状态。如果WORD列表为空,那么循环一次也
不执行,退出状态为0.
if if_LIST; then then_LIST; [elif elif_LIST; then el_then_LIST;] ... [else LIST;] fi
if_LIST被作为命令来执行,如果命令退出状态为0(退出状态为0表示成功,不为0表示失败)。那么执行
then_LIST命令,并且跳过其他的elif和else。否则判断elif_LIST条件是否成立如果成立就执行
el_then_LIST,并且跳过其他的elif和else .依次类推如果所有的elif条件都不成立那么执行else LIST。
while COND; do LIST; done
until COND; do LIST; done
while命令,当COND命令退出状态为0时,反复执行LIST,直到COND退出状态不为0。
until命令,当COND命令退出状态不为0时,反复执行LIST,直到COND退出状态为0。
function NAME { COMMAND; ... }
定义名为NAME的函数。花括号内为一系列命令。函数定义命令不影响$?。函数定义之后,函数名就是一
个可用的命令名。退出状态为最后一条命令的退出状态。
menuentry TITLE [`--class=class' ...] [`--users=users'] [`--hotkey=key'] { COMMAND; ... } 用来建立菜单项,参见menuentry。
内建命令
内建命令用来控制脚本流程。
break [n]
从for while until循环中退出。n代表退出层级。n必须>=1。如果n大于循环嵌套层数那么退出所有循环。
break的退出状态为0,如果n小于1那么退出状态非0.
continue [n]
立刻开始下一轮for while until循环,continue n代表跳转到向外第n层循环。n必须>=1。如果n大于循
环嵌套层数。那么重新开始最外层循环。continue退出状态为0,n小于1时退出状态非0.
return [n]
用在函数体内,导致函数退出状态值为n。如果n省略,那么退出状态为函数体内最后一条函数的退出状态。
如果return用在非函数体中,退出状态非0。
shift [n]
n为一非负整数。对于位置变量$1 $2 ... $n $n+1 ... $n+z。执行shift n后,向左移动n位。导致$n+1移
动到$1 ,$n+2 => $2 ... $n+z => $z . n默认值为1.如果n为0,那么不产生任何变化。如果n > $# ($#是
有效的位置变量总数),也不会造成任何变化。如果n > $#或者n<0那么位置退出状态非0,否则退出状
15
态为0。
5.3嵌入配置文件到GRUB
GRUB可以把配置文件嵌入到核心镜像中。这样做可以在normal模式之前加载配置文件。这个功能对
以下情况有用:1无法直接找到外部配置文件;2在加载配置文件时debug。grub2-install在不使用BIOS访问磁盘或者在GRUB被安装到不包含/boot/grub的硬盘中时自动使用嵌入配置文件的功能。在这种情况下你可能需要search命令来自动设置根设备到正确的磁盘。
grub2-mkimage使用-c选项生成嵌入了配置文件的镜像。嵌入配置文件后,外部的配置文件就可以移
动或者删除了。
在执行了内嵌的配置文件后,GRUB加载normal模块,它会读取外部配置文件$prefix/grub.cfg。因此,你必须在嵌入的配置文件中设置正确的根设备。例如设置prefix为(hd0,1)/boot/grub,root设置为(hd0,1)。在大部分情况下,嵌入式配置文件只需要正确设置prefix和root选项。随后由normal模块处理。实例:
search.fs_uuid 01234567-89ab-cdef-0123-456789abcdef root
set prefix=($root)/boot/grub
在这个实例中核心镜像必须包含search_fs_uuid模块才能正确运行。
如果在核心镜像中包含了normal模块和configfile模块。就可以从嵌入式配置文件中加载外部配置文件。使用configfile命令加载外部配置文件,它可以不是/boot/grub/grub.cfg。
实例:
这个实例需要在核心镜像中包含echo search_label test模块
search.fs_label grub root
if [ -e /boot/grub2/example/test1.cfg ]; then
set prefix=($root)/boot/grub
configfile /boot/grub2/example/test1.cfg
else
if [ -e /boot/grub2/example/test2.cfg ]; then
set prefix=($root)/boot/grub
else fi
fi configfile /boot/grub2/example/test2.cfg
echo "Could not find an example configuration file!"
嵌入式配置文件可以不包含菜单定义。使用configfile间接加载其他配置文件。
6主题文件格式
6.1前言
GRUB图形化菜单支持主题,它可以设置启动菜单不同的色彩和排版。主题文件是用纯文本文件说明的GUI组件的排版,它包括引导菜单,超时进度条,文本信息。这些组件都可以使用色彩、字体、图像。
查看实例:附录《主题实例》62。
16
使用主题文件需要使用gfxterm输出终端。主题中可以包含中文字符,但是文件编码必须用utf8,unix 格式的换行,同时必须加载支持utf8中文的字体。
打开gfxterm需遵循以下步骤:
#为了添加背景,导入png和jpeg模块。
insmod png
insmod jpeg
#载入合适的显卡驱动
insmod vbe
#insmod vga
#引入gfxterm模块
insmod gfxterm
#insmod gfxmenu
#加载字体:
loadfont /boot/wqy.pf2
loadfont /boot/DejaVuSansMono.pf2
#设置gfxterm的参数:
set gfxmode=1024x768
set theme=(cd)/boot/theme/menu.txt
#theme变量指向主题配置文件。
#打开gfxterm设备
terminal_output gfxterm
6.2主题元素
6.2.1色彩
色彩可以通过多种方式指定:
? ? ? HTML风格:#RRGGB或者#RGB,R G B是十六进制数字。例如:"#8899FF" 逗号分割的3个十进制RGB数值:"128,128,255"
SVG 1.0色彩名,必须是小写:"cornflowerblue"
6.2.2字体
GRUB使用PF2字体格式点阵字体。字体必须是完整的字体名。使用grub2-mkfont可以转换已知的字
体到pf2。
grub-mkfont --verbose --range=0x0-0x7F --size=18 --output=DejaVuSans-18.pf2 \
$(locate DejaViewSans.ttf)
仿造面的命令生成DejaVuSansMono字体,在终端下支持中文你还需要其他中文字体,比如
WenQuanYi。
loadfont命令用来加载字体。lsfonts命令用来查看已经加载的所有字体的字体名。这些字体名会用在主
17
题文件的font字段。
如果命令输出大于1页,在执行lsfonts前使用set pager=1设置翻页。想显示中文应该使用gfxterm 6.2.3进度条组件
GRUB进度条用来表示默认加载倒计时。创建进度条使用progress_bar组件,并且设置id
"__timeout__"。GRUB会根据指定的时间倒计时,并且在用户进行键盘操作时关闭并隐藏进度条。
进度条表面可以有表示剩余时间的文本,设置show_text属性为true或者false,它将开启或者关闭文本显示。
6.2.4表盘进度指示器
表盘进度指示器类似与进度条,设置了__timeout__ id时,GRUB会设置倒计时时限。对于环表盘进度指示器可以使用两个图片center和tick。一个用来绘制表盘中心,一个用来绘制表周的刻度。
6.2.5标签组件
文本标签可以被放在引导界面的任何位置。标签有字体、色彩、和水平长度等属性。如果标签也拥有
__timeout__ ID那么标签的text属性会显示为自动引导倒计时。
6.2.6引导菜单组件
引导菜单组件是GRUB显示菜单项的地方。菜单项由配置文件的menuentry命令定义。菜单项是一个列表,它包含文本标识,和一个可选的图标。如果在grub/themes/icons目录下存在一个名为myclass .png的PNG图片,那么它会被显示在所有class为"myclass"的项目附近。菜单组件可以以多种方式配置,例如菜单项文本的字体和色彩,也可以为菜单组件本身和未选择菜单项、已选择菜单项指定样式盒。
6.2.7样式盒
排版的重要特性就是样式盒。一个样式盒由9个矩形区域组成(它们是空的未填充区域),会被无缝
绘制在屏幕。
她们的位置关系如下:
Northwest (nw) North (n) West (w) Center (c)
Southwest (sw) South (s) Northeast (ne) East (e) Southeast (se)
由于样式盒可以是任意尺寸,所以center区域会按照一定规则缩放用来适应所指定的大小: 18
1.四个边界区域(west north east south)只在它们贴近的方向缩放,比如在左边的west和east区
域,只在竖直方向缩放。north和south只在水平方向缩放。
2.边角区域不缩放:Northwest (nw) Northeast (ne) Southeast (se) Southwest (sw)不缩放。
3.中心区域用来填充剩下的区域
6.2.8创建样式盒图形
inkscape矢量图形编辑器对创建样式盒图形非常有用。简单的步骤就可以把图片切割成样式盒需要的部
分。以下是大概步骤:
1.新建或者打开一幅图像
2.在顶层创建一个新的图层。并使它可见,然后选中此图层。
3.按照你需要的样式盒的格局绘制9个无填充的矩形。设置矩形边框为实心直线1像素宽。边角区
域的边长必须精确匹配边界区域。如果将边界区域和边角区域的宽度设置为1像素,则意味着这
些区域被关闭了(几乎不存在,在图形中不可见)。如果边界区域和边角区域坐标和宽度的误差
哪怕只有1像素,在图形渲染时可能会很明显。你可能需要绘图软件的"网络/辅助线"功能来精确
放置矩形。
4.右击中心矩形,修改属性ld到slice_c。为其他矩形重复这个步骤,分别改为slice_n slice_ne
slice_e ... ...。
5.保存
6.选中所有这些矩形(可能是CTRL+A快捷键)。在状态栏应该看到"选中了9个对象"之类的
信息。
7.隐藏矩形所在的图层。这样矩形被选中了但是并没有显示。
8.单击文件--导出位图。它会在当前目录下创建按照矩形区域切割的9个PNG文件。
6.3主题文件教程
主题文件是一个文本文件。以#开始的行作为注释被忽略掉。主题文件包含两种类型的语句:
1.全局属性
2.组件构造
6.3.1全局属性
19
6.3.2格式
全局属性使用简单的格式指定:
? ? ? name1:value1
name2:"value which may contain spaces" name3:#88F
name3是一个色彩值。
6.3.3全局属性列表
title-text
值为字符串,它会作为标题居中显示在整个屏幕顶端。
title-font
用于title-text文本的字体。
title-color
用于title-text文本的色彩。
message-font
当GRUB无法自动加载某个菜单项时显示短消息使用的字体。
message-color
定义消息文本的色彩
message-bg-color
定义消息文本的背景色
desktop-image
定义屏幕背景图片,它会自动缩放以填充整个屏幕。
desktop-color
如果desktop-image没有设置,那么使用desktop-color背景色。
terminal-box
设置文件名通配,匹配得到的文件用来设置命令行终端窗口使用的样式盒。例如terminal-
box:terminal_*.png
会使用这些文件terminal_c.png terminal_n.png terminal_nw.png等等。。。分别表示:
Northwest (nw) North (n) West (w) Center (c)
Southwest (sw) South (s) Northeast (ne) East (e) Southeast (se)
如果某些区域没有对应的文件,那么会留空。
6.3.4组件构造
组件可以提供更加灵活的界面排版。容器组件可以包含其他组件。所有的组件都包含在一个根容器组件20