[grub實現]U盤引導多個linux鏡像安裝,同時支持BIOS和UEFI模式

前言: 生命不息,折騰不止。在折騰中進步,在踩坑中成長。php

補: 個人grub.cfg配置已經託管到oschina git倉庫: http://git.oschina.net/abcfy2/grub-cfglinux

準備開整

  • U盤一枚(4G容量以上,備份好數據,一會可能要從新格式化)
  • 可用的任意操做系統,64位(32位就不要折騰UEFI了)
  • UEFIESP預備知識,限於篇幅就不詳細介紹了,本身看文檔原理

USB啓動的原理就很少作講解了,有興趣的話找找相關的文檔,介紹不少,也很詳細,跟硬盤引導過程差很少。注意的是BIOS+MBR模式和UEFI+GPT模式是不一樣的。ios

基本步驟

先說一下個人環境,金士頓16G U盤一個,操做系統是Deepin 2014.3 64bit,基於Ubuntu 14.04,其餘相似的系統能夠類比。Linux系統原本就使用grub引導(不要在CentOS/RHEL 6及如下版本折騰了,那個是Grub Legacy,已經不維護了),折騰起來要比其餘操做系統方便的多,軟件倉庫就有grub相關的軟件包,也不須要單獨安裝太多東西。Windows下能夠用grub2win,原理是同樣的。git

步驟一: 格式化U盤

想要支持UEFI引導,GPT是不可少了,並且GPT是兼容MBR了。因此第一步須要先將U盤格式化爲GPT分區,這樣efi文件能夠和MBR共存,實現UEFI和BIOS雙支持。ubuntu

Linux下支持GPT分區的工具: parted, gdisk。大體的步驟就是使用gdisk(命令和操做方式幾乎和fdisk徹底同樣,只是支持GPT),或parted對U盤從新分區,而後標記ESP。若是用gdisk,只要給分區標記EF00編號便可,若是用parted,給分區boot標記便可。命令行就不演示了,很簡單,我這邊截圖使用圖形化工具gparted分區,一樣結果也是GPT分區。bash

圖形化的gparted操做也很簡單,創建GPT分區表,分區,格式化爲FAT32(注: 儘管ESP支持多種分區,可是爲了通用性與兼容性仍是建議FAT32),標記分區爲bootide

建立分區表 分區表類型GPT 輸入圖片說明 輸入圖片說明 輸入圖片說明

這樣U盤處理就完成了,使用gdisk或parted顯示一下U盤的信息,看到這樣的信息就是OK的工具

$ sudo gdisk -l /dev/sdb  # 根據你的U盤的名字修改dev設備
GPT fdisk (gdisk) version 0.8.8

Partition table scan:
  MBR: protective      # <========================= 保護性的MBR,這個是GPT兼容MBR的一種設計
  BSD: not present
  APM: not present
  GPT: present         # <========================= 看這裏,已是GPT了

