侧边栏壁纸
博主头像
落叶人生博主等级

走进秋风,寻找秋天的落叶

  • 累计撰写 130562 篇文章
  • 累计创建 28 个标签
  • 累计收到 9 条评论
标签搜索

目 录CONTENT

文章目录

grub2

2023-12-07 星期四 / 0 评论 / 0 点赞 / 77 阅读 / 11011 字

我在一台主机上先后安装了3各操作系统,Windows 7,以及32位和64位的ubuntu 14.04。安装完64位ubuntu之后发现启动菜单变得很乱,于是进入Windows用一个叫EasyBCD的

我在一台主机上先后安装了3各操作系统,Windows 7,以及32位和64位的ubuntu 14.04。安装完64位ubuntu之后发现启动菜单变得很乱,于是进入Windows用一个叫EasyBCD的工具修改启动菜单。结果导致整个MBR里面没有启动项,重启之后任何系统都进不了了。

我的解决方法是用之前制作的ubuntu系统的USB启动盘进入ubuntu试用系统,以便安装grub2 boot loader。grub boot loader的文档请参考官方资料

安装grub2

首先查看各物理硬盘及其分区:

Shell

ubuntu@ubuntu:~$ sudo fdisk -l

Shell挂载要安装grub2的分区:

ubuntu@ubuntu:~$ sudo mount /dev/sda6 /mnt# /dev/sda6是我安装32位ubuntu的分区,前面fdisk命令的输出结果中可以看到这个分区的信息

Shell安装grub菜单

ubuntu@ubuntu:~$ sudo grub-install --boot-dir=/mnt /dev/sda# --boot-dir设置为/mnt/boot,是说将将grub相关的信息如镜像文件存放在这个路径的grub子目录下。效果相当于登录32位ubuntu系统,然后执行`sudo grub-install /dev/sda`# /dev/sda 指定将grub安装在这个物理硬盘上

接下来我直接重启进入grub boot loader。不过我看到的grub是命令行方式的。接下类可以通过命令来进入安装在硬盘上的各系统:

启动系统

  1. 进入32位ubuntu系统
    grub> ls -l# 这里会列出各硬盘和分区grub> set root=(hd0,msdos6)# 输入到hd的时候按tab键,会列出连接的所有硬盘,我列出了hd0和hd1分别是一块硬盘和一个u盘# 输入到逗号(,)的时候按tab键,会列出硬盘上的所有分区,输出结果和前面的`ls -l`命令一致。网上很多资料这里都是直接用数字表示各分区,但我这边列出的是msdos加数字的形式。msdos6是我安装32位ubuntu系统的分区。grub> linux /boot/vmlinuz-3.13.0-40-generic root=/dev/sda6# 输入/boot/vmlinuz之后按tab键,会列出几个版本的文件比如vmlinuz-3.13.0-32-generic,vmlinuz-3.13.0-40-generic。我也不知道有什么区别,选了一个版本号最大的。# root=/dev/sda6没有tab键自动补全,我是根据32位ubuntu系统在第6分区来填写的grub> initrd /boot/initrd.img-3.13.0-40-generic # 跟前面linux命令类似这里的initrd.img也会有几个版本,我选择了与前面一致的版本grub> boot# 执行这条命令开始启动操作系统

    64 ubuntu

  2. grub> ls -l# 这里会列出各硬盘和分区grub> set root=(hd0,msdos6)# 输入到hd的时候按tab键,会列出连接的所有硬盘,我列出了hd0和hd1分别是一块硬盘和一个u盘# 输入到逗号(,)的时候按tab键,会列出硬盘上的所有分区,输出结果和前面的`ls -l`命令一致。网上很多资料这里都是直接用数字表示各分区,但我这边列出的是msdos加数字的形式。msdos6是我安装32位ubuntu系统的分区。grub> linux /boot/vmlinuz-3.13.0-40-generic root=/dev/sda7# 输入/boot/vmlinuz之后按tab键,会列出几个版本的文件比如vmlinuz-3.13.0-32-generic,vmlinuz-3.13.0-40-generic。我也不知道有什么区别,选了一个版本号最大的。# root=/dev/sda6没有tab键自动补全,我是根据32位ubuntu系统在第6分区来填写的grub> initrd /boot/initrd.img-3.13.0-40-generic # 跟前面linux命令类似这里的initrd.img也会有几个版本,我选择了与前面一致的版本grub> boot# 执行这条命令开始启动操作系统
    安装在sda7分区上的64位ubuntu系统也可以通过类似的方式启动
  3. 进入windows 7系统
    grub> set root=(hd0,msdos1)# 我的硬盘的第一分区在windows系统里面显示的是“系统保留”,大小为100M,安装windows系统的分区是msdos2。注意这里指定的是“系统保留”分区,而不是安装windows的分区grub> chainloader +1grub> boot

     

==============关于BIOS、 boot loader、MBR的知识碎片,待整理=================

PC开启的时候,先会运行BIOS。BIOS可以根据优先级启动各种设备(U盘,硬盘,光驱)中的一个,优先级可以在BIOS(开机的时候按DEL或者F12键进入)中进行设置。BIOS启动某一个设备的时候,执行该设备MBR(Master Boot Record)里面的boot loader。

MBR是一个512字节的block,位于存储设备的第一个sector,MBR中存储了分区表和boot code(boot loader)。MBR之后,才是该设备的各分区。在MBR的512字节中,boot code占了446字节,4个主分区记录各占16字节,还有两个字节是MBR signature。

boot loader的作用是选择并加载操作系统内核,然后将控制权交给操作系统。每个操作系统都会带一个可以加载该系统的boot loader,有些boot loader可以启动多种操作系统。

