修改MBR,在主引導扇區和第一分區之間找個地方放grub是老黃歷了。
電腦有nvme和SATA盤各一塊,UEFI啟動。nvme盤裝的是debian和grub,SATA盤裝的是Windows10。它們各有一個EFI分區。
~# blkid
/dev/nvme0n1p1: UUID="BDEB-5168" TYPE="vfat"
PARTUUID="85a71363-aa05-4ca2-ab37-b14e81559b25"
/dev/sda1: UUID="485B-1474" TYPE="vfat" PARTLABEL="EFI system partition"
PARTUUID="30dfa707-6611-431f-ba2c-74247bde9167"
UUID和分區的UUID不同。BIOS看到485B-1474就基本上顯示Windows Boot Manager。在操作過程中出現過Windows Boot Manager (debian)。
第一塊nvme盤的名字是/dev/nvme0n1。
mount | grep boot
/dev/nvme0n1p1 on /boot/efi
即/boot/efi是EFI分區的根目錄。mount /dev/sda1 /mnt后目錄結構差一層,最好mount mount /dev/sda1 /mnt/efi,這樣兩者一致。
然后先備份再修改。建議用tar,我覺得它保存不同文件系統的文件屬性比較保險。
# tree /boot/efi
/boot/efi
├── EFI
│ ├── debian
│ │ ├── BOOTX64.CSV
│ │ ├── fbx64.efi
│ │ ├── grub.cfg
│ │ ├── grubx64.efi
│ │ ├── mmx64.efi
│ │ └── shimx64.efi
# cat /boot/efi/EFI/debian/grub.cfg
search.fs_uuid acc415d0-f703-4ab1-97e3-b0401ccf7c64 root
set prefix=($root)'/boot/grub'
configfile $prefix/grub.cfg
/boot/grub/grub.cfg里:
insmod ext2
search --no-floppy --fs-uuid --set=root acc415d0-f703-4ab1-97e3-b0401ccf7c64
echo 'Loading Linux 6.1.0-18-amd64 ...'
linux /boot/vmlinuz-6.1.0-18-amd64 root=UUID=acc415d0-f703-4ab1-97e3-b0401ccf7c64 ro quiet
echo 'Loading initial ramdisk ...'
initrd /boot/initrd.img-6.1.0-18-amd64
debian的/是/dev/nvme0n1p2: UUID="acc415d0-f703-4ab1-97e3-b0401ccf7c64" TYPE="ext4" PARTUUID="5bc7c066-2dca-4835-9828-073c2cd85ae0";/boot是/下的一個子目錄;/boot/efi是/dev/nvme0n1p1。
Windows10的則在Microsoft目錄下。Microsoft/下有Boot和Recovery兩個目錄。grub引導Windows時:chainloader /EFI/Microsoft/Boot/bootmgfw.efi。和Microsoft同級的還有個Boot/,下面有個bootx64.efi,刪掉后仍然可以啟動:BIOS (N100, AMI)和grub都直接加載bootmgfw.efi。
我把SATA上的Microsoft的copy到了nvme下(UUID要相應地修改),刪掉SATA上的Microsoft后把nvme上的debian copy了過去,BIOS設成從SATA啟動。即啟動Windows時:BIOS-SATA-NVME-SATA。[微笑]
我不是吃飽了撐的:BIOS-NVME,grub老說找不到485B-1474。CPU和nvme太快了,SATA(雖然也是SSD)還沒來得及加載,詳情見鏈接
menuentry 'Windows Boot Manager (on /dev/sda1)'
--class windows --class os $menuentry_id_option
'osprober-efi-485B-1474' {
insmod part_gpt
insmod fat
search --fs-uuid --set=root BDEB-5168
chainloader /EFI/Microsoft/Boot/bootmgfw.efi
}
把os prober找到的485B-1474換成了BDEB-5168。Windows能這么啟動是好事,也是壞事。我曾用傲梅分區助手把Windows從SATA搬到了nvme,從nvme啟動后它還是用SATA當C:因為當初是裝在SATA上的,系統(注冊表?)里某個地方寫死了C:=第1塊SATA盤的第2個分區。
UUID 是 通用唯一識別碼(Universally Unique Identifier)的縮寫。簡單來說,就是它可以讓分布式系統中的所有元素,都能有唯一的辨識信息。每個人都可以創建不與其它人沖突的UUID。在這樣的情況下,就不需考慮數據的名稱重復問題。這里我們只講UUID在分區上的應用。
在傳統Linux中,對IDE設備以 hd 命名,對 SCSI 設備以 sd 命名。比如第一塊 IDE 設備接口磁盤地址為 /dev/hda ,其第一塊IDE設備磁盤的第一個分區為 /dev/hda1/ 。同理,第一塊 SATA 接口磁盤的第一個分區為 /dev/sda1 。在單硬盤系統中,這樣的命名方式簡單易懂,可是在多磁盤的系統中,又該如何區分呢?而以UUID命名磁盤分區則解決了這個問題。
第一種辦法,可以通過 ls 的方式查看。
ls /dev/disk/by-uuid/
這種方式并不能知道UUID和磁盤分區位置的對應關系。
第二種辦法,通過 blkid 命令。
blkid /dev/sda3
第三種辦法,通過 gparted 查看分區,在右鍵信息中找到UUID。
在Linux中,格式化磁盤,會自動生成UUID。但是這也許不是我們想要的,也許我們要把UUID用在其他方面,總不能自己編吧。這時候我們就要借助命令生成UUID。
在現代Linux中,可以直接使用 uuid 命令生成,部分老舊的系統需要用 uuidgen 。
另外,Linux內核本身具有生成隨機 UUID 的功能。
cat /proc/sys/kernel/random/uuid
該指令運行一次就生成一個不同的UUID。
分區的文件系統不同,修改UUID的命令也有所不同。修改UUID需要離線操作,修改ext、xfs、reiserfs 的UUID比較穩定,修改 btrfs 的UUID則有數據丟失的危險。強烈建議,無論學習還是生產環境,備份好數據在操作。
EXT文件系統
tune2fs {device} -U {uuid}
XFS 文件系統
xfs_admin -U {uuid} {device}
reiserfs 文件系統
tunefs.reiserfs -i {uuid} {device}
文件中的UUID,當然以 fstab 和 grub.cfg 最多。前者是Linux開機自動掛載文件系統,后者是啟動管理器調用啟動信息的關鍵。如果他們中的UUID錯了,當然就是無法進入系統。還是提前備份好相關文件。
sed -i 's/{olduuid}/{newuuid}/g' grub.cfg
好了,關于Linux下分區UUID,就介紹這么多了。一般情況也就用 tar 恢復系統的時候會用到。