在介绍GRUB切换系统默认启用内核的方法之前,我们首先了解一些背景知识。
想必大家都知道,boot loader是计算机启动时运行的第一个程序。 它负责装载和传输控制信息到操作系统内核,而内核负责初始化其余的操作系统。
GNU GRUB是一个非常强大的boot loader,可以加载很多种免费操作系统以及使用chain-loading的操作系统。 GRUB旨在解决启动个人电脑的复杂性。
GRUB的一个重要特点是它具有很强的灵活性。GRUB能够识别文件系统和内核可执行文件格式。因此您可以以您喜欢的方式加载任意一个操作系统并且不需要记录系统内核在磁盘上的物理位置。 因此您只需指定内核文件名、所在驱动器和内核驻留的分区即可加载内核。
使用GRUB引导时,可以使用命令行界面或菜单界面。 使用命令行界面需要键入驱动器名,手动指定内核的规格和文件名。 在菜单界面,您只需使用箭头键选择一个操作系统即可。 菜单界面基于事先准备的配置文件。 在菜单界面中,您可以切换到命令行模式,反之亦然。
GRUB
有两种不同的引导方法,一种是直接加载操作系统,另外一种是链式加载(chain-load)。通常采用的是第一种方式,因为它不需要安装或维护其他引导装载程序,GRUB能够通过这种方式从任意磁盘/分区加载操作系统。但是,后一种方式有时是必需的,因为GRUB并不支持对所有操作系统的直接加载。链式加载只支持PC BIOS和EFI平台。
GRUB由
'grub.cfg'
文件进行配置,通常位于
/boot/grub
路径下。这个文件相当灵活,但它通常不需要完全由用户手动写入。
程序’grub-mkconfig’生成使用于大多数情况的
'grub.cfg'
文件。它适用于升级发行版本,并可发现可用的内核以及为它们生成菜单条目。
文件
/etc/default/grub
控制
'grub-mkconfig
’程序的操作。它包含的内容是
'key=value'
的行序列,并且如果value中包含空格,那么value需要由引号标注,例如:
GRUB_TERMINAL_INPUT="console serial"
在
/etc/default/grub
中合法的key括
'GRUB_DEFAULT','GRUB_TIMEOUT','GRUB_TERMINAL_INPUT'
等,限于篇幅,这里不做详细介绍。
现在我们通过修改
/etc/default/grub
文件来改变系统默认启用的内核,先看默认情况下系统的
/etc/default/grub
文件内容。
# If you change this file, run 'update-grub' afterwards to update
# /boot/grub/grub.cfg.
# For full documentation of the options in this file, see:
# info -f grub -n 'Simple configuration'
GRUB_DEFAULT=0
#GRUB_HIDDEN_TIMEOUT=0
GRUB_HIDDEN_TIMEOUT_QUIET=true
GRUB_TIMEOUT=10
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash"
GRUB_CMDLINE_LINUX=""
# Uncomment to enable BadRAM filtering, modify to suit your needs
# This works with Linux (no patch required) and with any kernel that obtains
# the memory map information from GRUB (GNU Mach, kernel of FreeBSD ...)
#GRUB_BADRAM="0x01234567,0xfefefefe,0x89abcdef,0xefefefef"
# Uncomment to disable graphical terminal (grub-pc only)
#GRUB_TERMINAL=console
# The resolution used on graphical terminal
# note that you can use only modes which your graphic card supports via VBE
# you can see them in real GRUB with the command `vbeinfo'
#GRUB_GFXMODE=640x480
# Uncomment if you don't want GRUB to pass "root=UUID=xxx" parameter to Linux
#GRUB_DISABLE_LINUX_UUID=true
# Uncomment to disable generation of recovery mode menu entries
#GRUB_DISABLE_RECOVERY="true"
# Uncomment to get a beep at grub start
#GRUB_INIT_TUNE="480 440 1"
其中GRUB_DEFAULT用来设定默认启动项,一般使用数字,但我们这里采用另外一种方法。GRUB_TIMEOUT用来设定超时时间,在该时间内无操作,则启用GRUB_DEFAULT设定的启动项。
那么我们怎样查看自己可使用的启动项呢?使用下面这条命令即可:
grep menuentry /boot/grub/grub.cfg
回车后输出如下:
if [ x"${feature_menuentry_id}" = xy ]; then
menuentry_id_option="--id"
menuentry_id_option=""
export menuentry_id_option
menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-64b318d1-d51c-4042-8be4-cb134abd8948' {
submenu 'Ubuntu 高级选项' $menuentry_id_option 'gnulinux-advanced-64b318d1-d51c-4042-8be4-cb134abd8948' {
menuentry 'Ubuntu,Linux 4.13.0-32-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.13.0-32-generic-advanced-64b318d1-d51c-4042-8be4-cb134abd8948' {
menuentry 'Ubuntu, with Linux 4.13.0-32-generic (upstart)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.13.0-32-generic-init-upstart-64b318d1-d51c-4042-8be4-cb134abd8948' {
menuentry 'Ubuntu, with Linux 4.13.0-32-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.13.0-32-generic-recovery-64b318d1-d51c-4042-8be4-cb134abd8948' {
menuentry 'Ubuntu,Linux 4.10.0-28-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.10.0-28-generic-advanced-64b318d1-d51c-4042-8be4-cb134abd8948' {
menuentry 'Ubuntu, with Linux 4.10.0-28-generic (upstart)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.10.0-28-generic-init-upstart-64b318d1-d51c-4042-8be4-cb134abd8948' {
menuentry 'Ubuntu, with Linux 4.10.0-28-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-4.10.0-28-generic-recovery-64b318d1-d51c-4042-8be4-cb134abd8948' {
menuentry 'Memory test (memtest86+)' {
menuentry 'Memory test (memtest86+, serial console 115200)' {
menuentry 'Windows 7 (loader) (on /dev/sda1)' --class windows --class os $menuentry_id_option 'osprober-chain-90382FA0382F8476' {
menuentry 'Red Hat Enterprise Linux Server release 6.7 (Santiago) (on /dev/mapper/vg_oracleserver-lv_root)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-simple-fdd3857d-f18f-4073-80ec-a17f9301823a' {
submenu 'Red Hat Enterprise Linux Server release 6.7 (Santiago) (on /dev/mapper/vg_oracleserver-lv_root) 高级选项' $menuentry_id_option 'osprober-gnulinux-advanced-fdd3857d-f18f-4073-80ec-a17f9301823a' {
menuentry 'Oracle Linux Server Unbreakable Enterprise Kernel (3.8.13-68.3.4.el6uek.x86_64) (on /dev/mapper/vg_oracleserver-lv_root)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-/vmlinuz-3.8.13-68.3.4.el6uek.x86_64--fdd3857d-f18f-4073-80ec-a17f9301823a' {
menuentry 'Oracle Linux Server Red Hat Compatible Kernel (2.6.32-573.el6.x86_64) (on /dev/mapper/vg_oracleserver-lv_root)' --class gnu-linux --class gnu --class os $menuentry_id_option 'osprober-gnulinux-/vmlinuz-2.6.32-573.el6.x86_64--fdd3857d-f18f-4073-80ec-a17f9301823a' {
前缀带有
menuentry
都是
GRUB_DEFAULT可
以设置的启动项,如果我们要设置
Ubuntu, Linux 4.10.0-28-generic
为默认启动项,可以修改
GRUB_DEFAULT
如下:
GRUB_DEFAULT='gnulinux-advanced-64b318d1-d51c-4042-8be4-cb134abd8948>gnulinux-4.10.0-28-generic-advanced-64b318d1-d51c-4042-8be4-cb134abd8948'
对应的形式为:
GRUB_DEFAULT
=
$menuentry_id_option
之后的内容
>
‘Ubuntu高级选项
$menuentry_id_option gnulinux-advanced-64b318d1-d51c-4042-8be4-cb134abd8948
中括号里边
$menuentry_id_option
之后的内容
注意:
有些教程修改的是如下的形式,这种形式亲自验证,不能够使用。
GRUB_DEFAULT=“Ubuntu, Linux 4.10.0-28-generic”
上面的步骤完成后保存修改后的文件,并在终端下执行以下命令:
sudo update-grub
重启电脑即可看到grub菜单默认启动项已经定位到刚才设定的启动项。
当然我们也可以用menuentry的数字顺序来设置GRUB_DEFAULT,这里只是简单向大家介绍GRUB这个工具以及记录自己学到的知识,这种方法可以用来在多内核情况下切换系统内核,而不仅仅是设定默认启动项。
最后,在终端下执行以下命令,查看自己启动的内核版本是否和设定的对应:
uname -r
重启进入的grub是上述图中所示情况表示正确切换内核。
重启进入的grub时,出现默认的选项为Ubuntu,表示并没有修改默认选项成功。