Window系统中,XP及更早的版本使用NTLDR boot loader,Windows Vista及之后的系统使用BOOTMGR。linux系统有更多支持的boot loader,包括ISOLINUX,LILO,GRUB。

前面说过,MBR中只有4个主分区记录,这就是为什么存储设备(比如硬盘)分区的时候只能有4个主分区的原因。如果分区的时候,创建3个主分区和一个扩展分区(extended partition, logitical partition),那么MBR中的最后一个主分区记录实际上是一个分区表(扩展分区表)。扩展分区表存储各逻辑分区(logical volumes)的信息。

一个存储设备除了有MBR之外,每个分区(主分区或者逻辑分区)都有自己的boot sector,叫做volumne boot record(VBR)。由于MBR中的boot loader可能不知道如何加载一个操作系统的内核,因此它需要通过VRB中的boot loader来加载这个操作系统,比如GRUB不懂如何(直接)加载Windows系统,就得先加载Windows自身的boot loader(比如BOOTMGR),然后由BOOTMGR负责加载Windows系统。这个过程就是所谓的chain-loader。

GRUB Boot loader –> Windows Boot loader –> Load Windows Kernel

Windows的boot loader只能加载主分区的Windows操作系统,因此Windows必须得安装在主分区,否则windows boot loader无法启动Windows;GRUB可以加载主分区和逻辑分区的多种操作系统,包括直接加载linux系统,通过chain-loader加载Windows系统。接下来我们重点说一下GRUB2。

很多linux系统本身集成(安装)了GRUB2,这里说安装是指在操作系统中安装了相关的软件包,但操作系统安装过程中一般允许你选择是否需要将GRUB写入到MBR中。系统中安装的软件包提供了一系列命令行工具,用于检测硬盘中的各操作系统,生成启动菜单,更新MBR中的boot loader,更新VBR中的boot loader。这些命令会用到的一些相关文件包括:

  1. /etc/default/grub,这个文件设置一些变量的值。
    GRUB_TIMEOUT:等待这么多秒之后自动加载默认系统,我在Ubuntu 14.04 LTS系统的GRUB中配置这个值为0(直接加载默认操作系统),发现生成的grub.cfg中有那么一项检查,如果TIMEOUT为0就改成10。所以可能要使GRUB直接加载默认操作系统出了改这个值之外还需要做其他设置。
  2. /etc/grub.d,这个文件夹包含一些脚本和模块

以下是一些GRUB命令的说明:

  1. sudo update-grub,或 sudo mk-config
    根据前述的/etc/default/grub文件中的变量设置,生成grub.cfg文件。update-grub命令等同于mk-config -o /boot/grub/grub.cfg,也就是说将生成的文件直接存放在/boot/grub文件夹中,下次启动的时候就能看到效果。
  2. sudo grub-install /dev/sda
    这条命令将grub boot loader安装到MBR中,当前MBR中的boot loader会被替换。安装过程中会创建/boot/grub文件夹(如果之前没有安装过的话)。如果/boot/grub文件夹下没有grub.cfg文件,重启进入的GRUB2是命令模式的,需要通过输入命令来启动各系统。因此,正常流程是先运行grub-install安装GRUB到MBR中,然后运行udpate-grub生成grub.cfg文件,这个grub.cfg包含当前磁盘中存在的各操作系统,并且会生成一个菜单供选择。

以上说的是GRUB2,前面说过,GRUB2能够能够加载包括逻辑分区在内的任意分区里的操作系统。不过它chain-loader加载Windows系统的时候可能会出现橙色屏幕的情况。

另一种选择是在MBR中通过EasyBCD写入Windows boot loader。EasyBCD操作界面如下:

  1. “View Settings”或者”Edit Boot Menu”里面能够看到当前的启动菜单设置。
  2. “Add New Entry”可以将某个系统添加到启动菜单中,在Linux/BSD tab中,Drive选项可以选择该系统在哪个分区,注意这里可以选择逻辑分区。前面说过Windows boot loader只能加载主分区里面的操作系统,不懂EasyBCD是怎么实现加载逻辑分区的,不过有一点可以肯定,就是通过EasyBCD加载linux操作系统的时候,也是使用chain-loader。
  3. “Edit Boot Menu”能调整各系统在菜单中的顺序,设置默认操作系统,等待时间等等。

在我的Windows 7系统中,EasyBCD的boot loader会安装在硬盘第一个分区(100M的系统保留分区,应该是安装Windows 7的时候创建的),”Add New Entry”及”Edit Boot Menu”里面所做的改动直接生效(当然,”Edit Boot Menu”里面还得点击”Save Settings”按钮)。如果MBR中是Windows boot loader,那么直接在第一个启动菜单就能看到;如果MBR中是其他boot loader(比如GRUB2),那么选择启动Windows之后,chain-loader会加载EasyBCD在100M系统保留分区的启动boot loader。

如果也需要将boot loader写入到MBR中,只需在”BCD Deployment”中,选择”Install the Windows Vista/7 bootloader to the MBR”并点击”Write MBR”。这一步骤只需要做一次,以后Add New Entry,Edit Boot Menu的修改直接生效。如果使用EasyBCD之前MBR中本来就是Windows bootloader,连这一步骤都不需要做了。

针对EasyBCD,我的理解是,无论是MBR还是VBR(100M系统保留分区)中的boot loader,都只是boot loader的一小部分,剩下的boot loader代码以及配置就是EasyBCD中”Add New Entry”及”Edit Boot Menu”修改的部分。

广告 广告

评论区