[TOC]

0x00 基础介绍

描述:GRUB英文全称GRand Unified Bootloader俗称引导程序是硬盘中的软件,它可以启动用户在计算机中的多个操作系统所以也叫多重启动管理器。
目前主流版本是 GRUB2,在windows中也有类似的引导程序ntloader虽然它也可以引导Linux操作系统但是比较麻烦;

作用说明:
它可以载入操作系统的不同内核或者初始化操作系统,也可用于向这些内核传递启动参数,然后把引导权交给操作系统来完成引导。

优点说明:

  • 1.支持大硬盘(>=2T)
  • 2.支持开机画面
  • 3.两种执行模式;
  • 4.兼具扩展性和灵活性的一款引导加载程序,提供了大量可定制菜单选项。
  • 5.分区位置改变后不必重新配置
  • 6.支持引导几乎所有的 Unix,Linux,Windows 操作系统。

引导过程:
描述: 在通过自检后BIOS在硬盘启动时候通常是转向到第一块的硬盘的第一个扇区,即主引导记录(MBR), 以下是装载GRUB和操作系统的过程:

  • 1.装载记录BOOT:基本引导装载程序装载第二引导装载程序;
  • 2.装载GRUB:此时引出更高级的功能,以允许用户装载一个特定的操作系统。
  • 3.装载系统:载入操作系统内核,此时GRUB把机器的控制权移交给操作系统。
    TIPS:与windows引导方式是不同的,它使用了链式装载的引导方法,主引导记录仅仅是简单地指向操作系统所在分区的第一个扇区。

设备名称:
描述:GRUB识别的设备名称不区分IDE硬盘和SCSI硬盘,统一使用hd*来表示既(hdx,y))标识某个硬盘中的某个分区x表示硬盘号,y表示分区号(他们都是从0开始计数),同时软盘使用fdx来标识即(fdx) x为硬盘号,x从0开始计数

装置 Lilo Grub
IDE1 master hda, hda1, hda2 (hd0), (hd0,0), (hd0,1)
IDE1 slave hdb, hdb1, hdb2 (hd1), (hd1,0), (hd1,1)
IDE2 master hdc, hdc1, hdc2 (hd2), (hd2,0), (hd2,1)
IDE2 slave hdd, hdd1, hdd2 (hd3), (hd3,0), (hd3,1)

注意事项:

  • (1) 在windows中系统的第一个硬盘驱动器表示为(hd0),此时该磁盘的第一个分区表示为(hd0,0)它就是我们所说的C盘;
  • (2) 由于主分区受限于磁盘格式常常为四个,所以第一个磁盘的主分区分别用(hd0,0)~(hd0,3)来表示,而逻辑分区则是从(hd0,4)开始计算, 在Windows中分区都是一个主分区其余是逻辑分区,因此C盘用(hd0,0),D盘用(hd0,4)来表示;


GRUB 位置
描述:其启动代码(boot.img)直接安装在 MBR 中,然后执行 GRUB 内核镜像(core.img),最后从/boot/grub中读取配置和其他功能代码。
如下图所示,GRUB 的执行顺序为 boot.img --> core.img --> /boot/grub/

BIOS 引导方式中,MBR 分区表和 GPT 分区表的 GRUB 引导文件所放分区不同:

  • (1) 在 MBR 分区表中,boot.img 和 core.img 都在 MBR 中。MBR 虽然只占用一个扇区(512Byte),但是其所在的磁道是空闲的,不会用于分区,可以放下 core.img。
  • (2) 在 GPT 分区表中,MBR 为 protected MBR(为兼容 MBR,在硬盘起始位置保留的空间),后面并没有空间放core.img,需要建一个专门的分区来放,称为BIOS boot partition,该分区的文件类型为unformatted,flag 为BOIS_grub,该 flag 用于标识core.img所要安装到的分区。
    • 2.1 如果使用 UEFI 引导,GRUB 读取的是 ESP 分区中的数据,不需要 flag 为 BIOS_grub的分区。
      WeiyiGeek.GRUB-位置

      WeiyiGeek.GRUB-位置


1.Grub安装