Found valid GPT with protective MBR; using GPT.   # <========== 這裏的顯示也說明是GPT分區
Disk /dev/sdb: 30736384 sectors, 14.7 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 022EE53E-9641-4D28-9394-0826CFA24730
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 30736350
Partitions will be aligned on 2048-sector boundaries
Total free space is 4029 sectors (2.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048        30734335   14.7 GiB    EF00         # <======== 這裏很關鍵,看Code是EF00,想要分區成爲ESP必須設置這個標記,若是手工用gdisk別忘了這一步

$ sudo parted /dev/sdb print
Model: Kingston DataTraveler 3.0 (scsi)
磁盤 /dev/sdb: 15.7GB
Sector size (logical/physical): 512B/512B
分區表:gpt                                 # <======= GPT分區
Disk Flags: 

數字  開始:  End     大小    文件系統  Name  標誌
 1  1049kB  15.7GB  15.7GB  fat32         啓動, esp      # <===== ESP已經設置成功

注意點: bios_grub標記的分區

這個要特別強調,bios_grub標記的分區必須存在,不然BIOS模式下沒法使用oop

有關bios_grub標記的分區說明: https://help.ubuntu.com/community/Installation/UEFI-and-BIOS/original-attempt#Make_a_system_bootable_in_UEFI_as_well_as_BIOS測試

這裏我簡單說起一下這個標記的做用。上面提到過,GPT兼容MBR,若是要讓grub在GPT上使用MBR模式安裝的話,須要設置這個標記。按照ubuntu官方文檔(上面那個文檔,想了解詳細的話必看!),這個分區有如下幾個特色:

  • 1MB容量
  • 不須要格式化
  • 設置bios_grub標記

若是用gdisk, parted, gparted這些工具分區的時候,你會發現總會有一個1MB的剩餘空間,就是幹這個用的,如今,我只須要給這個剩餘空間分區,並打上bios_grub標記就好了(EF02),不用格式化。parted操做也相似

sudo gdisk /dev/sdb
# 下面能夠看到gdisk的操做幾乎和fdisk徹底同樣,熟悉fdisk能夠無壓力上手

GPT fdisk (gdisk) version 0.8.8

Partition table scan:
  MBR: protective
  BSD: not present
  APM: not present
  GPT: present

Found valid GPT with protective MBR; using GPT.

Command (? for help): n
Partition number (2-128, default 2): 
First sector (34-30736350, default = 30734336) or {+-}size{KMGTP}: 
Last sector (30734336-30736350, default = 30736350) or {+-}size{KMGTP}: 
Current type is 'Linux filesystem'
Hex code or GUID (L to show codes, Enter = 8300): EF02
Changed type of partition to 'BIOS boot partition'

Command (? for help): p
Disk /dev/sdb: 30736384 sectors, 14.7 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 0086B5EF-81D9-4BD1-816C-AD1EADCD2338
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 30736350
Partitions will be aligned on 2048-sector boundaries
Total free space is 2014 sectors (1007.0 KiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048        30734335   14.7 GiB    EF00  
   2        30734336        30736350   1007.5 KiB  EF02  BIOS boot partition # <== EF02對應的就是bios_grub這個標記

Command (? for help): w

Final checks complete. About to write GPT data. THIS WILL OVERWRITE EXISTING
PARTITIONS!!

Do you want to proceed? (Y/N): y
OK; writing new GUID partition table (GPT) to /dev/sdb.
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot.
The operation has completed successfully.


$ sudo parted /dev/sdb print
Model: Kingston DataTraveler 3.0 (scsi)
磁盤 /dev/sdb: 15.7GB
Sector size (logical/physical): 512B/512B
分區表:gpt
Disk Flags: 

數字  開始:  End     大小    文件系統      Name                 標誌
 1    1049kB  15.7GB  15.7GB  fat32                          啓動, esp
 2    15.7GB  15.7GB  1032kB            BIOS boot partition  bios_grub  # <== 要的就是這個!

至此分區的步驟就完成了。若是你已是GPT分區了,就不用從新分區了,只要處理成ESP就好了

步驟二: 安裝grub到U盤

這一步相比上一步已經簡單許多了,但仍是有一個小坑須要注意。先貼命令:

$ sudo mount /dev/sdb1 /mnt -o uid=$USER,gid=$USER  # 沒什麼好說的,掛載U盤使用,加上uid和gid參數只是爲了編輯文件不須要sudo而已

# grub安裝到MBR
$  sudo grub-install --target=i386-pc --recheck --boot-directory=/mnt/boot /dev/sdb
Installing for i386-pc platform.
Installation finished. No error reported.

# grub安裝到ESP,特別注意--removable參數,安裝到移動設備上必定要用這個參數
$ sudo grub-install --target x86_64-efi --efi-directory /mnt --boot-directory=/mnt/boot --removable
Installing for x86_64-efi platform.
Installation finished. No error reported.

命令沒有任何難度,可是有幾個坑須要特別注意:

  • Ubuntu的分包問題 grub默認的target是i386-pc,這個target包含在grub-pc這個包,若是你的系統使用BIOS+MBR安裝,這個包默認是存在的。x86_64-efi這個target包含在grub-efi這個包,只有你的系統使用UEFI+GPT方式安裝這個包纔會存在。若是某個target報錯,錯誤信息相似於grub-install: error: /usr/lib/grub/x86_64-efi/modinfo.sh doesn't exist. Please specify --target or --directory. 這樣的話,就須要安裝grub-pcgrub-efi以後再試。

  • 安裝到ESP要加--removable這個參數 這個參數專門針對於可移動設備,必定要加

  • bios_grub標記的分區 若是按照上面的分區過程操做了,增長了這個標記的分區,安裝grub的時候會自動識別這個標記的分區併成功安裝grub,不然報錯:

Installing for i386-pc platform.
grub-install: warning: this GPT partition label contains no BIOS Boot Partition; embedding won't be possible.
grub-install: warning: 沒法嵌入。在這次安裝中 GRUB 只能經過使用塊列表安裝。可是塊列表是不可信賴的,不推薦使用。.
grub-install:錯誤: will not proceed with blocklists.

步驟三: 添加grub菜單

若是前面都沒問題的話,最後就只剩下添加grub菜單了。在/mnt/boot/grub這個目錄下,新建grub.cfg配置文件就好了。grub2的語法很複雜,圖省事就從網上各類摘抄拼接就好了。好比我把linux發行版的iso鏡像都扔到了boot/iso這個目錄,因而乎個人grub.cfg成了這樣:

# path to the partition holding ISO images (using UUID)
probe -u $root --set=rootuuid
set imgdevpath="/dev/disk/by-uuid/$rootuuid"

# define globally (i.e outside any menuentry)
insmod search_fs_uuid
search --no-floppy --set=isopart --fs-uuid $rootuuid
insmod all_video

menuentry "Linux Mint cinnamon 64bit ISO" {
 set isofile=/boot/iso/linuxmint-17.2-cinnamon-64bit.iso
 loopback loop ($isopart)$isofile
 linux (loop)/casper/vmlinuz file=/cdrom/preseed/linuxmint.seed boot=casper iso-scan/filename=$isofile noeject noprompt splash locale=zh_CN.UTF-8 --
 initrd (loop)/casper/initrd.lz
}

menuentry "Ubuntu Desktop 64bit ISO" {
 set isofile=/boot/iso/ubuntu-14.04.3-desktop-amd64+mac.iso
 loopback loop ($isopart)$isofile
 linux (loop)/casper/vmlinuz file=/cdrom/preseed/ubuntu.seed boot=casper iso-scan/filename=$isofile noeject noprompt splash locale=zh_CN.UTF-8 --
 initrd (loop)/casper/initrd.lz
}

menuentry "UbuntuKylin Desktop 64bit ISO" {
 set isofile=/boot/iso/ubuntukylin-14.04.3-desktop-amd64.iso
 loopback loop ($isopart)$isofile
 linux (loop)/casper/vmlinuz.efi boot=casper iso-scan/filename=$isofile noeject noprompt splash locale=zh_CN.UTF-8 --
 initrd (loop)/casper/initrd.lz
}

menuentry "Ubuntu Server 64bit ISO" {
 set isofile=/boot/iso/ubuntu-14.04.3-server-amd64+mac.iso
 loopback loop ($isopart)$isofile
 set gfxpayload=keep
 linux (loop)/install/vmlinuz file=/cdrom/preseed/ubuntu-server.seed iso-scan/filename=$isofile quiet --
 initrd (loop)/install/initrd.gz
}

menuentry "Deepin 2014 ISO" {
 set isofile=/boot/iso/deepin_2014.3_amd64.iso 
 loopback loop ($isopart)$isofile
 linux (loop)/casper/vmlinuz boot=casper iso-scan/filename=$isofile noeject noprompt splash locale=zh_CN.UTF-8 --
 initrd (loop)/casper/initrd.lz
}

根據本身的需求增刪改改就好了。想進一步美化的話,grub2關於美化的文檔也不少,就不贅述了。

注意: 不要使用虛擬機測試,由於虛擬機不能完整模擬主板。所以不必定能引導你的U盤,讓你誤覺得製做失敗了。儘量用真機去測試引導。

最後,貼一個效果圖,能夠看到BIOS模式和UEFI均可以引導了

輸入圖片說明輸入圖片說明

補充: 稍做美化一下效果

輸入圖片說明

參考文獻

相關文章
相關標籤/搜索