Linux
OS
GRUB
硬盘分区
2016年双十一入手了一块500G的 SSD(Solid State Drive,固态硬盘),打算安装到本身的笔记本上。笔记本的 HDD(Hard Disk Drive,机械硬盘)已经跑了 Ubuntu16.10 + Win10 双系统。光驱位的硬盘支架也装好了,一直虚位以待。工做忙一直拖到了2017年。html
公司的 PC 机器也是 Ubuntu16.10,而且安装的软件比较齐全,因此计划将 PC 的 Ubuntu16.10 迁移到 SSD 上,而后在笔记本上运行。node
Ubuntu16.10,PC 上安装,各项迁移步骤运行的环境并做为要迁移到 SSD 的系统。linux
[Gparted Partition Editor],图形化的分区工具。ios
外接硬盘盒,经过 USB 线将 SSD 链接到 PC 上。ubuntu
该章节是计算机启动和系统加载的一些概念,有助于加深对迁移原理的理解,注重实践的话能够直接跳过。vim
总结不必定准确,仅做为我的理解。干货能够看这篇文章:uefi-boot-how-does-that-actually-work-thensass
BIOS(Basic Input/Output System)和 UEFI(Unified Extensible Firmware Interface )是不一样的计算机启动固件(Fireware),须要硬件(一般为主板)支持,相互代替的,其中 UEFI 是比较新的方式。安全
BIOS
经典的启动固件,会调用磁盘的 MBR,而后由 MBR 中的 loader 继续加载操做系统。app
UEFI
UEFI 用来代替 BIOS,并克服 BIOS 的缺点,大多数的 UEFI 固件会提供兼容 BIOS 的启动方式。ide
区别
能够看这篇文章:UEFI是什么?与BIOS的区别在哪里?
MBR 与 GPT 用于存储硬盘的分区信息,是不一样的硬盘分区表类型。
MBR
MBR 表示 MBR 分区表,MBR 分区表在硬盘开头处存放了特殊的启动分区,称为 MBR(Master Boot Record,主启动记录),包含 Boot Loader 和硬盘逻辑分区。MBR 支持最大约2T的硬盘,最多能划分4个主分区,更多分区须要使用拓展分区实现。
(MBR
在行文中能够表示 MBR 分区表
和主启动记录
两个意思,注意甄别。)
GPT
GPT 表示 GUID(Globally Unique Identifier) 分区表,是 UEFI 规范的一部分,用于替换 MBR 的分区方式。GPT 没有分区数和分区大小限制。
区别
能够看这篇文章:What’s the Difference Between GPT and MBR When Partitioning a Drive
File System(文件系统)是存储媒介中文件存储的组织方式。
不一样的文件系统类型有不一样的速度,灵活性,安全性和占用空间。不一样操做系统只支持特定的文件系统类型。
常见的文件系统类型有 FAT16,FAT32,NTFS,EXT3,EXT4,HFS 等。
Wikipedia 上有许多关于磁盘的资料,在磁盘分区上,我猜想的发展脉络是这样的:
磁盘跟内存同样直接物理寻址去访问数据;
为了方便,创建数据 Index,有了 File System;
须要多个分区,搞出了 Partition Tabel。
BIOS/UEFI 跟 MBR/GPT 是不一样层级的,BIOS/UEFI 是 Fireware,MBR/GPT 是分区表。
推荐的使用方式: BIOS + MBR 或 UEFI + GPT:
If you want to do a ‘BIOS compatibility’ type installation, you probably want to install to an MBR formatted disk.
If you want to do a UEFI native installation, you probably want to install to a GPT formatted disk.
理论上来讲是能够组合使用的:
Of course, to make life complicated, many firmwares can boot BIOS-style from a GPT formatted disk.
UEFI firmwares are in fact technically required to be able to boot UEFI-style from an MBR formatted disk.
Windows 一般会要求 UEFI 的启动方式使用 GPT,否则不给继续安装。
使用外接硬盘盒,将 SSD 链接到 PC 机上,先查看硬盘状态:
$ sudo fdisk -l Disk /dev/sda: 465.8 GiB, 500107862016 bytes, 976773168 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes Disklabel type: dos Disk identifier: 0xb2708ce0 Device Boot Start End Sectors Size Id Type /dev/sda1 * 2048 411647 409600 200M 7 HPFS/NTFS/exFAT /dev/sda2 411648 210126847 209715200 100G 7 HPFS/NTFS/exFAT /dev/sda3 210128894 913704959 703576066 335.5G f W95 Ext'd (LBA) /dev/sda5 210128896 703989759 493860864 235.5G 83 Linux /dev/sda6 703991808 704966655 974848 476M 83 Linux /dev/sda7 704968704 764067839 59099136 28.2G 83 Linux /dev/sda8 764069888 771973119 7903232 3.8G 82 Linux swap / Solaris Partition 3 does not start on physical sector boundary. 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
其中/dev/sda
为 PC 上的硬盘,装有 Ubuntu16.10 + Win7;/dev/sdb
为 SSD,当前 SSD 为空盘。
笔记本是 2011 年的机器,主板启动引导好像不支持 UEFI,是用 BIOS。
考虑 SSD 的拓展性,分区表选择 GPL,选用的引导方式为 BIOS + GPT。
此时安装 GRUB 引导对分区划分有要求,具体参考接下文的《GRUB 引导》章节。
先上分区结果:
(注:前文出现的/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。
分区操做在 Gparted 软件中完成,命令行fdisk
和parted
也能够操做,可是我不熟悉。
创建分区表
SSD 是一个空磁盘,此时并无分区表,因此要先创建分区表。分区表的格式选用 GPT:
打开 Gparted,点击 Device
--> Created Partition Table
。
选择partition tabel type
为gpt
,而后点击Apply
。
创建 GRUB 所需分区
分区大小为1M,分区类型为unformatted
。
在新建的分区上点击右键,选择managerFlags
,而后选中bios_grub
选项。
创建 Linux 系统分区
根据上文<<分区策略>>章节,依次创建其余分区,分区的文件格式选择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 /dev/sdh3 2101248 106958847 104857600 50G Linux filesystem /dev/sdh4 106958848 736104447 629145600 300G Linux filesystem
GRUB(Grand Unified Boot loader)是硬盘中的软件,引导器(loader)的一种。目前主流版本是 GRUB2,能够看 GRUB2 中文介绍。
GRUB 用于从多操做系统的计算机中选择一个系统来启动,或从系统分区中选择特殊的内核配置。
provides a user the choice to boot one of multiple operating systems installed on a computer or select a specific kernel configuration available on a particular operating system's partitions. -- GRUB
示例:
如图:第一个选项和最后一个选项是选择不一样的操做系统;第一个选项和第二个选项是选择不一样的内核配置。
其启动代码(boot.img)直接安装在 MBR 中,而后执行 GRUB 内核镜像(core.img),最后从/boot/grub
中读取配置和其余功能代码。
BIOS 引导方式中,MBR 分区表和 GPT 分区表的 GRUB 引导文件所放分区不一样:
如图,GRUB 的执行顺序为 boot.img
--> core.img
--> /boot/grub/
。
在 MBR 分区表中,boot.img
和 core.img
都在 MBR 中。MBR 虽然只占用一个扇区(512Byte),可是其所在的磁道是空闲的,不会用于分区,能够放下 core.img
。
Some MBR code loads additional code for a boot manager from the first track of the disk, which it assumes to be "free" space that is not allocated to any disk partition, and executes it. -- MBR
在 GPT 分区表中,MBR 为 protected MBR(为兼容 MBR,在硬盘起始位置保留的空间),后面并无空间放core.img
,须要建一个专门的分区来放,称为BIOS boot partition,该分区的文件类型为unformatted
,flag 为BOIS_grub
,该 flag 用于标识core.img
所要安装到的分区。若果使用 UEFI 引导,GRUB 读取的是 ESP 分区中的数据,不须要 flag 为 BIOS_grub
的分区。
使用 grup-install 的教程来安装 GRUB 到 SSD 盘。
挂载 /boot
挂载 SSD 的/boot
为 PC Ubuntu 的/mnt
,由于咱们须要将 GRUB 配置文件放入 SSD 的/boot/grub
中。
$ sudo mount /dev/sdb2 /mnt
安装 GRUB
执行如下命令:
$ sudo grub-install --target=i386-pc --root-directory=/mnt --recheck --debug /dev/sdb
若是看到如下输出,应该就是成功了:
... Installation finished. No error reported.
此时/mnt
目录下,应该有一个./boot/grub
的文件夹:
/mnt/boot/grub ⌚ 20:54:33 $ ls fonts grubenv i386-pc locale
修复/grub
位置
查看下 PC Ubuntu 的/boot
,/grub
是直接放置在/boot
下的:
/boot/grub ⌚ 13:30:33 $ ls fonts gfxblacklist.txt grub.cfg grubenv i386-pc locale unicode.pf2
而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
启动电脑后,当 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/
,主要有两种,对应有两种引导修复模式:
GRUB Rescue 模式
GRUB Rescue 模式是 GRUB 没法找到/boot
分区,也就没法找到/boot/grub/
。修复方法能够参考:grub rescue 模式下修复。
GRUB Normal 模式
GRUB Normal 模式是 GRUB 没法找到 GRUB 菜单grub.cfg
,没法选择合适的内核或系统来启动。修复方法能够参考:Boot GNU/Linux from GRUB。
该步骤是把 PC 硬盘中几个 Linux 分区的数据拷贝到 SSD 上对应的分区。
(注意:PC Ubuntu 和 SSD Ubuntu 都有/
、/boot
、/home
分区,阅读下文时注意辨别,我有时并无写得很清晰。)
操做的套路是先将 SSD 的分区使用mount
命令挂载为 PC 的/mnt
,使用cp
命令复制数据,再用umount
命令移出这个分区;对下一个分区作一样操做。
挂载和移出操做
// 挂载 $ sudo mount /dev/sdb2 /mnt // 移出 $ sudo umount /mnt
复制操做
使用cp
指令要加-r
,-f
,-a
参数,-r
表示递归复制,-f
表示强制覆盖,-a
表示保留原文件的属性(mode,ownership,tiemstamps等)
$ sudo cp -rf -a source destination
/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
/
分区SSD Ubuntu 的/
分区(根目录)比较特殊:一些子目录挂载了其余分区,并存在“伪目录”,不一样子目录有特定的用途。
因此复制/
分区是有选择性的,不区分子目录进行复制,可能会提示“权限问题”、“没法访问”等错误。
不须要复制的目录
/boot
,/home
,/mnt
挂载了其余分区
/media
/cdrom
挂载可移除的媒体(cdrom 等)
/swap
交换分区(不须要交换分区了)
须要复制的目录
主要参考: Linux操做系统备份之二
/bin
系统可执行文件
/etc
系统核心配置文件
/opt
用户程序文件
/root
root用户主目录
/sbin
系统可执行文件
/usr
程序安装目录
/var
系统运行目录
须要手动建立的目录
在/mnt
中须要给 SSD 的/
建立几个空目录。
/dev
主要存放与设备(包括外设)有关的文件
/proc
正在运行的内核信息映射
/sys
硬件设备的驱动程序信息
这几个目录是 Linux 内核启动后由内核来挂载并存放信息的,不能从运行中的 PC Ubuntu 复制过去,可是须要创建空目录,否则内核启动后会报相似错误:
mount: mount point /dev does not exist
建立命令:
$ sudo mkdir dev proc sys
操做策略
每一个目录单独执行复制命令,出错了好处理。
/home
分区挂载 SSD Ubuntu/home
到 PC Ubuntu /mnt
,而后全盘复制:
$ sudo mount /dev/sdb4 /mnt $ sudo cp -rf -a /home/* /mnt
/home
和/boot
分区SSD Ubuntu 的/home
和/boot
须要挂载到/
,挂载方法为:修改/ect/fstab
。
挂载/dev/sda3
为 PC Ubuntu /mnt
使用blkid
查看 SSD 各分区的 UUID
$ sudo blkid ... /dev/sdb3 UUID="a5eb2b0c-2104-4afe-aa78-93396d3e0986" TYPE="ext4" PARTUUID="b2708ce0-07" ...
修改 SSD Ubuntu 的fstab
文件
$ sudo vim /mnt/etc/fatab
fstab
文件大概是这样子的:
# /etc/fstab: static file system information. # # Use 'blkid' to print the universally unique identifier for a # device; this may be used with UUID= as a more robust way to name devices # that works even if disks are added and removed. See fstab(5). # # <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
将 SSD 经过 USB 插入到笔记本,开机,选择从 USB 启动。此时应该会是看到相似下图的画面。
说明已经进入到 GRUB 引导程序中,可是没有 GRUB 启动选项,没法继续引导了。距离成功仅剩一步:修复 GRUB 引导。
指定/boot
分区和/grub
位置(好像不须要这步,GRUB Rescue 才须要)
// grub> root=hd0,gpt2 // grub> prefix=(hd0,gpt2)/grub grub> set root=hd0,gpt2 grub> set prefix=(hd0,gpt2)/grub
设置启动的 Linux 内核
grub> linux /vmlinuz-4.8.0-36-generic ro root=/dev/sda2
设置虚拟内存
grub> initrd /initrd.img-4.8.0-36-generic
启动 SSD Ubuntu
grub> boot
到这一步应该能够启动 SSD 的 Ubuntu,可是下次从新开机,又须要手动指定内核才能启动,经过在 SSD Ubuntu 中重建 GRUB 引导能够解决该问题。
从 SSD 开启 Ubuntu 成功后,执行如下命令:
$ sudo update-grub $ sudo grub-install /dev/dsa
以上命令更新了 GRUB 可引导的系统/内核列表:/boot/grub/grub.cf
,并从新安装了 GRUB。能够参考:Grub2/Installing。
笔记本下次开机,就能看到相似画面:
将 SSD 放入笔记本内置硬盘位,将旧的 HDD 放到光驱位置,开机,完成!(撒花)!
总共花了三天时间搞定这个事情,整理出文章花了N天,查看了不少资料,对计算机开机引导,硬盘分区和 GRUB 算是比较了解了。
如今笔记本有了 SSD + HDD,下一步可能会实践双硬盘的数据备份。
最后放上 HDD 凌乱的分区图,记念这几年装机折腾的日子。折腾中总有收获。
UEFI是什么?与BIOS的区别在哪里
Linux:系统启动引导过程
What’s the Difference Between GPT and MBR When Partitioning a Drive
6 Stages of Linux Boot Process (Startup Sequence)
GRUB2 中文介绍