描述:Grub 2 最好的特性是可以随时重新安装,因为当其它像 Windows 之类的系统用它们自己的 bootloader 替换后,导致 Grub 2 丢失,你可以使用 live 发行版,寥寥数步即可重装 Grub ;

需求:假设你在 /dev/sda5 安装了一个发行版,若要重装 Grub

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1.为发行版创建一个挂载目录
sudo mkdir -p /mnt/distro

# 2.挂载分区
mount /dev/sda5 /mnt/distro

# 3.重装 Grub 到分区之中,注意此时命令会改写 /dev/sda 设备上的 MBR 信息,指向当前 Linux 系统,并重写一些 Grub 2 文件,如 grubenv 和 device.map 。
grub2-install --root-directory=/mnt/distro /dev/sda

# 4.另一个问题常见于装有多个发行版的计算机上。
# 当你安装了新的 Linux 发行版,它的 bootloader 应当要能找到所有已经安装的发行版。
# 一旦不行只要引导进入新安装的发行版,并运行
grub2-mkconfig

注意事项:

  • (1) 在执行此命令前请确保启动菜单中缺失的发行版的 root 分区已经挂载,如果你想添加的发行版有单独的 /root 和 /home 分区,在运行 grub2-mkconfig 之前,只需挂载包含 /root 的分区
  • (2) 如果你以默认设置安装了 Fedora ,则发行版的安装器已经创建了 LVM 分区。此时你需要使用发行版的包管理系统安装 lvm2 驱动,如下sudo apt-get install lvm2才能使得 Grub 2 的 os-prober 脚本能够找到并将 Fedora 添加进启动菜单。

0x01 GRUB 文件介绍

描述:此处以Linux中GRUB引导程序为例,其重要的部分是一堆文本文件和两个脚本文件,即下面列出的文件目录;

  • /etc/default/grub : 文本文件,设置通用配置变量和 Grub 2 菜单(见下方 常见用户设置 )的其它特性。
  • /etc/grub2.cfg :
  • /etc/grub2-efi.cfg :
  • /etc/grub.d: 文件夹,定义每个菜单项的所有脚本都放置在这里,里面以两位数字+脚本名称的格式存放,为的是在构建 Grub 2 菜单时定义脚本的执行顺序以及相应菜单项的顺序
  • /boot/grub/grub.cfg :


grub

Grub设置通用配置变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# 配置文件信息
[[email protected] ~]# ls -alhs /etc/default/grub
4.0K -rw-r--r--. 1 root root 279 7月 17 2020 /etc/default/grub

# 打开GRUB配置文件可以看见一些常见的变量
[[email protected] ~]$ cat /etc/default/grub

# - 指定启动默认菜单项之前的停留时间
GRUB_TIMEOUT=5

# - 获取系统的发行版信息
GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"

# - 指定默认的启动项,可以设置为数字值或者saved,比如 0 表示第一个菜单项,或者设置为 “saved” 将指向上一次启动时选中的菜单项
GRUB_DEFAULT=saved

GRUB_DISABLE_SUBMENU=true

GRUB_TERMINAL_OUTPUT="console"

# - 传递给所有 Linux 菜单项的内核命令行参数。
GRUB_CMDLINE_LINUX="crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet"

# - 是否禁用恢复模式不生成恢复模式菜单项。
# 恢复模式菜单项会以单用户模式启动发行版,这种模式下允许你利用命令行工具修复系统。
GRUB_DISABLE_RECOVERY="true"

# - 指定了菜单上文本显示的分辨率,它可以设置为你的显卡所支持的任何数值。
GRUB_GFXMODE=1024x768


grub2.cfg and grub2-efi.cfg


grub.d 目录

描述:如果想要禁用 /etc/grub.d 目录下的脚本,你只需移除其可执行位,比如使用chmod -x /etc/grub.d/20_memtest86+ 就能将 Memory Test 选项从菜单中移除。

Grub菜单启动项

