tags: Linux
OS
GRUB
硬盤分區
背景
2016年雙十一入手了一塊500G的 SSD(Solid State Drive,固態硬盤),打算安裝到自己的筆記本上。筆記本的 HDD(Hard Disk Drive,機械硬盤)已經跑了 Ubuntu16.10 + Win10 雙系統。光驅位的硬盤支架也裝好了,一直虛位以待。工作忙一直拖到了2017年。
公司的 PC 機器也是 Ubuntu16.10,并且安裝的軟件比較齊全,所以計劃將 PC 的 Ubuntu16.10 遷移到 SSD 上,然后在筆記本上運行。
開工準備
- Ubuntu16.10,PC 上安裝,各項遷移步驟運行的環境并作為要遷移到 SSD 的系統。
- Gparted Partition Editor,圖形化的分區工具。
- 外接硬盤盒,通過 USB 線將 SSD 連接到 PC 上。
基礎知識
該章節是計算機啟動和系統加載的一些概念,有助于加深對遷移原理的理解,注重實踐的話可以直接跳過。
總結不一定準確,僅作為個人理解。干貨可以看這篇文章:uefi-boot-how-does-that-actually-work-then
BIOS vs UEFI
BIOS(Basic Input/Output System)和 UEFI(Unified Extensible Firmware Interface )是不同的計算機啟動固件(Fireware),需要硬件(通常為主板)支持,相互代替的,其中 UEFI 是比較新的方式。
BIOS
經典的啟動固件,會調用磁盤的 MBR,然后由 MBR 中的 loader 繼續加載操作系統。UEFI
UEFI 用來代替 BIOS,并克服 BIOS 的缺點,大多數的 UEFI 固件會提供兼容 BIOS 的啟動方式。區別
可以看這篇文章:[UEFI是什么?與BIOS的區別在哪里?][UEFI是什么?與BIOS的區別在哪里]
MBR vs GPT
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][What’s the Difference Between GPT and MBR When Partitioning a Drive]
File System
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 分區
硬盤狀態
使用外接硬盤盒,將 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 引導》章節。
-
先上分區結果:
partition-result.png
(注:前文出現的/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
。
create-gpt.png
- 建立 GRUB 所需分區
-
分區大小為1M,分區類型為
unformatted
。
bios-grub-partition.png -
在新建的分區上點擊右鍵,選擇
managerFlags
,然后選中bios_grub
選項。
set-bios-grub-flag.png
- 建立 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 引導
GRUB 是什么
GRUB(Grand Unified Boot loader)是硬盤中的軟件,引導器(loader)的一種。目前主流版本是 GRUB2,可以看 [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
示例:
如圖:第一個選項和最后一個選項是選擇不同的操作系統;第一個選項和第二個選項是選擇不同的內核配置。
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
的分區。
建立 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 引導修復類型
啟動電腦后,當 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
GRUB 引導修復
將 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 引導可以解決該問題。
重建 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 凌亂的分區圖,紀念這幾年裝機折騰的日子。折騰中總有收獲。
Refenrences
- UEFI是什么?與BIOS的區別在哪里
http://www.ihacksoft.com/uefi.html
[UEFI是什么?與BIOS的區別在哪里]:http://www.ihacksoft.com/uefi.html
- Linux:系統啟動引導過程
- What’s the Difference Between GPT and MBR When Partitioning a Drive
http://www.howtogeek.com/193669/whats-the-difference-between-gpt-and-mbr-when-partitioning-a-drive/
[What’s the Difference Between GPT and MBR When Partitioning a Drive]:http://www.howtogeek.com/193669/whats-the-difference-between-gpt-and-mbr-when-partitioning-a-drive/
- 6 Stages of Linux Boot Process (Startup Sequence)
- GRUB2 中文介紹
https://my.oschina.net/guol/blog/37373
[GRUB2 中文介紹]:https://my.oschina.net/guol/blog/37373