Linux伺服器 Linux伺服器

資工所專業課程上課教材

資工所專業課程 > 課程內容 > 專題七 - 以虛擬機器模擬 EFU 取代 BIOS 環境

專題七 - 以虛擬機器模擬 EFU 取代 BIOS 環境

上次更新日期 2019/08/21

目前的硬碟容量已經越來越大,甚至已經有 8T 的產品。傳統的主機 BIOS 由於某些限制的關係,使用 MBR (MSDOS partition type) 只能抓到 2TB 的開機硬碟,這就造成些許問題。目前有所謂的 GPT 分割表,Linux 可以使用 BIOS 搭配 GPT 來實做系統,但是, Windows 若要使用 GPT,最好就得要搭配 UEFI 的開機環境。由於 UEFI 會有一個獨立的分割區來存放開機資料,因此,與傳統的 BIOS 差異很大! 我們這個章節就來處理一下,那如何在虛擬機器裡面,以 UEFI 來安裝多重作業系統的管理呢?

  • 什麼是 UEFI 與 BIOS
  • GPT 分割表的多重作業系統安裝流程以及 CentOS 的 grub2 選單製作
  • 設計支援 UEFI 的 iPXE 以及萬用的 grub2 image 製作
  • 使用 rootfs 搭配 partclone 進行備份、復原的任務
  • 參考資料

什麼是 UEFI 與 BIOS

為了讓系統可以更快速的開機,同時為了可以在進入作業系統之前的階段,可以進行更多的硬體控制行為,因此有了 UEFI 的產生。

  1. UEFI 與 BIOS 的差異:
    1. 傳統的 BIOS 使用了 16 位元的執行模式,只能搜尋 1MB 左右的記憶體定址功能,並透過中斷來發送管理訊號給週邊設備。 基本上,BIOS 就是一組韌體,開機時可以透過 BIOS 進行主機的硬體自我檢查 (S.M.A.R.T),並讓用戶選擇開機裝置後,就可以順利的啟動電腦。 但是,當作業系統載入後,會忽略 BIOS 提供的各項裝置驅動。
    2. 但是 BIOS 由於是韌體,雖然目前有快閃記憶體在負責 BIOS 這一塊程式的開發,不過 BIOS 依舊存在只能使用 16 位元模式、 最大定址為 1MB、找到的磁碟容量在 windows 底下最大僅能支援到 2.1T、開發界面不友善等問題。
    3. Intel 與其夥伴成立 UEFI 論壇,制定了 UEFI 的各項標準,這個 UEFI 可以說是介於韌體與作業系統間的一層, 大致的相關性可如底下所示:
    4. UEFI 可進行模組化、規格化的運作,大部分程式碼使用 C 程式語言編寫,可以執行於 x86-64 與 ARM 架構上,直接以 64 位元模式進行運作。 在硬體控制方面,可直接以 EFI driver 的方式辨識及操作顯示卡、網路卡等等硬體,同時該驅動程式也可以在 x86-64 或 ARM 上面直接運作, 另外,UEFI 也能夠提供圖形化界面,多國語言模式支援,甚至可以直接使用網際網路,同時可以支援 GPT 磁碟分割類型, 對於 windows 系統來說,就可以提供超過 2T 以上的磁碟裝置了!
  2. 對於 KVM 的支援情況:
    1. 如果要使用 UEFI 的話,最好連虛擬機器的機器設備也調整一下比較好!如何判斷目前的 qemu 支援的硬體?可以這樣看:
      # 1. 來查看看 qemu-kvm 支援的硬體有哪些:
      # yum install centos-release-qemu-ev
      # yum --enablerepo=centos-qemu-ev install qemu-kvm-ev
      # /usr/libexec/qemu-kvm -version
      記得要出現 2.x 的版本才可以!
      # systemctl restart libvirtd
      
      # /usr/libexec/qemu-kvm -machine help
      Supported machines are:
      pc                   RHEL 7.6.0 PC (i440FX + PIIX, 1996) (alias of pc-i440fx-rhel7.6.0)
      pc-i440fx-rhel7.6.0  RHEL 7.6.0 PC (i440FX + PIIX, 1996) (default)
      pc-i440fx-rhel7.5.0  RHEL 7.5.0 PC (i440FX + PIIX, 1996)
      pc-i440fx-rhel7.4.0  RHEL 7.4.0 PC (i440FX + PIIX, 1996)
      pc-i440fx-rhel7.3.0  RHEL 7.3.0 PC (i440FX + PIIX, 1996)
      pc-i440fx-rhel7.2.0  RHEL 7.2.0 PC (i440FX + PIIX, 1996)
      pc-i440fx-rhel7.1.0  RHEL 7.1.0 PC (i440FX + PIIX, 1996)
      pc-i440fx-rhel7.0.0  RHEL 7.0.0 PC (i440FX + PIIX, 1996)
      rhel6.6.0            RHEL 6.6.0 PC
      rhel6.5.0            RHEL 6.5.0 PC
      rhel6.4.0            RHEL 6.4.0 PC
      rhel6.3.0            RHEL 6.3.0 PC
      rhel6.2.0            RHEL 6.2.0 PC
      rhel6.1.0            RHEL 6.1.0 PC
      rhel6.0.0            RHEL 6.0.0 PC
      q35                  RHEL-7.6.0 PC (Q35 + ICH9, 2009) (alias of pc-q35-rhel7.6.0) <==用這個!
      pc-q35-rhel7.6.0     RHEL-7.6.0 PC (Q35 + ICH9, 2009)
      pc-q35-rhel7.5.0     RHEL-7.5.0 PC (Q35 + ICH9, 2009)
      pc-q35-rhel7.4.0     RHEL-7.4.0 PC (Q35 + ICH9, 2009)
      pc-q35-rhel7.3.0     RHEL-7.3.0 PC (Q35 + ICH9, 2009)
      none                 empty machine
      
    2. 預設虛擬機器使用 SEABIOS 的模樣,這個是傳統 BIOS 喔!那怎麼載入 UEFI 的韌體呢?先查一下有沒有名為 ovmf 的軟體安裝在 Linux 上?
      # 1. 先查看 OVMF 有沒有安裝?然後再看該軟體提供的檔案資料即可:
      # rpm -qa | grep -i ovmf
      OVMF-20180508-3.gitee3198e672e2.el7_6.1.noarch
      
      # rpm -ql OVMF
      /usr/share/OVMF
      /usr/share/OVMF/OVMF_CODE.secboot.fd  <==用這個!
      /usr/share/OVMF/OVMF_VARS.fd
      /usr/share/OVMF/OVMF_VARS.secboot.fd
      /usr/share/OVMF/UefiShell.iso
      /usr/share/doc/OVMF/Licenses
      /usr/share/doc/OVMF/Licenses/OpensslLib-License.txt
      /usr/share/doc/OVMF/Licenses/OvmfPkg-License.txt
      /usr/share/doc/OVMF/Licenses/edk2-License.txt
      /usr/share/doc/OVMF/README
      /usr/share/doc/OVMF/ovmf-whitepaper-c770f8c.txt
      
    3. 在每一部虛擬機器上面,都會記載自己的 UEFI 設定值!但是上面的 OVMF_CODE.secboot.fd 檔案,僅是 UEFI 的主要程式碼。 那如何設定呢?其實,每一部虛擬機器在啟動時,都會自己建立 OVMF_VARS.fd 這個檔案,該檔案就是設定檔的參考值! 最好不要直接用掉喔!該檔案主要是被拿來複製的一個範本檔!現在,讓我們來建立一個 uefi 的範本機器吧:
      # 1. 先來建立虛擬機器 xml 檔案:
      # vim create_vm_settings.sh
      ...
      vmnames="uefios"
      ...
      
      # sh create_vm_settings.sh
      # qemu-img create -f qcow2 uefios.img 135G
      Formatting 'uefios.img', fmt=qcow2 size=144955146240 cluster_size=65536 lazy_refcounts=off refcount_bits=16
      
      
      # 2. 再來修改 XML 檔案,讓這個檔案支援 UEFI 囉: # vim uefios.xml <os> <type arch="x86_64" machine='q35' >hvm</type> <loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.secboot.fd</loader> <nvram>/vmdisk/uefios.fd</nvram> <bootmenu enable='no'/> </os> <disk type="file" device="cdrom"> <driver name="qemu" type="raw"/> <source file="/vmdisk/iso/CentOS-7-x86_64-DVD-1810.iso"/> <target dev="sda" bus="sata"/> <readonly/> </disk>
      因為 q35 裝置已經不支援 IDE 的設備,因此要將 IDE 修改成為 sata 裝置才行!這點很重要!鳥哥當時就死在這個地方好久好久...

GPT 分割表的多重作業系統安裝流程以及 CentOS 的 grub2 選單製作

這一小節我們同樣會花費很多時間在等待安裝的流程當中!所以,整個流程請盡量順暢的進行!否則時間會被拖到喔!

  1. 安裝 CentOS 7 管理小系統:
    1. 與 BIOS 不一樣, UEFI 需要一個小型檔案系統提供放置開機管理模組的位置,因此,得要額外分割出一個大約 200M~500M 的磁碟槽, 這個磁碟槽基本上使用的是 VFAT 檔案系統格式!因此,在安裝的過程中,就需要一些額外的注意事項才行!此外, UEFI 啟動 CentOS 7 的安裝畫面與原本的 BIOS 畫面不太一樣!這也需要注意一下才好:
      # 1. 先啟動虛擬機器:
      # virsh create /vmdisk/uefios.xml
      
      一般來說,如果你沒有任何的虛擬機啟用,那麼埠口會是 5900 才對!,現在請用 spice 連線到虛擬機終端機上面, 就會看到如下的畫面才對:
    2. 點選上面的『 Install CentOS 7 』之後,就會順利的進入安裝畫面中了。
    3. 接下來,請在 spice 的環境下,將 CentOS 安裝妥當!大概需要注意的僅有:
      • 選擇中文-台灣語系
      • 選擇『最小型安裝』,但是增加『相容性函式庫』、『開發工具』、『系統管理工具』等
      • 安裝目的地,使用『標準分割』,不要 swap,不要 /boot,只需要 /boot/efi 大約 200M,/ 大約 5G,且為 EXT4 檔案系統
      • 關閉 KDUMP 吧!
      • 在網路與主機名稱的部份,直接啟用網路吧!
      • root 密碼以及你的個人帳號,就自由設定,但是不可以太簡單!
    4. 完成並且重新開機進入這個小型 Linux 管理系統,進行全系統升級,並且安裝需要的軟體:
      # 1. 先登入虛擬機器:
      # ssh 192.168.19.24
      
      
      # 2. 處理小型系統的各項任務: # yum -y update # yum install net-tools bash-completion vim-enhanced tcpdump bind-utils bridge-utils iptables-services # fdisk /dev/vda # 依舊需要先切出來額外兩塊分割槽才行: # fdisk -l /dev/vda WARNING: fdisk GPT support is currently new, and therefore in an experimental phase. Use at your own discretion. Disk /dev/vda: 145.0 GB, 144955146240 bytes, 283115520 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O 大小 (最小/最佳化):512 位元組 / 512 位元組 Disk label type: gpt Disk identifier: 079FCA41-C1CD-4CC9-9778-D69D901083C7 # Start End Size Type Name 1 2048 411647 200M EFI System EFI System Partition 2 411648 10897407 5G Linux filesyste 3 10897408 220612607 100G Microsoft basic <==用 systemid 為 11 喔! 4 220612608 283115486 29.8G Microsoft basic
      沒問題之後,先不要關機!我們直接透過指令抽換光碟片,就可以再次的進入 Windows 的安裝畫面囉!
  2. 建立平時上課用的 Windows 10 系統:
    1. 抽換光碟:目前的系統還在開機喔!現在我們模擬平時安裝的行為,將光碟片退出,放入 Windows 10 的光碟片之後, 才進行重新開機的動作!但是請注意,我們的機器設備現在只支援 sata 而已,所以不能使用之前的指令! 要修改關鍵資料成為如下的模樣:
      # 1. 先放讓 SATA 界面的光碟機,抽換 Windows 10 的安裝光碟片:
      # virsh attach-disk uefios /vmdisk/iso/Win10_1809_64.iso sda --targetbus sata --type cdrom --mode readonly
      
      # 2. 換完之後,查看一下是否是正確的光碟資料呢?
      # virsh qemu-monitor-command --hmp uefios --cmd "info block"
      pflash0 (#block167): /usr/share/OVMF/OVMF_CODE.secboot.fd (raw, read-only)
          Attached to:      /machine/unattached/device[10]
          Cache mode:       writeback
      
      pflash1 (#block302): /vmdisk/uefios.fd (raw)
          Attached to:      /machine/unattached/device[11]
          Cache mode:       writeback
      
      drive-virtio-disk0 (#block516): /vmdisk/uefios.img (qcow2)
          Attached to:      /machine/peripheral/virtio-disk0/virtio-backend
          Cache mode:       writeback
      
      drive-sata0-0-0 (#block1325): /vmdisk/iso/Win10_1809_64.iso (raw, read-only)
          Attached to:      sata0-0-0
          Removable device: not locked, tray closed
          Cache mode:       writeback
      
      確定沒錯!這時就可以重新開機了!
    2. 重新開機的過程中,一定要很快速的按下 [F2] 來進入 UEFI 的設定畫面!如果你沒有按下 [F2] 的話,系統會直接以上次成功開機的系統開機! 所以,就無法使用光碟開機了!基本上,按下 [F2] 會出現如下的畫面: 這個是 UEFI 的設定畫面!先不要理詳細的設定值~我們先來使用光碟開機!按下如上圖的『Boot Manager』之後,就會出現如下的模樣: 你會看到有『 UEFI QEMU DVD-ROM 』的字樣,沒錯!那就是光碟!按下這片光碟!如果這片光碟是可以開機的裝置, 那就會進入安裝流程了!記得 windows 的安裝過程中,需要按下任意鍵,才會進入到安裝流程中。
    3. 進入安裝程序後,你可以依序這樣選擇:
      • 確認安裝的語言,然後『下一步』
      • 按下『立即安裝』後,開始程序
      • 選擇『Windows 10 專業版』這一個版本
      • 接受授權條款後,下一步
      • 使用『自訂:只安裝 Windows』這個項目
      • 接下來,你會看到『找不到任何磁碟機』的畫面!不要懷疑!確實沒有磁碟機。
    4. 抽換光碟片,這個就需要在實體機器進行了!指令也很簡單:
      # virsh attach-disk uefios /vmdisk/iso/virtio-win-0.1.171.iso sda --targetbus sata --type cdrom --mode readonly
      
      此時,請回到 spice 畫面,然後按下『載入驅動程式』的按鈕,再按下『瀏覽』就可以看到 D 槽了! 光碟標題會是『virtio-win-0.1....』這樣。最重要的是底下這幾個驅動程式要安裝:
      1. amd64/win10 --> Red Hat VirtIO SCSI controller
      2. Balloon/win10/amd64 --> VirtIO Balloon Driver
      3. NetKVM/win10/amd64 --> Red Hat VirtIO Ethernet Adapter
      4. qemufwcfg/win10/amd64 --> QEMU FWCfg Device
      5. qxldod/win10/amd64 --> Red Hat QXL controller
      6. viorng/win10/amd64 --> VirtIO RNG Device
      安裝驅動程式完畢後,還不能繼續!這時,請先將 Windows 10 的光碟片換回來:
      # virsh attach-disk uefios /vmdisk/iso/Win10_1809_64.iso sda --targetbus sata --type cdrom --mode readonly
      
    5. 然後,你應該就會看到剛剛建立成功的 4 個分割槽,在 100G 左右的那個分割槽上面點一下,然後按『下一步』之後, 系統就開始自動安裝了!接下來就是持續不斷的等待而已。不過,與 MSDOS 分割槽安裝時候不一樣,在 UEFI 搭配 GPT 的安裝畫面中, Windows 的黑色螢幕轉圈圈超級久~你都不會知道系統到底是當機了還是正常運作中!非常怪異!不過,只要圈圈還有在持續跑, 你就讓他跑吧!所花費的時間與安裝 MSDOS 的時間不會差太多!
    6. 再次的登入 windows 系統,比較重要的部份,在建立帳號的那個地方!大致上的本機帳號建置流程:
      • 選擇左下角『離線帳戶』
      • 不要使用 microsoft 帳戶,所以選擇『否』
      • 開始輸入你的帳號與密碼 (個人使用,可以不輸入密碼喔!)
      • 紀錄個人歷程可以選『否』,然後接受隱私權設定,就可以順利登入了!
      因為我們是暫時用來測試用的,因此,可以的話,請將 windows 的『設定』--> 『更新與安全性』--> 『進階選項』--> 全部都關閉!確認沒有問題!就好了!先不要關機!
  3. 處理第一套系統的 UEFI 紀錄資訊
    1. 開機紀錄區域的變化:在傳統 BIOS 的環境下,開機紀錄區主要是記載在整顆磁碟最前面的區塊 (MBR) , 以及每個檔案系統最前面的那個區塊 (boot sector),所以,我們經常得要使用 grub2-install 去安裝這樣。 作業系統的開機管理程式控制權移交 (chainloader),也就是讀取這個區塊來載入核心等相關資訊的喔!
    2. 開機紀錄區的變化:在 UEFI 的環境下,我們在安裝第一套管理系統的 CentOS 時,就已經知道了! UEFI 會去一個 GPT 分割表系統 ID (system id) 名稱為『 EFI system 』的分割槽,該分割槽必須要格式化成為 FAT 檔案系統, 然後,所有的開機引導程式,已經都改變位置啦!都寫入在這個地方!因此,我們只要處理這個分割槽的內容, 就可以修改開機選單相關的資訊了。
    3. 查看與變更第一套 Windows 上課用系統的位置。由於 Windows 預設會將開機選單紀錄資料放置到這個分割槽內固定位置, 基本上就是在底下的位置上:
      ($root)//EFI/Microsoft/Boot/bootmgfw.efi
      # 同時,好像 UEFI 也僅認識微軟的開機選單在這個固定的位置上!
      # 所以,如果你變更了目錄,可能 UEFI 就找不到這個開機選單了!
      
      但是我們預計要安裝多個 Windows 系統的啊!如此一來,我們可能就會被迫要輸入兩次選單選擇:
      • 第一次,就是通過 UEFI 選擇 CentOS 的選單,使用者可以選擇 Windows 來開機;
      • 第二次,進入 Windows 開機管理程式後,再由 Windows 提供兩個選單來讓使用者選擇要進入的那個系統環境。
      那怎麼辦?其實有個投機取巧的方式,那就是更改上面那個 windows 的選單位置檔名,讓 UEFI 確實找不到! 然後再安裝第二套 windows,此時第二套 windows 所放置的開機管理位置就不會覆蓋原本的第一套系統! 那就可以製作兩個完全獨立的 windows 選單系統了!只是,如此一來,你的 windows 就一定只能透過 CentOS 來啟用了! 不過這也還好,我們原本的 BIOS 規劃的情況下,也正好是這樣的情況啊!所以,就讓我們來看看如何處理這部份資料吧!
      # 1. 先重新開機進入 CentOS 的環境:
      # 按照剛剛的流程, 『Boot Manager』 --> 『CentOS』來啟動吧!
      
      
      # 2. 進入 Linux 之後,可以使用 ssh 進去系統工作即可: # df -T | grep -v 'tmpfs' 檔案系統 類型 1K-區段 已用 可用 已用% 掛載點 /dev/vda2 ext4 5029504 1765900 2985076 38% / /dev/vda1 vfat 204580 36648 167932 18% /boot/efi <==就是這裡囉!
      # 3. 開始查看這個 UEFI 的開機選單紀錄資料裡面有什麼鬼? # cd /boot/efi # find . -type d ./EFI ./EFI/centos <==CentOS 開機選單紀錄 ./EFI/centos/fonts ./EFI/BOOT <==UEFI 紀錄 ./EFI/Microsoft <==Microsoft 自己的選單紀錄 ./EFI/Microsoft/Boot <==開機資料 ./EFI/Microsoft/Boot/bg-BG <==各國語系界面資料 ./EFI/Microsoft/Boot/cs-CZ ..... ./EFI/Microsoft/Boot/zh-CN ./EFI/Microsoft/Boot/zh-TW ./EFI/Microsoft/Boot/Fonts ./EFI/Microsoft/Boot/Resources <==其他資源 ./EFI/Microsoft/Boot/Resources/en-US ./EFI/Microsoft/Boot/Resources/zh-TW ./EFI/Microsoft/Recovery <==系統救援方式
      # 4. 確實開始更改 Microsoft 的開機選單位置,改成 win10class 好了: # cd /boot/efi/EFI/ # ll drwx------. 2 root root 4096 5月 31 11:44 BOOT drwx------. 3 root root 4096 5月 31 21:54 centos drwx------. 4 root root 4096 5月 31 22:04 Microsoft <==將這個改掉! # mv Microsoft win10class # ll win10class/Boot/bootmgfw.efi -rwx------. 1 root root 1469752 9月 15 2018 win10class/Boot/bootmgfw.efi # 上面這個檔案,就是 windows 的開機引導程式囉!
    4. 先作到這樣就好!我們先讓第一套 windows 不能直接透過 UEFI 開機 ^_^!救援選單等等再來處理~ 先來安裝第二套 windows 吧!
  4. 建立第二套 Windows 系統:
    1. 先在 host 上面確認一下,光碟片是否為 windows 的安裝光碟呢?如果是的話,就重新開機,然後透過 [F2] 來進入 UEFI 選單喔!
      # virsh qemu-monitor-command --hmp uefios --cmd "info block"
      pflash0 (#block127): /usr/share/OVMF/OVMF_CODE.secboot.fd (raw, read-only)
          Attached to:      /machine/unattached/device[10]
          Cache mode:       writeback
      
      pflash1 (#block391): /vmdisk/uefios.fd (raw)
          Attached to:      /machine/unattached/device[11]
          Cache mode:       writeback
      
      drive-virtio-disk0 (#block539): /vmdisk/uefios.img (qcow2)
          Attached to:      /machine/peripheral/virtio-disk0/virtio-backend
          Cache mode:       writeback
      
      drive-sata0-0-0 (#block1325): /vmdisk/iso/Win10_1809_64.iso (raw, read-only)
          Attached to:      sata0-0-0
          Removable device: locked, tray closed
          Cache mode:       writeback
      
      # reboot
      
    2. 繼續從『 Boot Manager 』 --> 『UEFI QEMU DVD-ROM 』開機吧!繼續進入 Windows 的安裝程序!記得安裝第二套 windows 在剩餘的容量裡面! 之後的程序就完全按照之前的方法來處理吧!安裝完畢之後,先將光碟退出,然後就準備來處理選單的問題了:
      # virsh change-media uefios sda --eject
      # virsh qemu-monitor-command --hmp uefios --cmd "info block"
      virsh qemu-monitor-command --hmp uefios --cmd "info block"
      pflash0 (#block196): /usr/share/OVMF/OVMF_CODE.secboot.fd (raw, read-only)
          Attached to:      /machine/unattached/device[10]
          Cache mode:       writeback
      
      pflash1 (#block399): /vmdisk/uefios.fd (raw)
          Attached to:      /machine/unattached/device[11]
          Cache mode:       writeback
      
      drive-virtio-disk0 (#block551): /vmdisk/uefios.img (qcow2)
          Attached to:      /machine/peripheral/virtio-disk0/virtio-backend
          Cache mode:       writeback
      
      drive-sata0-0-0: [not inserted]
          Attached to:      sata0-0-0
          Removable device: not locked, tray open
      # 果然已經不存在光碟片檔案囉!
      
  5. 處理第二套 Windows 系統的 UEFI 選單位置,以及處理全系統的 CentOS 選單設計:
    1. 重新開機,按下 [F2] 進入 UEFI 管理畫面,選擇 CentOS 選單開機!就可以進入 Linux 的管理環境中了。 之後,我們先將第二套 Windows 的開機選單設計成為 win10exam 吧!
      # 1. 先觀察檔案系統掛載的情況,然後再去到 EFI 所在目錄處理檔名問題:
      # df -T | grep -v 'tmpfs'
      檔案系統       類型     1K-區段    已用    可用 已用% 掛載點
      /dev/vda2      ext4     5029504 1766116 2984860   38% /
      /dev/vda1      vfat      204580   61940  142640   31% /boot/efi
      
      # cd /boot/efi/EFI/
      # ll
      drwx------. 2 root root 4096  5月 31 11:44 BOOT
      drwx------. 3 root root 4096  5月 31 21:54 centos
      drwx------. 4 root root 4096  5月 31 22:57 Microsoft  <==這次要改這個東西!
      drwx------. 4 root root 4096  5月 31 22:04 win10class
      
      # mv Microsoft win10exam
      # ll
      drwx------. 2 root root 4096  5月 31 11:44 BOOT
      drwx------. 3 root root 4096  5月 31 21:54 centos
      drwx------. 4 root root 4096  5月 31 22:04 win10class  <==這兩個會是重點!
      drwx------. 4 root root 4096  5月 31 22:57 win10exam
      
    2. 再來就是要處理 grub2 的選單設計了!要注意的是,grub 的設定檔位置依舊是在 /etc/grub.d/40_custom, 但是,實際的選單位置其實是在 /boot/efi/EFI/centos/grub.cfg!並不是原本的位置了喔!要注意!要注意!
      # 1. 先處理 40_custom 的檔案內容:
      # vim /etc/grub.d/40_custom
      #!/bin/sh
      exec tail -n +3 $0
      # This file provides an easy way to add custom menu entries.  Simply type the
      # menu entries you want to add after this comment.  Be careful not to change
      # the 'exec tail' line above.
      menuentry "Windows 10 Class system" {
              insmod part_gpt
              insmod search_fs_uuid
              insmod chain
              set root=(hd0,gpt1)
              chainloader /EFI/win10class/Boot/bootmgfw.efi
      }
      menuentry "Windows 10 Exam environment" {
              insmod part_gpt
              insmod search_fs_uuid
              insmod chain
              set root=(hd0,gpt1)
              chainloader /EFI/win10exam/Boot/bootmgfw.efi
      }
      
      事實上,你要注意的大概就是那個『set root=(hd0,gpt1) 』這玩意!因為我們的 UEFI 分割槽位置在 /dev/vda1 這裡, 所以選單所在的根目錄就是 (hd0,gpt1) 的意思喔!就這裡大家可能會搞混而已!這裡搞定之後,只要將檔名填進去就好了!
    3. 上面的 40_custom 內容,在實體機器上面測試時,卻出現了莫名其妙的問題! 當實體機器開機進入 windows 前,出現了 grub2 的一個錯誤,螢幕上面顯示:『invalid sector size 65535』這樣的字句。 經過查詢之後,發現到 grub2 的官方文件,建議在設計 UEFI 的選單時,盡量不要使用磁碟代碼,亦即『 set root=(hd0,gpt1) 』 這種語法盡量避免比較好。那怎麼處理這個 root 呢?可以從檔案系統的 uuid 或 label 去著手處理!
      # 1. 先查出 win10class 這個 uefi 開機引導檔案所在的檔案系統 uuid 數值
      # grub2-probe --target=fs_uuid /boot/efi/EFI/win10class/Boot/bootmgfw.efi
      0C42-DEAD
      
      # 2. 使用這個數值,搭配 grub2 的 search 功能做底下的處理:
      # vim /etc/grub.d/40_custom
      #!/bin/sh
      exec tail -n +3 $0
      # This file provides an easy way to add custom menu entries.  Simply type the
      # menu entries you want to add after this comment.  Be careful not to change
      # the 'exec tail' line above.
      menuentry "Windows 10 Class system" {
              insmod part_gpt
              insmod search_fs_uuid
              insmod chain
              search --no-floppy --fs-uuid --set 0C42-DEAD
              chainloader /EFI/win10class/Boot/bootmgfw.efi
      }
      menuentry "Windows 10 Exam environment" {
              insmod part_gpt
              insmod search_fs_uuid
              insmod chain
              search --no-floppy --fs-uuid --set 0C42-DEAD
              chainloader /EFI/win10exam/Boot/bootmgfw.efi
      }
      
      如果你對於這樣的設計覺得很惶恐,因為檔案系統的 UUID 總是會改變的!不過未來我們會需要用到復原的環境, 或者是重灌的環境,如此一來,我們的設定可能會跑掉。這個時候,可以改用檔案系統標題 (filesystem label) 來處理!
      # 1. 先設定 /dev/vda1 的 DOS LABEL 喔!注意,因為需要相容於 windows,所以建議 label name 為大寫:
      # dosfslabel /dev/vda1 DICBOOT
      # grub2-probe --target=fs_label /boot/efi/EFI/win10class/Boot/bootmgfw.efi
      DICBOOT
      
      # 2. 使用這個數值,搭配 grub2 的 search 功能做底下的處理:
      # vim /etc/grub.d/40_custom
      #!/bin/sh
      exec tail -n +3 $0
      # This file provides an easy way to add custom menu entries.  Simply type the
      # menu entries you want to add after this comment.  Be careful not to change
      # the 'exec tail' line above.
      menuentry "Windows 10 Class system" {
              insmod part_gpt
              insmod search_fs_uuid
              insmod chain
              search --no-floppy --label --set DICBOOT
              chainloader /EFI/win10class/Boot/bootmgfw.efi
      }
      menuentry "Windows 10 Exam environment" {
              insmod part_gpt
              insmod search_fs_uuid
              insmod chain
              search --no-floppy --label --set DICBOOT
              chainloader /EFI/win10exam/Boot/bootmgfw.efi
      }
      
      這樣也比較不容易讓設定值跑掉啊!
    4. 設計妥當之後,就來更新選單檔案吧!
      # 1. 先將選單預設秒數給為 30 秒,增加一些選擇的時間:
      # vim /etc/default/grub
      GRUB_TIMEOUT=30
      GRUB_DISTRIBUTOR="$(sed 's, release .*$,,g' /etc/system-release)"
      GRUB_DEFAULT=saved
      GRUB_DISABLE_SUBMENU=true
      GRUB_TERMINAL_OUTPUT="console"
      GRUB_CMDLINE_LINUX="rhgb quiet"
      GRUB_DISABLE_RECOVERY="true"
      
      # grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg
      # vim /boot/efi/EFI/centos/grub.cfg
      # 單純進來查詢一下有沒有看到 windows 選單資訊啦!
      
      接下來,當然就是重新開機,測試一下能不能順利的看到選單啊!例如下列的模樣: 分別進入兩個 windows 看看是否為正確的環境即可!

設計支援 UEFI 的 iPXE 以及萬用的 grub2 image 製作

基本上,iPXE 在 BIOS 與 UEFI 的平台運作上是不太一樣的,因此需要有兩個不同的 iPXE 的開機載入器,其實就是開機管理程式需要分別載入。 所以,我們得要重新製作給 UEFI 使用的 iPXE 載入檔案,同時重新修改 dhcp 設定檔,這樣才能處理 rootfs 的載入哩!

  1. 製作給 UEFI 平台使用的 iPXE 載入器:
    1. 在前幾個章節,談到 iPXE 時,我們曾經下載 iPXE 的原始碼在 /vmdisk/rootfs/ipxe 裡面, 同時,在 Makefile 裡面也能看到一個名為 bin-x86_64-efi/ipxe.efi 的資料,所以編譯起來還挺容易的:
      # 1. 設計給 uefi 使用的 iPXE 的 chainloader
      # cd /vmdisk/rootfs/ipxe/src
      # make bin-x86_64-efi/ipxe.efi
      # 會花一小段時間來進行編譯
      
      
      # 2. 開始設計 tftp 的檔案放置,因應不同的 BIOS/UEFI 所以我們這樣做: # mkdir /var/lib/tftpboot/uefi # mkdir /var/lib/tftpboot/bios # cp bin-x86_64-efi/ipxe.efi /var/lib/tftpboot/uefi/ # cd /var/lib/tftpboot/ # mv undionly.kpxe bios # ll drwxr-xr-x. 2 root root 27 6月 1 15:34 bios drwxr-xr-x. 2 root root 22 6月 1 15:34 uefi # ll */* -rw-r--r--. 1 root root 75468 5月 21 11:13 bios/undionly.kpxe <==傳統 BIOS 用 -rw-r--r--. 1 root root 955328 6月 1 15:34 uefi/ipxe.efi <==給 UEFI 平台用
  2. 開始修改 dhcp 設定檔,讓不同的平台取得不同的載入器:
    1. 在不同的平台使用 PXE 的情況 (網路開機) 時,用戶端會發送不同的平台識別碼給 dhcpd 伺服器。詳細的識別碼可以參考底下的網站:
    2. 根據上面網站的建議,我們發現到原本針對 BIOS 設定的環境已經不夠用了,因此需要將設定檔修改成為這樣才行:
      # vim /etc/dhcp/dhcpd.conf
      default-lease-time 600;
      max-lease-time 72000;
      ddns-update-style none;
      log-facility local7;
      
      option space PXE;
      option arch code 93 = unsigned integer 16;
      
      subnet 192.168.19.0 netmask 255.255.255.0 {
        range 192.168.19.1 192.168.19.150;
        option routers 192.168.19.254;
        option domain-name "virtual.dic";
        option domain-name-servers 120.114.100.1,120.114.150.1;
      
        next-server 192.168.19.254;
      
        if exists user-class and option user-class = "iPXE" {
            filename "http://192.168.19.254/ipxe/menu.php";
        } else {
            if exists arch {
                if option arch = 00:00 {
                    filename "bios/undionly.kpxe";
                } elsif option arch = 00:07 {
                    filename "uefi/ipxe.efi";
                } elsif option arch = 00:09 {
                    filename "uefi/ipxe.efi";
                }
            } else {
                filename "http://192.168.19.254/ipxe/menu.php";
            }
        }
      }
      
      # systemctl restart dhcpd
      # 最後要重新啟動 dhcpd 才行啊!
      
    3. 最後,修改 menu.php 這個設定檔。載入 rootfs 的 filesystem 與相關 filesystem 內的流程都沒有問題, 但是,在 UEFI 的架構下,如果沒有讓核心 (vmlinuz) 知道 initrd 這個參數所在的檔名時,它就不知道怎麼掛載根目錄... 這還真是個奇怪的地方...總之,沒關係,就讓我們來處理一下吧!很簡單的工作:
      # 修改一下 vmlinuz 的參數,一定要額外帶入 initrd 的參數才可以!
      # vim /var/www/html/ipxe/menu.php
      :diskless
      echo Boot from rootfs diskless
      kernel vmlinuz devfs=nomount rw panic=60 selinux=0 ip=dhcp biosdevname=0 net.ifnames=0 ipv6.disable=0 initrd=initramfs.gz
      initrd initramfs.gz
      boot || goto failed
      goto start
      
  3. 開始測試 rootfs 的執行,當然就是要讓網路開機優先啦!
    1. 確認 dicos.xml 以及 uefios.xml 裡面的開機順序都是以 network 網卡優先,如下所示:
      # 1. 檢查 dicos.xml 的開機順序部份:
      # vim dicos.xml
        <os>
          <type arch="x86_64">hvm</type>
          <boot dev="network"/>   <==確認這個最優先!
          <boot dev="cdrom"/>
          <boot dev="hd"/>
        </os>
      
      # vim uefios.xml
        <os>
          <type arch="x86_64" machine='q35' >hvm</type>
          <loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.secboot.fd</loader>
          <nvram>/vmdisk/uefios.fd</nvram>
          <boot dev="network" />  <==確認這個最優先!
          <boot dev="cdrom" />
          <boot dev="hd" />
          <bootmenu enable='off'/>
        </os>
      
      然後,請你分別啟動 dicos.xml 以及 uefios.xml 這兩個虛擬機器,同時分別使用 spice 連線到這兩個虛擬機的終端機, 查看一下開機的過程,BIOS 與 UEFI 的開機畫面還是有點不太一樣的:
    2. 經過上述的設定,目前我們的系統就可以處理 rootfs 了!不論是 BIOS 還是 UEFI 的平台,都可以透過我們這個界面, 進行 rootfs 的系統執行喔!
  4. 設計給個別系統使用的 chainloader 環境:
    1. 選單製作的問題以及最終的解決方案:
      1. 因為 grub4dos 並不支援 UEFI 的環境,因此我們無法簡單的使用 grub4dos 來進行相關的處理。 而至於 iPXE 官網提供關於各種系統的開機選項,例如使用 wimboot 之類的方式,似乎也無法滿足我們簡易設定的需求! 基本上,還是使用本機來進行開機是最適當的!但是 iPXE 以及搭配 PXE 等等的方式,很難使用到 chainloader 的功能! 這就造成了我們的困擾。
      2. 讓我們回到 grub2 的偵測方式,針對 grub2 的開機,它通常是搜尋系統裡面的 UUID,來找到所謂的根目錄 (root), 然後再透過設定 linuxefi 以及 initrdefi 等,就可以進行開機了!基本的方式有點像底下這樣 (從 grub.cfg 撈出來的資料)
        menuentry 'CentOS Linux (3.10.0-957.12.2.el7.x86_64) 7 (Core)' --class centos \
          --class gnu-linux --class gnu --class os --unrestricted $menuentry_id_option \
          'gnulinux-3.10.0-957.12.2.el7.x86_64-advanced-1ca1faf4-0add-4659-b2de-c759bc32e7ec' {
                load_video
                set gfxpayload=keep
                insmod gzio
                insmod part_gpt
                insmod ext2
                if [ x$feature_platform_search_hint = xy ]; then
                  search --no-floppy --fs-uuid --set=root  1ca1faf4-0add-4659-b2de-c759bc32e7ec
                else
                  search --no-floppy --fs-uuid --set=root 1ca1faf4-0add-4659-b2de-c759bc32e7ec
                fi
                linuxefi /boot/vmlinuz-3.10.0-957.12.2.el7.x86_64 root=UUID=1ca1faf4-0add-4659-b2de-c759bc32e7ec ro rhgb quiet
                initrdefi /boot/initramfs-3.10.0-957.12.2.el7.x86_64.img
        }
        
        上面那段特殊字體,就是在找尋系統 UUID 的項目,並將該裝置設置為開機的根目錄之意!
      3. 那麼 Windows 的設定又是如何呢?像這樣:
        menuentry "Windows 10 Class system" {
                insmod part_gpt
                insmod search_fs_uuid
                insmod chain
                set root=(hd0,gpt1)
                chainloader /EFI/win10class/Boot/bootmgfw.efi
        }
        
        你會發現到只要有 (1)開機檔案所在的裝置(就是那個 root 的設定) 以及 (2)開機管理程式檔案, 那麼系統就能夠移交控制權~如此一來,我們就可以開始開機!
      4. 雖然上面講得很簡單,但是目前的 iPXE 以及其他的裝置,有點難以處理,因此,我們只好使用 grub2 原生的映像檔來開機! 使用了 grub2-mkimage 來處理即可!
    2. 那麼目前我們主要的三個系統的開機管理程式分別在哪裡呢?其實目前分別在底下這裡:
      • CentOS: (/dev/vda1)/EFI/centos/grubx64.efi
      • Win10class: (/dev/vda1)/EFI/win10class/Boot/bootmgfw.efi
      • Win10exam: (/dev/vda1)/EFI/win10exam/Boot/bootmgfw.efi
      所以整個問題就簡化了!最重要的就是找到那個 (/dev/vda1) 在 grub2 裡面的代號,如果能夠 (1)執行 grub2 以及 (2)設定好該裝置代號, 這樣就完成了問題的處理!請注意, grub4dos 是 0.97 改的,並不是 grub2 喔!所以無法直接執行~
    3. 那該怎麼辦?基本上, grub2 提供一個所謂的 grub2-mkimage 指令,以及 grub2-mkstandalone 這兩個指令來處理,其中 grub2-mkstandalone 可以產生虛擬根目錄,用在預計作為嵌入式環境很有幫助!基本上也可以用來處理 busybox 的工作啦! 我們只要使用 grub2-mkimage 即可!因為我們的重點是產生一個可以透過 iPXE 的 http 去載入的 grub2 環境, 有了這個環境,自然就可以根據上述的功能,去分別執行各自的 chainloader 囉!所以,先來看看 grub2-mkimage 的指令參數:
      grub2-mkimage -c 設定檔 -o 執行檔 -O x86_64-efi -p /usr/lib/grub/x86_64-efi -v 各種開機用途的模組
      
      -c 設定檔:基本上,就是個別的 chainloder 資料,亦即是 menuentry 底下的內容
      -o 執行檔:就是要給 iPXE 執行的檔名,通常副檔名會是 .efi
      -O x86_64-efi:就是這個執行檔的格式,當然要針對你的學生端電腦平台來設計
      -p /usr/lib/grub/x86_64-efi :grub2 的各種需要的模組
      -v :只是查看製作流程
      模組:例如 fat ext2 xfs search 等等
      
    4. 安裝所需要的 grub2 模組,因為我們的 Server 安裝時,使用的是傳統 BIOS 的方式,因此並不存在 /usr/lib/grub/x86_64-efi 目錄, 所以需要先安裝這個項目才行:
      # yum search grub
      # yum install grub2-efi-x64-modules
      # ll -d /usr/lib/grub/x86*
      drwxr-xr-x. 2 root root 12288  6月  3 09:13 /usr/lib/grub/x86_64-efi
      
    5. 開始設計 linux, win10class, win10exam 的各項需要資料:
      # 1. 先來製作 Linux 相關的工作:
      # mkdir /vmdisk/rootfs/grub2
      # cd /vmdisk/rootfs/grub2
      # vim linux.cfg
      echo "Embedded configuration file in this grub images"
      search --file --set=root  /efi/centos/grubx64.efi
      set prefix=($root)/efi/centos
      chainloader ($root)/efi/centos/grubx64.efi
      boot
      
      # grub2-mkimage -c linux.cfg -O x86_64-efi -o linux.efi -p /usr/lib/grub/x86_64-efi \
        fat exfat ext2 xfs part_gpt search_fs_uuid search_fs_file search \
        normal font all_video configfile all_video gzio \
        echo linuxefi lsefi chain boot multiboot multiboot2
      
      # ll linux*
      -rwxr-xr-x. 1 root root     183  6月  3 09:43 linux.cfg
      -rw-r--r--. 1 root root  783872  6月  3 10:35 linux.efi
      
      # file linux.*
      linux.cfg: ASCII text
      linux.efi: PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
      
      
      # 2. 開始處理 win10class 這個系統: # vim win10class.cfg echo "Embedded configuration file in this grub images" search --file --set=root /EFI/win10class/Boot/bootmgfw.efi set prefix=($root)/EFI/win10class/Boot/bootmgfw.efi chainloader ($root)/EFI/win10class/Boot/bootmgfw.efi boot # grub2-mkimage -c win10class.cfg -O x86_64-efi -o win10class.efi -p /usr/lib/grub/x86_64-efi \ fat exfat ext2 xfs part_gpt search_fs_uuid search_fs_file search \ normal font all_video configfile all_video gzio \ echo linuxefi lsefi chain boot multiboot multiboot2
      # 3. 處理 win10exam 這個系統 # vim win10exam.cfg echo "Embedded configuration file in this grub images" search --file --set=root /EFI/win10exam/Boot/bootmgfw.efi set prefix=($root)/EFI/win10exam/Boot/bootmgfw.efi chainloader ($root)/EFI/win10exam/Boot/bootmgfw.efi boot # grub2-mkimage -c win10exam.cfg -O x86_64-efi -o win10exam.efi -p /usr/lib/grub/x86_64-efi \ fat exfat ext2 xfs part_gpt search_fs_uuid search_fs_file search \ normal font all_video configfile all_video gzio \ echo linuxefi lsefi chain boot multiboot multiboot2 # ll *efi; file *efi -rw-r--r--. 1 root root 783872 6月 3 10:40 linux.efi -rw-r--r--. 1 root root 783872 6月 3 10:40 win10class.efi -rw-r--r--. 1 root root 783872 6月 3 10:40 win10exam.efi linux.efi: PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows win10class.efi: PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows win10exam.efi: PE32+ executable (EFI application) x86-64 (stripped to external PDB), for MS Windows
    6. 接下來,開始來搞定 iPXE 的呼叫吧!整個流程也很簡單:
      # 1. 將 efi 執行檔複製到 iPXE 的環境下:
      # mkdir /var/www/html/ipxe/efi
      # cp /vmdisk/rootfs/grub2/*.efi /var/www/html/ipxe/efi
      
      
      # 2. 修改 iPXE 的選單部份~ # vim /var/www/html/ipxe/menu.php # 選單部份改成這樣: :start menu iPXE ${version} Boot Menu (ip ${net0/ip}, mac ${net0/mac}) item --gap -- ------------------------- Use diskless system ---------------------------- item diskless Go To diskless item --gap -- item --gap -- ------------------------- Use BIOS system -------------------------------- item local Go To Local HD booting item win10class Go To Windows 10 Class item win10exam Go To Windows 10 Exam item --gap -- item --gap -- ------------------------- Use UEFI system -------------------------------- item uefilocal Go To Local HD booting item uefiwin10class Go To Windows 10 Class item uefiwin10exam Go To Windows 10 Exam item --gap -- item --gap -- ------------------------- Advanced Options ------------------------------- item memtest Go To Memtest86 item shell Drop to iPXE shell item instcent Install CentOS 7 use KSU FTP item reboot Reboot computer choose --timeout ${menu-timeout} --default ${menu-default} selected || goto exit set menu-timeout 0 goto ${selected} .... # 各個開機項目改成這樣: :uefilocal echo Go into CentOS grub menu list set base-url http://${net0/gateway}/ipxe/ chain ${base-url}/efi/linux.efi || goto failed :uefiwin10class echo Go To Windows 10 class set base-url http://${net0/gateway}/ipxe/ chain ${base-url}/efi/win10class.efi || goto failed :uefiwin10exam echo Go To Windows 10 exam set base-url http://${net0/gateway}/ipxe/ chain ${base-url}/efi/win10exam.efi || goto failed
    7. 接下來,開機測試,你就會發現有這幾個選單,而且都可以順利的進入個別的系統囉!

很快的,我們就擁有 UEFI 的開機選單!當然,這個選單還是得要依據你的 host 環境而定!比起 BIOS 單純從 boot sector 去找問題, UEFI 的設置還是稍嫌嘛煩!若要萬用於所有的系統,還是需要做點額外的工作設定才行!

使用 rootfs 搭配 partclone 進行備份、復原的任務

現在,跟 MSDOS 相同的,我們需要的是透過 rootfs 來進行備份與費源~現在,先來搞定備份的任務!備份同樣儲存到 192.168.19.254:/vmdisk/backups 囉!

  1. 開始備份的行為,先將 uefios.xml 重新開機進入 rootfs 裡頭,然後依序這樣做囉:
    # 1. 開始進行掛載的動作:
    # showmount -e 192.168.19.254
    Export list for 192.168.19.254:
    /vmdisk/backups 192.168.19.0/24,127.0.0.0/8
    
    # mount -t nfs 192.168.19.254:/vmdisk/backups /mnt
    # df -Th /mnt
    案系統                       類型  容量  已用  可用 已用% 掛載點
    192.168.19.254:/vmdisk/backups nfs4  358G  141G  217G   40% /mnt
    
    # mkdir /mnt/uefi
    # ll /mnt
    drwxr-xr-x 2 root root 144  5月 28 15:33 msdos  <==前一章節的備份
    drwxr-xr-x 2 root root   6  6月  3 11:18 uefi   <==此章節的備份
    
    
    # 2. 開始備份 partition tables,不過我們忘記安裝 gdisk 在 rootfs 了... # yum install gdisk # gdisk -l /dev/vda > /mnt/uefi/gpt.partition.txt # sgdisk --backup=/mnt/uefi/gpt.partition.backup /dev/vda # file /mnt/uefi/gpt.partition.* /mnt/uefi/gpt.partition.backup: x86 boot sector; partition 1: ID=0xee, starthead 0, startsector 1, 283115519 sectors, extended partition table (last)\011, code offset 0x0 /mnt/uefi/gpt.partition.txt: ASCII text
    # 3. 開始備份 UEFI 的開機 FAT 磁區 # partclone.vfat -c -d -s /dev/vda1 -I | gzip -c -1 > /mnt/uefi/uefios.vda1.img.gz Partclone v0.3.11 http://partclone.org 開始備份 裝置 (/dev/vda1) 到 印象檔 (-) Reading Super Block Calculating bitmap... Please wait... 經過:00:00:01, 剩餘: 00:00:00, 完成:100.00% 全部時間:00:00:01, 100.00% completed! done! 檔案系統: FAT16 Device size: 209.7 MB = 409600 Blocks Space in use: 63.7 MB = 124320 Blocks Free Space: 146.1 MB = 285280 Blocks 裝置區塊大小: 512 Byte 經過:00:00:02, 剩餘: 00:00:00, 完成:100.00%, 速率: 1.91GB/min current block: 409600, total block: 409600, Complete: 100.00% 全部時間:00:00:02, 平均速率: 1.9GB/min, 100.00% completed! Syncing... OK! 備份 裝置 (/dev/vda1) 到 印象檔 (-) 完成 Cloned successfully.
    # 4. 開始備份 Linux 分割槽 # partclone.ext4 -c -d -s /dev/vda2 -I | gzip -c -1 > /mnt/uefi/uefios.vda2.img.gz Partclone v0.3.11 http://partclone.org 開始備份 裝置 (/dev/vda2) 到 印象檔 (-) Reading Super Block Calculating bitmap... Please wait... 經過:00:00:01, 剩餘: 00:00:00, 完成:100.00% 全部時間:00:00:01, 100.00% completed! done! 檔案系統: EXTFS Device size: 5.4 GB = 1310720 Blocks Space in use: 2.0 GB = 496800 Blocks Free Space: 3.3 GB = 813920 Blocks 裝置區塊大小: 4096 Byte 經過:00:00:48, 剩餘: 00:00:00, 完成:100.00%, 速率: 2.54GB/min current block: 1132527, total block: 1310720, Complete: 100.00% 全部時間:00:00:48, 平均速率: 2.5GB/min, 100.00% completed! Syncing... OK! 備份 裝置 (/dev/vda2) 到 印象檔 (-) 完成 Cloned successfully.
    # 5. 開始備份 win10class 分割槽 # partclone.ntfs -c -d -s /dev/vda3 -I | gzip -c -1 > /mnt/uefi/uefios.vda3.img.gz Partclone v0.3.11 http://partclone.org 開始備份 裝置 (/dev/vda3) 到 印象檔 (-) Reading Super Block Calculating bitmap... Please wait... 經過:00:00:01, 剩餘: 00:00:00, 完成:100.00% 全部時間:00:00:01, 100.00% completed! done! 檔案系統: NTFS Device size: 107.4 GB = 26214399 Blocks Space in use: 13.3 GB = 3257901 Blocks Free Space: 94.0 GB = 22956498 Blocks 裝置區塊大小: 4096 Byte 經過:00:05:36, 剩餘: 00:00:00, 完成:100.00%, 速率: 2.38GB/min current block: 3512350, total block: 26214399, Complete: 100.00% 全部時間:00:05:36, 平均速率: 2.4GB/min, 100.00% completed! Syncing... OK! 備份 裝置 (/dev/vda3) 到 印象檔 (-) 完成 Cloned successfully.
    # 6. 開始備份 win10exam 分割槽 # partclone.ntfs -c -d -s /dev/vda4 -I | gzip -c -1 > /mnt/uefi/uefios.vda4.img.gz Partclone v0.3.11 http://partclone.org 開始備份 裝置 (/dev/vda4) 到 印象檔 (-) Reading Super Block Calculating bitmap... Please wait... 經過:00:00:01, 剩餘: 00:00:00, 完成:100.00% 全部時間:00:00:01, 100.00% completed! done! 檔案系統: NTFS Device size: 32.0 GB = 7812859 Blocks Space in use: 11.6 GB = 2828740 Blocks Free Space: 20.4 GB = 4984119 Blocks 裝置區塊大小: 4096 Byte 經過:00:04:44, 剩餘: 00:00:00, 完成:100.00%, 速率: 2.45GB/min current block: 2993088, total block: 7812859, Complete: 100.00% 全部時間:00:04:44, 平均速率: 2.4GB/min, 100.00% completed! Syncing... OK! 備份 裝置 (/dev/vda4) 到 印象檔 (-) 完成 Cloned successfully. # ll /mnt/uefi -rw-r--r-- 1 root root 17920 6月 3 11:31 gpt.partition.backup -rw-r--r-- 1 root root 825 6月 3 11:30 gpt.partition.txt -rw-r--r-- 1 root root 30634743 6月 3 11:32 uefios.vda1.img.gz -rw-r--r-- 1 root root 792479750 6月 3 11:34 uefios.vda2.img.gz -rw-r--r-- 1 root root 6303197278 6月 3 11:40 uefios.vda3.img.gz -rw-r--r-- 1 root root 5085825695 6月 3 11:45 uefios.vda4.img.gz
    處理完畢之後,就可以直接關機啦!
  2. 建立 uefios2 的系統來進行復原測試:
    # 1. 先建立 uefios2 的相關資料:
    # cd /vmdisk
    # vim create_vm_settings.sh
    ....
    vmnames="uefios2"
    ....
    
    # sh create_vm_settings.sh
    # qemu-img create -f qcow2 uefios2.img 135G
    # vim uefios2.xml
      <os>
        <type arch="x86_64" machine='q35' >hvm</type>
        <loader readonly='yes' type='pflash'>/usr/share/OVMF/OVMF_CODE.secboot.fd</loader>
        <nvram>/vmdisk/uefios2.fd</nvram>
        <boot dev="network" />
        <boot dev="cdrom" />
        <boot dev="hd" />
        <bootmenu enable='off'/>
      </os>
    ....
        <disk type="file" device="cdrom">
          <driver name="qemu" type="raw"/>
          <source file=""/>
          <target dev="sda" bus="sata"/>
          <readonly/>
        </disk>
    
    # virsh create uefios2.xml
    
    
    # 2. 使用 tail -f /var/log/messages 找到 IP 後,登入 rootfs 環境工作: # yum install gdisk # mount -t nfs 192.168.19.254:/vmdisk/backups /mnt # 2.a 先復原磁碟分割: # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sr0 11:0 1 1024M 0 rom vda 253:0 0 135G 0 disk <==未分割狀態 # sgdisk --load-backup=/mnt/uefi/gpt.partition.backup /dev/vda # lsblk NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT sr0 11:0 1 1024M 0 rom vda 253:0 0 135G 0 disk ├─vda1 253:1 0 200M 0 part ├─vda2 253:2 0 5G 0 part ├─vda3 253:3 0 100G 0 part └─vda4 253:4 0 29.8G 0 part # 2.b 復原 UEFI 資料 # gzip -c -d /mnt/uefi/uefios.vda1.img.gz | partclone.vfat -I -r -s - -o /dev/vda1 Partclone v0.3.11 http://partclone.org 開始還原 印象檔 (-) 到 裝置 (/dev/vda1) Calculating bitmap... Please wait... done! 檔案系統: FAT16 Device size: 209.7 MB = 409600 Blocks Space in use: 63.7 MB = 124320 Blocks Free Space: 146.1 MB = 285280 Blocks 裝置區塊大小: 512 Byte 經過:00:00:02, 剩餘: 00:00:00, 完成:100.00%, 速率: 1.91GB/min current block: 409600, total block: 409600, Complete: 100.00% 全部時間:00:00:02, 平均速率: 1.9GB/min, 100.00% completed! Syncing... OK! 還原 印象檔 (-) 到 裝置 (/dev/vda1) 完成 Cloned successfully. # 2.c 復原 Linux 管理系統 # gzip -c -d /mnt/uefi/uefios.vda2.img.gz | partclone.ext4 -I -r -s - -o /dev/vda2 Partclone v0.3.11 http://partclone.org 開始還原 印象檔 (-) 到 裝置 (/dev/vda2) Calculating bitmap... Please wait... done! 檔案系統: EXTFS Device size: 5.4 GB = 1310720 Blocks Space in use: 2.0 GB = 496800 Blocks Free Space: 3.3 GB = 813920 Blocks 裝置區塊大小: 4096 Byte 經過:00:00:32, 剩餘: 00:00:00, 完成:100.00%, 速率: 3.82GB/min current block: 1132527, total block: 1310720, Complete: 100.00% 全部時間:00:00:32, 平均速率: 3.8GB/min, 100.00% completed! Syncing... OK! 還原 印象檔 (-) 到 裝置 (/dev/vda2) 完成 Cloned successfully. # 2.d 復原 Windows 10 Class 系統 # gzip -c -d /mnt/uefi/uefios.vda3.img.gz | partclone.ntfs -I -r -s - -o /dev/vda3 Partclone v0.3.11 http://partclone.org 開始還原 印象檔 (-) 到 裝置 (/dev/vda3) Calculating bitmap... Please wait... done! 檔案系統: NTFS Device size: 107.4 GB = 26214399 Blocks Space in use: 13.3 GB = 3257901 Blocks Free Space: 94.0 GB = 22956498 Blocks 裝置區塊大小: 4096 Byte 經過:00:03:34, 剩餘: 00:00:00, 完成:100.00%, 速率: 3.74GB/min current block: 3512350, total block: 26214399, Complete: 100.00% 全部時間:00:03:34, 平均速率: 3.7GB/min, 100.00% completed! Syncing... OK! 還原 印象檔 (-) 到 裝置 (/dev/vda3) 完成 Cloned successfully. # 2.e 復原 Windows 10 Exam 系統 # gzip -c -d /mnt/uefi/uefios.vda4.img.gz | partclone.ntfs -I -r -s - -o /dev/vda4 Partclone v0.3.11 http://partclone.org 開始還原 印象檔 (-) 到 裝置 (/dev/vda4) Calculating bitmap... Please wait... done! 檔案系統: NTFS Device size: 32.0 GB = 7812859 Blocks Space in use: 11.6 GB = 2828740 Blocks Free Space: 20.4 GB = 4984119 Blocks 裝置區塊大小: 4096 Byte 經過:00:03:02, 剩餘: 00:00:00, 完成:100.00%, 速率: 3.82GB/min current block: 2993088, total block: 7812859, Complete: 100.00% 全部時間:00:03:02, 平均速率: 3.8GB/min, 100.00% completed! Syncing... OK! 還原 印象檔 (-) 到 裝置 (/dev/vda4) 完成 Cloned successfully.
    # 3. 檢測一下 system ID 是否回復正常了! # blkid /dev/vda1: SEC_TYPE="msdos" LABEL="BOOTDEV" UUID="F1D2-A34F" TYPE="vfat" PARTLABEL="EFI System Partition" PARTUUID="a532352a-c250-4a72-bcf0-b54e3561ead1" /dev/vda2: UUID="1ca1faf4-0add-4659-b2de-c759bc32e7ec" TYPE="ext4" PARTUUID="0af3cd6a-c76c-4f6b-bbb9-9542ac2fbee1" /dev/vda3: UUID="FA9EA3109EA2C48B" TYPE="ntfs" PARTUUID="6c2d84be-a40b-4774-9f39-58c8b7e169bc" /dev/vda4: UUID="EC8E0BE78E0BA8E2" TYPE="ntfs" PARTUUID="f8e584d4-43fa-4065-9051-8c60828162ef"
    基本上,到這一個步驟就已經完成了 UEFI 的系統復原!因為與 BIOS 環境不一樣,我們不需要重建 grub 的開機環境! 原因是, grub 的開機環境就已經放在 /dev/vda1 這一個 VFAT 檔案系統格式的分割槽內了!所以就無須復原 grub 啦! 也不需要重建 MBR 囉!接下來,請重新開機測試看看能不能分別進入三個系統吧!

參考資料題