1
2
3
4
5
6
7
8
9
10
11
12
# 脚本的名称必须有两位的数字前缀。其目的是在构建 Grub 2 菜单时定义脚本的执行顺序以及相应菜单项的顺序
[[email protected] ~]# ls /etc/grub.d/ | grep ''
00_header : 首先被读取负责解析 /etc/default/grub 配置文件
00_tuned
01_users
10_linux : 存放Linux 内核的菜单项,该脚本脚本在默认的 /boot 分区为每个内核创建一个正规菜单项和一个恢复菜单项
20_linux_xen
20_ppc_terminfo
30_os-prober : 第三方应用所用脚本, 为内核和其它分区里的操作系统创建菜单项。它能识别安装的 Linux、 Windows、 BSD 以及 Mac OS X,如果你的硬盘布局比较独特使得 os-prober 无法找到已经安装的发行版你可以在 40_custom 文件进行设置;
40_custom : 第三方应用所用脚本,到无法找到发行版时候需要添加自定义菜单项中;
41_custom
README

_Grub引导文件:00_header_

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
```


Q: GRUB与文件系统的关系说明?
> 答: GRUB中根文件系统(root filesystem)与Linux的根文件系统是没有关系的!



---

#### 0x02 GRUB 相关命令
描述:然而在实际操作中 Grub 2 不需要你手动维护你的启动选项的配置文件:取而代之的是使用 `grub2-mkconfi`g 命令产生 /boot/grub/grub.cfg 文件
`
GRUB 命令分为内置命令(在引导界面bootloader 菜单按c进入`grub>`命令行模式界面)以及Linux安装的grub管理相关命令;

<br>

##### 内置命令
描述: 此处是您在引导程序显示界面bootloader 菜单按C进入GRUB的命令行模式之中;

以下命令可工作`在 grub> 和 grub rescue> 提示符`下, 输入`grub > help` 查看其内置命令

