因为经常需要在ubuntu下调试openstack代码,在windows下用虚拟机又会严重影响使用性能,所以干脆将笔记本装了windows+ubuntu双系统,曾多次半懂地设置了启动顺序,但当重装系统后再次设置时总是忘记如何设置,所以决定花点时间,简单研究了下grub
的配置。
GNU GRUB(简称“GRUB”)是一个来自GNU项目的启动引导程序。GRUB是多启动规范的实现,它允许用户可以在计算机内同时拥有多个操作系统,并在计算机启动时选择希望运行的操作系统。GRUB可用于选择操作系统分区上的不同内核,也可用于向这些内核传递启动参数。 ——百度百科
Grub 2 是新一代的Grub,功能比Grub功能更加强大,由三部分组成:
* /etc/default/grub 文件
* /etc/grub.d 文件夹
* /boot/grub/grub.cfg 文件
其中ubuntu系统启动用的是 grub.cfg 文件。
我觉得可以这样认为,在我们执行update-grub(更新启动菜单)命令后系统就会根据 /etc/default/grub文件 和 /etc/grub.d文件夹 的内容生成 /boot/grub/grub.cfg文件,所以当 /etc/default/grub文件 和 /etc/grub.d文件夹 被修改后,再执行 update-grub
, grub.cfg文件内容被更改,或者说是被更新吧。
所以网上常见的通过直接修改 /boot/grub/grub.cfg 来设置grub
的启动顺序并不是最好的一种方法,因为每个更新内核或才手动执行 “update-grub” 命令后,这样的设置就失效了。
以ubuntu 15.10进行说明:
/boot/grub/grub.cfg ----系统启动引导读取的文件
/etc/default/grub文件 ----存有开机默认启动项、倒记时时间的内容等grub的相关配置
/etc/grub.d文件夹 -------存有各个具体启动项,如下
wangchao@ubuntu:/etc/grub.d$ ls
00_header 10_linux 20_memtest86+ 30_uefi-firmware 41_custom
05_debian_theme 20_linux_xen 30_os-prober 40_custom README
00_header
配置grub程序,变量从 /etc/default/grub
中导入
05_debian_theme
设置 GRUB 2
的背景图片、字体颜色和主题等
10_linux
搜索识别当前系统的内核,并建立启动菜单,随着Ubuntu的内核升级,可能有多个内核。
20_memtest86+
搜索 /boot/memtest86+.bin 并添加内存测试启动项。如果用不上,去掉该文件的可执行权限即可。
sudo chmod -x /etc/grub.d/20_memtest86+
sudo update-grub
20_linux_xen
以 Xen hypervisor 启动linux系统。
30_os-prober
查找存在的其他操作系统并建立启动菜单项,依次为windows,linux,macos和Hurd。
40_custom
根据模板添加自定义启动项。
说明:在/etc/grub.d
目录下的启动项,只要变动文件的x属性(执行权限),即可决定这个选项要不要出现在grub的启动选单中。
配置grub
我们一般也只需要修改 /etc/default/grub
这个文件就行,如果改坏了,没有关系,重新 从/usr/share/grub/default/grub
拷贝一份就可以了。
GRUB_DEFAULT
设置默认的grub
启动项,可以是序号,完整的条目名或者是“saved”,默认为 0,表示为grub
启动菜单的每一个启动项。自 Grub 1.99
引入了子启动项的结构,常见于 高级启动项。对于这样的grub
菜单,在设置时就分为主菜单项和子菜单项了。
默认启动项为主菜单项
在主菜单项的第一个启动项序号为 0,第二条为 1,并以此类推。另外你也可以直接用完整的启动名作为值,所以可以这样配置。
GRUB_DEFAULT=0
GRUB_DEFAULT=1
GRUB_DEFAULT="Ubuntu, with Linux 3.2.0-23-generic"
默认启动项为子菜单项
对于 GRUB_DEFAULT
配置子菜单的值由3个部分组成,依次为:一级菜单(即主菜单项)的序号或者条目名,”>” 符号(前后不能有空格)和 二级菜单的序号或者条目名。直接上图进行说明:
GRUB_DEFAULT="Previous Linux versions>Ubuntu, with Linux 3.2.0-18-generic-pae"
GRUB_DEFAULT="Previous Linux versions>0"
GRUB_DEFAULT="2>0"
GRUB_DEFAULT="2>Ubuntu, with Linux 3.2.0-18-generic-pae"
当值为saved 时(对grub 1.98及后续版本有效),设置默认启动项时就需要通过 “grub-reboot” 和 “grub-set-default” 两个命令去设置了,其中“grub-reboot”仅设置下次启动的默认启动项,“grub-set-default”设置每次启动的默认项。
尽管上面讲的都是设置默认启动项,在开机过程中,也可以手动选择启动项启动操作系统。
GRUB_SAVEDEFAULT
如果设置了true
,则下次的默认启动项就上次选择的,个人觉得这个比较好用,我就是选用这种方式设置默认启动项的。当然,要使用这种设置,还需要满足下面的条件:
/boot
目录所在分区不能是LVM分区或者是RAIDGRUB_HIDDEN_TIMEOUT
设置等待用户按shift键的时间,在此期间不会显示grub
界面,直到用户按下shift按键,才会进入grub
菜单,如果没有按下shift键,等过了这个时间,直接进行默认的操作系统,特别是在单操作系统下,这也是默认行为。经过我测试,其实就算是设置值为0,及时按shift键还是可以进入grub
。
经过测试,发现上述仅是针对单系统,如果有多系统,那个这个参数会覆盖下面的GRUB_TIMEOUT
参数,表现出GRUB_TIMEOUT
的行为,即代表显示grub
的等待时间。
GRUB_HIDDEN_TIMEOUT_QUIET
值为true
或false
,设置在GRUB_HIDDEN_TIMEOUT
期间要不要显示倒计时。
GRUB_TIMEOUT
设置在自动启动操作系统时grub
的显示时间,期间可以手动选择相关启动项,并也中止倒计时,期间如果没有任何操作,则过了这个时间,自动进入默认的操作系统。
与系统启动顺序配置相关的也就这几个主要参数了,其他配置就不作过多的介绍了,具体参见官方说明
GRUB_TIMEOUT & GRUB_HIDDEN_TIMEOUT
总的来说,只要GRUB_HIDDEN_TIMEOUT
设置了值,那GRUB_TIMEOUT
就不会生效,在update-grub
时,系统会提示“Warning: Setting GRUB_TIMEOUT to a non-zero value when GRUB_HIDDEN_TIMEOUT is set is no longer supported.”的警告信息。
但在不同的情况下,GRUB_HIDDEN_TIMEOUT
又表现出不同的行为。在单系统下,表示隐藏grub
等待用户通过按shift键进行了grub
的时间;而在多系统下,则表示显示grub
等待用户选择启动项的时间,此时与GRUB_TIMEOUT
类似,但会覆盖GRUB_TIMEOUT
的值(如果也同时设置了GRUB_TIMEOUT
)。
弄懂上面的原理后,那就可以随心所欲地根据自己的需求配置了grub
了。由于我同时安装了win8.1和ubuntu 15.10,并且平常使用win8.1更多,所以需要将win8.1的启动项调到第一个,其次关于ubuntu测试的启动项也用不到,所以需要禁用,命令如下:
cd /etc/grub.d
sudo mv 30_os-prober 06__os-prober
sudo chmod -x 20_memtest86+
最后,还配置了默认启动上次启动的操作系统,并设置grub
超时时间为 3s,最终修改如下:
GRUB_DEFAULT=saved
GRUB_SAVEDEFAULT=true
# GRUB_HIDDEN_TIMEOUT=5
# GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=3
参考文献
Grub2/Submenus - Community Help Wiki
Grub2/Setup - Community Help Wiki