准備開整
基本步驟
步驟一: 格式化U盤
注意點: bios_grub標記的分區
步驟二: 安裝grub到U盤
步驟三: 添加grub菜單
參考文獻
前言: 生命不息,折騰不止。在折騰中進步,在踩坑中成長。
准備開整
U盤一枚(4G容量以上,備份好數據,一會可能要重新格式化)
可用的任意操作系統,64位(32位就不要折騰UEFI了)
UEFI與ESP預備知識,限於篇幅就不詳細介紹了,自己看文檔原理
USB啟動的原理就不多做講解了,有興趣的話找找相關的文檔,介紹很多,也很詳細,跟硬碟引導過程差不多。注意的是BIOS+MBR模式和UEFI+GPT模式是不同的。
基本步驟
先說一下我的環境,金士頓16G U盤一個,操作系統是Deepin 2014.3 64bit,基於Ubuntu 14.04,其他類似的系統可以類比。Linux系統本來就使用grub引導(不要在CentOS/RHEL 6及以下版本折騰了,那個是Grub Legacy,已經不維護了),折騰起來要比其他操作系統方便的多,軟體倉庫就有grub相關的軟體包,也不需要單獨安裝太多東西。Windows下可以用grub2win,原理是一樣的。
步驟一: 格式化U盤
想要支持UEFI引導,GPT是不可少了,而且GPT是兼容MBR了。所以第一步需要先將U盤格式化為GPT分區,這樣efi文件可以和MBR共存,實現UEFI和BIOS雙支持。
如果U盤已經是
Linux下支持GPT分區的工具: parted, gdisk。大致的步驟就是使用gdisk(命令和操作方式幾乎和fdisk完全一樣,只是支持GPT),或parted對U盤重新分區,然後標記ESP。如果用gdisk,只要給分區標記EF00編號即可,如果用parted,給分區boot標記即可。命令行就不演示了,很簡單,我這邊截圖使用圖形化工具gparted分區,同樣結果也是GPT分區。
圖形化的gparted操作也很簡單,建立GPT分區表,分區,格式化為FAT32(注: 盡管ESP支持多種分區,但是為了通用性與兼容性還是建議FAT32),標記分區為boot
這樣U盤處理就完成了,使用gdisk或parted顯示一下U盤的信息,看到這樣的信息就是OK的
$ sudo gdisk-l/dev/sdb# 根據你的U盤的名字修改dev設備
GPT fdisk(gdisk)version0.8.8
Partitiontable scan:
MBR:protective# <========================= 保護性的MBR,這個是GPT兼容MBR的一種設計
BSD:notpresent
APM:notpresent
GPT:present# <========================= 看這里,已經是GPT了
Foundvalid GPTwithprotective MBR;usingGPT.# <========== 這里的顯示也說明是GPT分區
Disk/dev/sdb:30736384sectors,14.7GiB
Logicalsector size:512bytes
Diskidentifier(GUID):022EE53E-9641-4D28-9394-0826CFA24730
Partitiontable holds up to128entries
Firstusable sectoris34,lastusable sectoris30736350
Partitionswill be aligned on2048-sector boundaries
Totalfree spaceis4029sectors(2.0MiB)
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標志
- 11049kB15.7GB15.7GB fat32啟動,esp# <===== ESP已經設置成功
注意點: bios_grub標記的分區
這個要特別強調,bios_grub標記的分區必須存在,否則BIOS模式下無法使用。
有關bios_grub標記的分區說明:https://help.ubuntu.com/community/Installation/UEFI-and-BIOS#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.8Partition table scan:
- MBR: protective
- BSD: not present
- APM: not present
- GPT: presentFound valid GPT with protective MBR; using GPT.Command (? for help): nPartition 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): EF02Changed type of partition to 'BIOS boot partition'Command (? for help): pDisk /dev/sdb: 30736384 sectors, 14.7 GiBLogical sector size: 512 bytesDisk identifier (GUID): 0086B5EF-81D9-4BD1-816C-AD1EADCD2338Partition table holds up to 128 entriesFirst usable sector is 34, last usable sector is 30736350Partitions will be aligned on 2048-sector boundariesTotal free space is 2014 sectors (1007.0 KiB)Number Start (sector) End (sector) Size Code Name
- 2048 30734335 14.7 GiB EF00 30734336 30736350 1007.5 KiB EF02 BIOS boot partition # <== EF02對應的就是bios_grub這個標記Command (? for help): wFinal 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 printsudo gdisk /dev/sdb
- GPT fdisk (gdisk) version 0.8.8Partition table scan:
- MBR: protective
- BSD: not present
- APM: not present
- GPT: presentFound valid GPT with protective MBR; using GPT.Command (? for help): nPartition 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): EF02Changed type of partition to 'BIOS boot partition'Command (? for help): pDisk /dev/sdb: 30736384 sectors, 14.7 GiBLogical sector size: 512 bytesDisk identifier (GUID): 0086B5EF-81D9-4BD1-816C-AD1EADCD2338Partition table holds up to 128 entriesFirst usable sector is 34, last usable sector is 30736350Partitions will be aligned on 2048-sector boundariesTotal free space is 2014 sectors (1007.0 KiB)Number Start (sector) End (sector) Size Code Name
- 2048 30734335 14.7 GiB EF00 30734336 30736350 1007.5 KiB EF02 BIOS boot partitionCommand (? for help): wFinal 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 printModel: Kingston DataTraveler 3.0 (scsi)磁碟 /dev/sdb: 15.7GBSector size (logical/physical): 512B/512B分區表:gptDisk Flags: 數字 開始: End 大小 文件系統 Name 標志
- 1049kB 15.7GB 15.7GB fat32 啟動, esp 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/sdbInstalling 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 --removableInstalling 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-pc或grub-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=rootuuidset 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都可以引導了
補充: 稍作美化一下效果,只不過那個從本地硬碟啟動還沒實現,需要看看別人怎麼寫的。