**GRUB常用命令:**
- ls命令-列出 Grub 识别出的所有分区以及分隔格式信息
```bash
grub> ls
(hd0) (hd0,gpt1) (hd0,gpt2) (hd0,gpt3) (lvm/centos-root)
grub> ls (hd0,gpt1) # 获得分区的信息,比如文件系统类型、总体大小和最后修改时间
(hd0,gpt1): Filesystem is fat
grub> ls (hd0,5)/ # 显示文件系统的文件
lost+found/ var/ etc/ media/ bin/ initrd.gz
boot/ dev/ home/ selinux/ srv/ tmp/ vmlinuz

  • cat命令 - 读取磁盘中文件内容

    1
    grub> cat (lvm/centos-root)/etc/system-release
  • set命令 - 标记GRUB环境变量设置

  • linux命令 - 设置引导的内核镜像如/boot/vmlinuz-3.13.0-24-generic
  • initrd命令 - 指定初始化的映像文件类似于Windows中windows.wim文件

    1
    2
    3
    4
    grub> set pager=1 #设置显示分页,防止文本在屏幕上一滚而过
    grub> set root=(hd0,5)
    grub> linux /boot/vmlinuz-3.13.0-24-generic root=/dev/sda5
    grub> initrd /boot/initrd.img-3.13.0-24-generic
  • boot - Grub 将会引导进入指定的操作系统

    1
    grub> boot


grub2-mkconfig 命令

基础实例:

1
2
# 1.为 Grub 重新产生新的配置文件
grub-mkconfig -o /boot/grub/grub.cfg


grub2-install 命令

基础实例:

1
2
# 1.往 MBR 里安装一份 bootloader 的拷贝
sudo grub2-install /dev/sda


0x03 GRUB 引导方式的关系

legacy 启动

描述: 当系统为传统的引导方式下,并且未将/boot进行单独分区(与根分区在一起的情况),并且磁盘分区不采用LVM逻辑磁盘管理方式;

grub 的 Shell 终端下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 列出分区的同时一并列出了分区表方案(即 msdos)
grub> ls
(hd0) (hd0,msdos5) (hd0,msdos6) (hd1,msdos1)

# 在每个分区上面使用 ls 来查找你的根文件系统:
grub> ls (hd0,5)/ #你可以不写上分区名的 msdos 部分
lost+found/ var/ etc/ media/ bin/ initrd.gz boot/(未单独分区) dev/ home/ selinux/ srv/ tmp/ vmlinuz

# 假设你在 (hd0,5) 中找到根文件系统,请确保它包含 /boot/grub 目录,以及你想引导进入的内核镜像,如 vmlinuz-3.13.0-24-generic;
# Grub 指向我们想引导进入的发行版所在的分区
grub> set root=(hd0,5)
# 通知 Grub 内核镜像在分区中的位置,以及根文件系统的位置。最后一行设置虚拟文件系统文件的位置
grub> linux /boot/vmlinuz-3.13.0-24-generic root=/dev/sda5
grub> initrd /boot/initrd.img-3.13.0-24-generic

# Grub 将会引导进入指定的操作系统
grub> boot

如果你在 grub rescue> 提示符下,情况会有些许不同。
因为 bootloader 未能够找到并加载任何必需的模块,你需要手动添加这些模块:

1
2
3
4
5
6
7
8
9
10
grub rescue> set root=(hd0,5)
grub rescue> insmod (hd0,5)/boot/grub/normal.mod
# normal 模块激活时将会恢复到标准 grub> 模式。
grub rescue> normal
# 如果 linux 模块没加载采用的命令会进行添加linux模块
grub> insmod linux
# 如果这个模块已经加载你可以跟之前一样,把引导加载程序指向内核镜像和虚拟文件系统文件,然后使用 boot 启动发行版,完美收官
grub> linux /boot/vmlinuz-3.13.0-24-generic root=/dev/sda5
grub> initrd /boot/initrd.img-3.13.0-24-generic
grub> boot


UEFI 启动

描述: 最近几年上市的机器大部分都是支持 UEFI 该种方式进行引导,其特点是支持单块大硬盘(>=2T)所以常常把磁盘进行GPT分区格式, 但是它只支持64位的系统;

虽然在支持 UEFI 的机器调试坏掉的 Grub 2 增加了另一复杂的层次。但是恢复安装在 UEFI 机器上的 Grub 2 的和安装在非 UEFI 机器上的并没多大区别,只是新的固件处理方式不一样,从而导致了很多种恢复结果。
对于基于 UEFI 的系统,不要在 MBR 上安装任何东西。相反你要在 EFI 系统分区( ESP )里安装 Linux EFI bootloader,并且借助工具把它设置为 EFI 的默认启动程序, 该工具在Linux下是efibootmgr,而在window下则是bcdedit。

grub 的 shell 终端,采用UEFI启动并且BOOT引导盘单独分区引导设置

1
2
3
4
5
6
7
8
9
# 可以参考 /etc/grub2-efi.cfg 文件
grub> ls (hd0,2)/ # 实际上是 boot 分区
grub> set root=(hd0,2) # 设置引导进入的分区
# 告知 Grub 内核镜像在分区中的位置,以及根文件系统的位置,以及启动的语系等等
grub> linuxefi /vmlinuz-3.10.0-1127.el7.x86_64 root=/dev/mapper/centos-root ro crashkernel=auto rd.lvm.lv=centos/root rd.lvm.lv=centos/swap rhgb quiet LANG=zh_CN.UTF-8
# 初始化镜像
grub> initrdefi /initramfs-3.10.0-1127.el7.x86_64.img
# 加载配置的grub引导程序
grub> reboot

WeiyiGeek.grub手动引导重启后正常进入系统

WeiyiGeek.grub手动引导重启后正常进入系统


0x04 GRUB 自定义配置

描述:上面我们对bootloader或者说是grub的相关文件进行了一个简单的介绍,如果希望往 bootloader 菜单里添加菜单项,你需要在 40_custom文件里添加一个启动段;

1.菜单启动项配置

例如,你可以使用它展示一个菜单项来启动安装在可移动 USB 驱动里的 Linux 发行版。假设你的 USB 驱动器是 sdb1 ,并且 vmlinuz 内核镜像和虚拟文件系统都位于根 (/)目录下,在 40_custom 文件中添加以下内容:

1
2
3
4
5
6
7
8
9
10
11
# 1.设置菜单实体与菜单名称
menuentry "Linux on USB" {
# 把 grub 指向我们想引导进入的发行版所在的分区,相比使用设备和分区名,建议使用它们的 UUID 可以获得更精确结果可以采用 blkid 命令获取UUID
# /dev/sda2: UUID="4fa08d50-8363-4b98-9af9-1b4907fdadc7" TYPE="xfs" PARTUUID="48a46594-30b9-4d92-b8b1-184d0d9c67e5"
# set root=(hd1,1)
set root=UUID=4fa08d50-8363-4b98-9af9-1b4907fdadc7
# grub 内核镜像路径以及参数设置
linux /vmlinuz root=/dev/sdb1 ro quiet splash
# 设置虚拟内存文件系统文件的位置
initrd /initrd.img
}


0x05 GRUB 故障修复

GRUB 引导修复类型
描述:启动电脑后,当 GRUB 无法按照boot.img –> core.img –> /boot/grub/顺序执行时,会看到命令行界面,等待用户输入命令。此时可以通过输入 GRUB 内置的命令来修复 GRUB 引导。

由于boot.img是写在 MBR 中的,如果不能执行直接跟 GRUB 引导方式说再见了,所以执行boot.img一般没问题。boot.img不能识别任何文件系统,core.img的位置是硬编码进boot.img的,所以执行boot.img一般没问题。

因此,常见的引导问题集中在/boot/grub/,主要有两种对应有两种引导修复模式:

  • 1) GRUB Rescue 模式是 GRUB 无法找到/boot分区,也就无法找到/boot/grub/。修复方法可以参考:grub rescue 模式下修复
  • 2) GRUB Normal 模式是 GRUB 无法找到 GRUB 菜单grub.cfg,无法选择合适的内核或系统来启动。修复方法可以参考:Boot GNU/Linux from GRUB
1.图形化的引导修复

描述: 对于Grub的图形化修复我们选择Boot Repair 应用, 传统只需要点击按钮Grub 2 许许多多的问题都能轻易解决, 还可以让你定制 Grub 2 的选项
优点:漂亮小巧的应用有一个直观的用户界面,可以扫描并识别多种硬盘布局和分区方案,还能发现并正确识别安装在其中的操作系统, 并且可以处理传统计算机里的主引导记录 (MBR),也可以处理新型 UEFI 计算机中的GUID 分区表(GPT);

安装方式: Boot Repair 最简单的使用方式是安装到 Live Ubuntu 会话中
在一个 bootloader 损坏的机器上启动 Ubuntu Live 发行版,先通过添加它的 PPA 版本库来安装 Boot Repair ,命令如下:

1
2
3
4
5
6
7
8
# 1.添加软件PPA版本库并然后刷新版本库列表
sudo add-apt-repository ppa:yannubuntu/Boot Repair && sudo apt-get update

# 2.安装应用
sudo apt-get install -y Boot Repair

# 3.安装完毕后就启动应用,此时在显示它的界面(由一对按键组成)之前将会扫描你的硬盘
根据工具的指示,只需按下 Recommended Repair按钮,即可修复大部分坏掉的 bootloader ,修复 bootloader 之后会输出一个短小的 URL ,它包含了硬盘详尽的信息:分区信息以及重要的 Grub 2 文件(如 `/etc/default/grub` 和 `/boot/grub/grub.cfg` )的内容

referrence-

referrence-


2.Bootloader 急救

描述:Grub 2 引导问题会让系统处于几种不同状态, 当系统开机后本该显示 bootloader 菜单的地方会指示出系统的当前状态:

  • (1) 如果系统中止于 grub> 提示符,表明 Grub 2 模块已经被加载,但是找不到 grub.cfg 文件
  • (2) 如果前是完全版的 Grub 2 命令行 shell看到的是 grub rescue> 提示符表明 bootloader 不能找到 Grub 2 模块或者找不到任何引导文件
  • (3) 如果你的屏幕只显示 ‘GRUB’ 一词,表明 bootloader 找不到通常位于主引导记录里的最基本的信息。

解决办法:可以通过使用 live CD 或者在 Grub 2 shell 中修正此类错误;

如果 grub2-install 命令不能正常运作,使得你无法引导进入 Linux ,你需要完整地重装以及重新配置 bootloader, 任何拥有 chroot 工具的 Linux live CD 都可以实现这个目的,不过需要确保 live 介质的系统架构和硬盘上系统的架构一致
因此当你希望 chroot 到 64 位系统,你必须使用 amd64 live 发行版, 启动进入 live 发行版之后,首先需要检查机器上的分区;

  • Step 1.使用 fdisk -l 列出磁盘上所有分区,记录你想修复的 Grub 2 系统所在的分区。
  • Step 2.从安装在 /dev/sda5 中的发行版中恢复 bootloader 。启动终端使用如下命令挂载分区:sudo mount /dev/sda5 /mnt
  • Step 3.绑定Grub 2 bootloader 需要进入的目录,以便检测其它操作系统:
    1
    2
    3
    4
    $ sudo mount --bind /dev /mnt/dev
    $ sudo mount --bind /dev/pts /mnt/dev/pts
    $ sudo mount --bind /proc /mnt/proc
    $ sudo mount --bind /sys /mnt/sys
  • Step 4.离开 live 环境进入安装在 /dev/sda5 分区中的发行版了,通过 chroot :
    1
    $ sudo chroot /mnt /bin/bash  # 灵魂
  • Step 5.现在可以安装、检测、以及升级 Grub 了,跟之前一样,使用下面的命令来重装 bootloader;
    1
    2
    sudo grub2-install /dev/sda
    sudo grub-mkconfig -o /boot/grub/grub.cfg # 同时生成引导配置
  • Step 6.现在你就有了 Grub 2 的一份全新拷贝,罗列了机器上所有的操作系统和发行版。在重启电脑之前,你需要依次退出 chroot 系统卸载所有分区,然后在重新后bootloader将被修复, 如下所示:
    1
    2
    3
    $ exit
    $ sudo umount /mnt/{sys,proc,dev/pts,dev,}
    $ sudo umount /mnt


3.UEFI启动Grub2引导程序修复

描述:如果 bootloader 损坏,你可以使用 live 发行版修复机器。在启动 live 介质之时,请确保是以 UEFI 模式启动。计算机每个可移动驱动器的启动菜单将会有两个: 一个普通的和一个以 EFI 标记的。使用后者会用到 /sys/firmware/efi/ 文件中的 EFI 变量。

在 live 环境中,挂载教程前面所提的安装挂掉系统的根文件系统。除此之外还需要挂载 ESP 分区。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 1.假设分区是 `/dev/sda1`你可以如下所示挂载
sudo mount /dev/sda1 /mnt/boot/efi

# 2.接着在 chroot 到安装完毕的发行版前之前,使用 modprobe efivars 加载 efivars 模块。
chroot sysroot/
modprobe efivars

# 3.Fedora 用户可以使用如下命令重新安装 bootloader
yum reinstall grub2-efi shim
# Ubuntu 用户则改用以下命令 :apt-get install --reinstall grub-efi-amd64
# 3. 先产生新的配置文件grub2引导配置保存到/boot/grub2/grub.cfg之中
grub2-mkconfig -o /boot/grub2/grub.cfg

# 4.一旦 bootloader 正确就位,退出 chroot ,卸载所有分区重启到 Grub 2 菜单。


0x06 GRUB 引导实战记录

1.系统迁移之SSD分区添加GRUB引导

环境说明:

1
2
3
4
5
6
7
8
9
10
引导方式为 BIOS + GPT(分区表类型) 
/dev/sdb为 SSD,当前 SSD 为空盘
# (注:文中出现的/dev/sdb1,/dev/sdf1和后面可能出现的/dev/sd#1都为同一个分区,因为多次插拔了 SSD ,所以标识一直按字母序递增)

# 分区创建规划
不建立/swap分区了,因为 Ubuntu17.04也要移除 swap 分区。
/dev/sdf1分区,建立 GRUB 引导所需分区,大小为 1M,分区文件类型为unformatted,分区 flag 为bios_grub。
/dev/sdf2分区,Linux /boot分区,大小 1G。
/dev/sdf3分区,Linux /分区,大小 50G。
/dev/sdf4分区,Linux /home分区,大小 300G。

操作流程:

  • Step 1.硬盘状态,使用外接硬盘盒,将 SSD 连接到 PC 机上,先查看硬盘状态:
    1
    2
    3
    4
    5
    $ sudo fdisk -l
    Disk /dev/sdb: 489.1 GiB, 525112713216 bytes, 1025610768 sectors
    Units: sectors of 1 * 512 = 512 bytes
    Sector size (logical/physical): 512 bytes / 512 bytes
    I/O size (minimum/optimal): 512 bytes / 33553920 bytes
  • Step 2.分区操作在 Gparted 软件中完成,命令行fdisk和parted也可以操作
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    #建立分区表
    #SSD 是一个空磁盘,此时并没有分区表,所以要先建立分区表。分区表的格式选用 GPT:
    1.打开 Gparted,点击 Device --> Created Partition Table。
    2.选择partition tabel type为gpt,然后点击Apply。

    #建立 GRUB 所需分区
    1.分区大小为1M,分区类型为unformatted。
    2.在新建的分区上点击右键,选择managerFlags,然后选中bios_grub选项。

    #建立 Linux 系统分区
    3.根据分区创建规划依次建立其他分区,分区的文件格式选择ext4。

    # 分区结果
    $ sudo fdisk -l /dev/sdh
    Device Start End Sectors Size Type
    /dev/sdh1 2048 4095 2048 1M BIOS boot
    /dev/sdh2 4096 2101247 2097152 1G Linux filesystem #/boot
    /dev/sdh3 2101248 106958847 104857600 50G Linux filesystem
    /dev/sdh4 106958848 736104447 629145600 300G Linux filesystem
    WeiyiGeek.Gparted分区

    WeiyiGeek.Gparted分区

  • Step 3.可以参考(grup-install教程)[http://www.gnu.org/software/grub/manual/html_node/Installing-GRUB-using-grub_002dinstall.html]来安装 GRUB 到 SSD 盘
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    # 1.挂载 SSD 的/boot 到 /mnt
    $ sudo mount /dev/sdb2 /mnt

    # 2.将 GRUB 配置文件放入 SSD 的/boot/grub中。
    $ sudo grub-install --target=i386-pc --root-directory=/mnt --recheck --debug /dev/sdb
    # ...
    # Installation finished. No error reported.

    # 3.此时/mnt目录下,应该有一个./boot/grub的文件夹:
    /mnt/boot/grub 20:54:33
    $ ls
    fonts grubenv i386-pc locale

    # 4.修复/grub位置,查看下 PC Ubuntu 的/boot,/grub是直接放置在/boot下的:
    /boot/grub 13:30:33
    $ ls
    fonts gfxblacklist.txt grub.cfg grubenv i386-pc locale unicode.pf2

    # 5.而grub-install /dev/sdb安装的 GRUB 是/mnt/boot/grub,其中/mnt是 SSD /dev/sdb2分区,从 SSD 启动 Ubuntu 的话,/dev/sdb2会挂载为/boot,此时 GRUB 的位置是/boot/boot/grub
    # 而当grub-install /dev/dsa安装 GRUB 到 PC Ubuntu 启动磁盘时,生成的/grub是在/boot/grub。
    # grub-install的处理逻辑应该是先判断/boot路径是否存在,没有就新建。 所以要将/mnt/boot/grub移动到/mnt/grub
    sudo mv /mnt/boot/grub /mnt/grub
  • Step 4.把 PC 硬盘中几个 Linux 分区的数据拷贝到 SSD 上对应的分区。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    # 1.复制/boot分区
    SSD Ubuntu 的/boot从 PC Ubuntu 上看为/dev/sdb2,将/dev/sdb2挂载为 PC Ubuntu 的/mnt
    GRUB 之后,/mnt已经有/grub这个文件夹和默认的lost+found文件夹, 此时使用cp将 PC 的/boot中其他文件复制到/mnt。
    /mnt/ 13:56:06
    $ ls | sort
    abi-4.8.0-36-generic
    config-4.8.0-36-generic
    grub
    initrd.img-4.8.0-36-generic
    lost+found
    memtest86+.bin
    memtest86+.elf
    memtest86+_multiboot.bin
    System.map-4.8.0-36-generic
    vmlinuz-4.8.0-36-generic


    # 2.复制/分区
    SSD Ubuntu 的/分区(根目录)比较特殊:一些子目录挂载了其他分区,并存在“伪目录”,不同子目录有特定的用途。
    所以复制/分区是有选择性的,不区分子目录进行复制,可能会提示“权限问题”、“无法访问”等错误。

    不需要复制的目录
    * /boot,/home(实际情况选择),/mnt挂载了其他分区
    * /media /cdrom 挂载可移除的媒体(cdrom 等)
    * /swap交换分区(不需要交换分区了)

    需要复制的目录
    * /bin 系统可执行文件
    * /etc 系统核心配置文件
    * /opt 用户程序文件
    * /root root用户主目录
    * /sbin 系统可执行文件
    * /usr 程序安装目录
    * /var 系统运行目录

    需要手动创建的目录:
    #在/mnt中需要给 SSD 的/创建几个空目录, Linux 内核启动后由内核来挂载并存放信息的,不能从运行中的 PC Ubuntu 复制过去,但是需要建立空目录
    # 不然内核启动后会报类似错误:mount: mount point /dev does not exist
    * /dev 主要存放与设备(包括外设)有关的文件
    * /proc 正在运行的内核信息映射
    * /sys 硬件设备的驱动程序信息
    $ sudo mkdir /mnt/{dev,proc,sys}


    # 3.复制/home分区
    $ sudo mount /dev/sdb4 /mnt
    $ sudo cp -rf -a /home/* /mnt
  • Step 5.迁移完成后 SSD Ubuntu 的/home和/boot需要挂载到/,挂载方法为:修改/ect/fstab。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    # 使用blkid查看 SSD 各分区` / /boot /home `的 UUID
    $ sudo blkid
    /dev/sdb3 UUID="a5eb2b0c-2104-4afe-aa78-93396d3e0986" TYPE="ext4" PARTUUID="b2708ce0-07"

    # 修改 SSD Ubuntu 的fstab文件 (示例如下)
    $ sudo vim /mnt/etc/fatab
    # <file system> <mount point> <type> <options> <dump> <pass>
    # / was on /dev/sda3 during installation
    UUID=a5eb2b0c-2104-4afe-aa78-93396d3e0986 / ext4 errors=remount-ro 0 1
    #
    # /boot was on /dev/sda2 during installation
    UUID=8cba10c6-dff2-4300-a630-ab0e7a4782af /boot ext4 defaults 0 2
    #
    # /home was on /dev/sda4 during installation
    UUID=298ba5ad-d306-4b4a-aaa8-54312590dec6 /home ext4 defaults 0 2
  • Step 6.将 SSD 通过 USB 插入到笔记本,开机,选择从 USB 启动。此时应该会是看到类似下图的画面。说明已经进入到 GRUB 引导程序中,但是没有 GRUB 启动选项,无法继续引导了。距离成功仅剩一步修复 GRUB 引导。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # 1.指定/boot分区和/grub位置*
    grub> set root=hd0,gpt2
    grub> set prefix=(hd0,gpt2)/grub


    # 2.设置启动的 Linux 内核以及参数设置
    grub> linux /vmlinuz-4.8.0-36-generic ro root=/dev/sda2

    # 3.设置虚拟内存镜像
    grub> initrd /initrd.img-4.8.0-36-generic

    # 4.启动 SSD Ubuntu
    grub> boot
  • Step 7.系统开机后需要重建 GRUB 引导(不用每次都执行第6步操作)

    1
    2
    3
    # 更新了 GRUB 可引导的系统/内核列表:/boot/grub/grub.cf,并重新安装了 GRUB
    $ sudo update-grub
    $ sudo grub-install /dev/dsa
WeiyiGeek.引导构建成功

WeiyiGeek.引导构建成功


0x07 F&Q

知识小结

Q: BIOS 与 UEFI 在 Bootloader 中处于怎样的角色?

答: 它们是系统自检成功后同时进行BIOS或者UEFI引导,然后读取磁盘中的第一个分区位置(MBR/GPT分区表存放位置不同,并且受引导方式的影响),以MBR为例其启动代码(boot.img)指向并执行 GRUB 内核镜像(core.img),最后从/boot/grub中读取配置和其他功能代码,系统屏幕显示Bootloader引导界面。


Referrence

参考地址: