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 中文介紹