Konwersja MBR <=> GPT

Kategoria: Artykuły, etykiety: mbr, konwersja, gpt, dysk

Dodany: 2014-01-04 16:54 (zmodyfikowany: 2014-01-11 01:52)
Przez: morfik

Wyświetleń: 23407

Od jakiegoś czasu nosiłem się z zamiarem utworzenia na swoim dysku tablicy partycji GPT. Problem w tym, że tam jest wgranych paręset GiB danych i nie mam gdzie tego upchnąć. Jedyne co mi wpadło do głowy to przekonwertowanie tablicy MBR na GPT. Nie żebym jakoś tego potrzebował, w końcu mam dysk 1,5TB ale tak z ciekawości chciałem zobaczyć czy da się to zrobić w sposób łatwy i bezproblemowy. No i dało się. W roli głównej wystąpił mój stary dysk (80GB) -- zrobiłem na nim 6 partycji, 3 zwykłe i 3 rozszerzone. Pierwsza partycja jest pod wina xp, druga to zaszyfrowany system linuxowy ale jak zwykle zapomniałem zostawić trochę miejsca na partycję /boot , a ta wylądowała na pozycji sda6. Partycja trzecia to niezaszyfrowany swap, a pozostałe dwie (5 i 7) to dwa zaszyfrowane voluminy, z których jeden celowo umieszczony na końcu dysku, drugi zaś na początku rozszerzonej partycji. Cel to przekonwertować tablicę partycji MBR na GPT (i vice versa) bez utraty danych.

Konwersja MBR -> GPT

Tak wygląda dysk widziany oczami parted (z uwzględnieniem wolnych przestrzeni):

(parted) print free                                                       
Model: ATA WDC WD800JB-00JJ (scsi)
Disk /dev/sda: 80,0GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size    Type      File system     Flags
        32,3kB  1049kB  1016kB            Free Space
 1      1049kB  31,5GB  31,5GB  primary   ntfs            boot
 2      31,5GB  43,0GB  11,5GB  primary
 3      43,0GB  44,1GB  1074MB  primary   linux-swap(v1)
 4      44,1GB  80,0GB  36,0GB  extended
 5      44,1GB  54,6GB  10,5GB  logical
 6      54,6GB  65,0GB  10,5GB  logical   ext4            boot
 7      65,0GB  80,0GB  15,0GB  logical
        80,0GB  80,0GB  56,8kB            Free Space

By przeprowadzić bezproblemowo konwersję z MBR na GPT trzeba mieć troszeczkę wolnego miejsca na początku i na końcu dysku. Ile? Struktura GPT wygląda tak: 512 bajtowy MBR + 512bajtowy nagłówek GPT + 16 KiB głównej tablicy partycji. Łącznie daje to 34 sektory 512 bajtowe, co przekłada się na 34*512=17408 bajtów wolnego miejsca na początku dysku. Ale tablica partycji GPT ma jeszcze backup swojej zawartości, który jest zlokalizowany na końcu dysku i w jego skład wchodzi kopia głównej tablicy partycji -- 16 KiB oraz kopia nagłówka 1 sektor 512 bajtowy. Łącznie 33 sektory co daje 16896 bajtów potrzebnego miejsca na końcu dysku.

Obecnie większość narzędzi tworzących partycje na dysku ustawia równanie do 1MiB co przekłada się na 2048 wolnych sektorów na początku dysku, więc tutaj nie powinno być problemów ze spełnieniem wymagań pod GPT. Ale takie równanie do 1MiB może czasem zając resztę dysku. W moim przypadku, jak widać powyżej, zostało trochę wolnego miejsca -- 56,8kB. Także u mnie wszystko jest ok. W przypadku jednak gdyby partycja wypełniła dysk do końca, trzeba będzie ją skrócić.

By przekonwertować tablicę partycji odpalamy gdisk:

# gdisk /dev/sda
GPT fdisk (gdisk) version 0.8.5

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


***************************************************************
Found invalid GPT and valid MBR; converting MBR to GPT format.
THIS OPERATION IS POTENTIALLY DESTRUCTIVE! Exit by typing 'q' if
you don't want to convert your MBR partitions to GPT format!
***************************************************************

Jak widać, gdisk wykrył, że ma do czynienia z tablicą partycji MBR. Konwertowanie polega na wpisaniu w:

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/sda.
The operation has completed successfully.

Sprawdzamy, czy faktycznie się przekonwertowało:

# gdisk /dev/sda
GPT fdisk (gdisk) version 0.8.5

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

Found valid GPT with protective MBR; using GPT.

Wygląda w porządku, teraz sprawdzamy układ partycji:

Command (? for help): p
Disk /dev/sda: 156299375 sectors, 74.5 GiB
Logical sector size: 512 bytes
Disk identifier (GUID): 526AC8D7-EEC8-4BA3-B654-31EF40528AF2
Partition table holds up to 128 entries
First usable sector is 34, last usable sector is 156299341
Partitions will be aligned on 2048-sector boundaries
Total free space is 8236 sectors (4.0 MiB)

Number  Start (sector)    End (sector)  Size       Code  Name
   1            2048        61442047   29.3 GiB    0700  Microsoft basic data
   2        61442048        83970047   10.7 GiB    8300  Linux filesystem
   3        83970048        86067199   1024.0 MiB  8200  Linux swap
   5        86069248       106549247   9.8 GiB     8300  Linux filesystem
   6       106551296       127031295   9.8 GiB     8300  Linux filesystem
   7       127033344       156299263   14.0 GiB    8300  Linux filesystem

Czyli bez problemu proces się zakończył. Rzućmy jeszcze okiem na to jak wygląda struktura partycji w parted:

# parted /dev/sda
GNU Parted 2.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free
Model: ATA WDC WD800JB-00JJ (scsi)
Disk /dev/sda: 80,0GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start   End     Size    File system     Name                  Flags
        17,4kB  1049kB  1031kB  Free Space
 1      1049kB  31,5GB  31,5GB  ntfs            Microsoft basic data  msftdata
 2      31,5GB  43,0GB  11,5GB                  Linux filesystem
 3      43,0GB  44,1GB  1074MB  linux-swap(v1)  Linux swap
        44,1GB  44,1GB  1049kB  Free Space
 5      44,1GB  54,6GB  10,5GB                  Linux filesystem
        54,6GB  54,6GB  1049kB  Free Space
 6      54,6GB  65,0GB  10,5GB  ext4            Linux filesystem
        65,0GB  65,0GB  1049kB  Free Space
 7      65,0GB  80,0GB  15,0GB                  Linux filesystem
        80,0GB  80,0GB  39,9kB  Free Space

No tu już widać trochę różnic. Przede wszystkim są dziury. W miejscu gdzie zaczynały się dyski na rozszerzonej partycji obecnie jest trochę wolnego miejsca. Dla lepszego rozeznania możemy ustawić jako jednostkę sektory:

(parted) unit s                                                           
(parted) print free                                                       
Model: ATA WDC WD800JB-00JJ (scsi)
Disk /dev/sda: 156299375s
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start       End         Size       File system     Name                  Flags
        34s         2047s       2014s      Free Space
 1      2048s       61442047s   61440000s  ntfs            Microsoft basic data  msftdata
 2      61442048s   83970047s   22528000s                  Linux filesystem
 3      83970048s   86067199s   2097152s   linux-swap(v1)  Linux swap
        86067200s   86069247s   2048s      Free Space
 5      86069248s   106549247s  20480000s                  Linux filesystem
        106549248s  106551295s  2048s      Free Space
 6      106551296s  127031295s  20480000s  ext4            Linux filesystem      legacy_boot
        127031296s  127033343s  2048s      Free Space
 7      127033344s  156299263s  29265920s                  Linux filesystem
        156299264s  156299341s  78s        Free Space

albo bajty:

(parted) unit b
(parted) print free                                                       
Model: ATA WDC WD800JB-00JJ (scsi)
Disk /dev/sda: 80025280000B
Sector size (logical/physical): 512B/512B
Partition Table: gpt

Number  Start         End           Size          File system     Name                  Flags
        17408B        1048575B      1031168B      Free Space
 1      1048576B      31458328575B  31457280000B  ntfs            Microsoft basic data  msftdata
 2      31458328576B  42992664575B  11534336000B                  Linux filesystem
 3      42992664576B  44066406399B  1073741824B   linux-swap(v1)  Linux swap
        44066406400B  44067454975B  1048576B      Free Space
 5      44067454976B  54553214975B  10485760000B                  Linux filesystem
        54553214976B  54554263551B  1048576B      Free Space
 6      54554263552B  65040023551B  10485760000B  ext4            Linux filesystem      legacy_boot
        65040023552B  65041072127B  1048576B      Free Space
 7      65041072128B  80025223167B  14984151040B                  Linux filesystem
        80025223168B  80025263103B  39936B        Free Space

Jak widać jest to 2048 sektorów albo, jak kto woli, 2048*512=1048576 bajtów i jest to wynikiem równania do 1MiB. Można te przestrzenie pokasować np. w gparted przez rozszerzenie partycji i rozciągnięcie systemu plików, jeśli to komuś przeszkadza. Można też zauważyć, że ilość wolnego miejsca na początku i końcu dysku uległa zmianie.

Sprawdźmy zatem czy zaszyfrowany linux wciąż gdzieś tam jest na dysku:

# cryptsetup luksOpen /dev/sda2 sda2_crypt
Hasło dla /dev/sda2:       
# mount /dev/mapper/sda2_crypt /mnt
# ls -al /mnt
razem 136
drwxr-xr-x  28 root root  4096 sty  3 05:55 .
drwxr-xr-x  31 root root   260 sty  4 12:15 ..
drwxr-xr-x   2 root root  4096 sty  4 07:55 bin
drwxr-xr-x   2 root root  4096 sty  4 10:16 boot
lrwxrwxrwx   1 root root    11 lis 11 01:00 cdrom -> media/cdrom
drwxr-xr-x  10 root root  4096 gru 30 10:24 cgroup
drwx------   3 root root  4096 lis 11 02:16 .config
drwxr-xr-x   2 root root  4096 sty  4 09:52 dev
drwxr-xr-x 144 root root 12288 sty  4 10:48 etc
drwxr-xr-x   5 root root  4096 gru 21 09:32 home
drwxrwxrwt   2 root root  4096 lis 11 02:54 .ICE-unix
drwxr-xr-x  18 root root  4096 gru 30 03:04 lib
drwxr-xr-x   2 root root  4096 gru  6 19:57 lib64
drwx------   2 root root 16384 lis 11 00:11 lost+found
drwxr-xr-x  15 root root  4096 sty  4 10:14 media
drwxr-xr-x   2 root root  4096 sty  4 09:52 mnt
drwxr-xr-x   9 root root  4096 gru 27 08:08 opt
dr-xr-xr-x   2 root root  4096 sty  4 07:59 proc
drwx------   2 root root  4096 lis 11 02:54 pulse-PKdhtXMmr18n
drwxr-xr-x  23 root root  4096 sty  4 10:27 root
drwxr-xr-x   4 root root  4096 sty  4 11:00 run
drwxr-xr-x   2 root root 12288 sty  4 07:55 sbin
drwxr-xr-x   2 root root  4096 lis 11 00:18 srv
dr-xr-xr-x   2 root root  4096 sty  4 07:59 sys
drwxrwxrwt   9 root root  4096 sty  4 11:03 tmp
drwxr-xr-x   2 root root  4096 lis 11 02:52 tmp_ram
drwxr-xr-x  11 root root  4096 lis 11 07:16 usr
drwxr-xr-x  13 root root  4096 lis 12 20:52 var
drwxrwxrwt   2 root root  4096 lis 11 02:58 .X11-unix

Wygląda na to, że przetrwał proces konwersji i nic mu nie jest. Ale to nie jest koniec naszej pracy. Trzeba jeszcze wgrać bootloader, w tym przypadku będzie to extlinux. Tworzymy zatem środowisko pod chroot i wchodzimy do systemu:

# mount -o bind /dev /mnt/dev/
# mount -o bind /dev/pts /mnt/dev/pts
# mount -o bind /sys /mnt/sys
# mount -o bind /proc /mnt/proc
# chroot /mnt

W sgdisk ustawiamy bit drugi na partycję, która zawiera katalog /boot. W moim przypadku jest to partycja 6:

# sgdisk /dev/sda --attributes=6:set:2
The operation has completed successfully.
# sgdisk /dev/sda --attributes=6:show
6:2:1 (legacy BIOS bootable)

Jeśli ktoś jest ciekawe jakie bity można ustawić, poniżej rozpiska:

# sgdisk /dev/sda --attributes=list
0: system partition
1: hide from EFI
2: legacy BIOS bootable
60: read-only
62: hidden
63: do not automount

Wgrywamy teraz MBR i VBR, tak samo jak w przypadku tablicy partycji MBR:

# dd bs=440 conv=notrunc count=1 if=/usr/lib/syslinux/gptmbr.bin of=/dev/sda
# extlinux --install /boot/extlinux/
/boot/extlinux/ is device /dev/sda6

Drugie polecenie powinno utworzyć plik ldlinux.sys w katalogu /boot/extlinux .

Po tym zabiegu można rebootnąć pc. U mnie system wystartował. Jedyne co to winxp się nie chciał odpalić i to trzeba mieć na uwadze -- winxp nie wystartuje jeśli dysk ma tablicę partycji GPT.

W drugą stronę, czyli GPT -> MBR

Konwertowanie partycji z GPT na MBR jest trochę trudniejsze. Przede wszystkim potrzebne są dziury dla rozszerzonych partycji, te same, które postały przy konwersji z MBR na GPT. Jeśli ich nie mamy na dysku, prawdopodobnie nie da rady przenieść niektórych partycji z GPT na MBR. Można je zawsze stworzyć. Trzeba pamiętać by miały 2048 sektorów. Mi dziury zostały, także wykorzystam już to co jest. Odpalamy gdiska:

# gdisk /dev/sda
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): r

Recovery/transformation command (? for help): g

Warning: 0xEE partition doesn't start on sector 1. This can cause problems
in some OSes.

I to w zasadzie tyle roboty. Podejrzymy jeszcze jak będzie wyglądał nowy układ partycji:

MBR command (? for help): p

** NOTE: Partition numbers do NOT indicate final primary/logical status,
** unlike in most MBR partitioning tools!

** Extended partitions are not displayed, but will be generated as required.

Disk size is 156299375 sectors (74.5 GiB)
MBR disk identifier: 0x00000000
MBR partitions:

                                                   Can Be   Can Be
Number  Boot  Start Sector   End Sector   Status   Logical  Primary   Code
   1                  2048     61442047   primary              Y      0x07
   2              61442048     83970047   primary              Y      0x83
   3              83970048     86067199   primary              Y      0x82
   5              86069248    106549247   logical     Y               0x83
   6             106551296    127031295   logical     Y               0x83
   7             127033344    156299263   logical     Y               0x83

Jak można zauważyć są 3 podstawowe i 3 logiczne na rozszerzonej partycji. Czyli wracamy do pozycji wyjściowej. Jeśli jednak by się zdarzyło, że układ nie odpowiada naszym oczekiwaniom, możemy go zmienić. Poniżej jest lista opcji, z których możemy skorzystać:

a    toggle the active/boot flag
c   recompute all CHS values
l   set partition as logical
o   omit partition
p   print the MBR partition table
q   quit without saving changes
r   set partition as primary
s   sort MBR partitions
t   change partition type code
w   write the MBR partition table to disk and exit

l - ustawia logiczną partycję, r - ustawia podstawową partycję, o - nie doda partycji do tablicy MBR.

Ja potrzebowałem tylko ustawić flagę boot na 6 partycję:

MBR command (? for help): a
Toggle active flag for partition: 6

MBR command (? for help): p       

Disk size is 156299375 sectors (74.5 GiB)
MBR disk identifier: 0x00000000
MBR partitions:

                                                   Can Be   Can Be
Number  Boot  Start Sector   End Sector   Status   Logical  Primary   Code
   1                  2048     61442047   primary              Y      0x07
   2              61442048     83970047   primary              Y      0x83
   3              83970048     86067199   primary              Y      0x82
   5              86069248    106549247   logical     Y               0x83
   6      *      106551296    127031295   logical     Y               0x83
   7             127033344    156299263   logical     Y               0x83

MBR command (? for help): w

Converted 6 partitions. Finalize and exit? (Y/N): y
GPT data structures destroyed! You may now partition the disk using fdisk or
other utilities.

Warning: 0xEE partition doesn't start on sector 1. This can cause problems
in some OSes.

U mnie po przekonwertowaniu z GPT na MBR trzeba było zresetować pc by zobaczyć zmiany. Poniżej się prezentuje dysk, po powrocie do tablicy partycji MBR:

# parted /dev/sda 
GNU Parted 2.3
Using /dev/sda
Welcome to GNU Parted! Type 'help' to view a list of commands.
(parted) print free                                                       
Model: ATA WDC WD800JB-00JJ (scsi)
Disk /dev/sda: 80,0GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start   End     Size    Type      File system     Flags
        32,3kB  1049kB  1016kB            Free Space
 1      1049kB  31,5GB  31,5GB  primary   ntfs
 2      31,5GB  43,0GB  11,5GB  primary
 3      43,0GB  44,1GB  1074MB  primary   linux-swap(v1)
        44,1GB  44,1GB  1048kB            Free Space
 4      44,1GB  80,0GB  36,0GB  extended                  lba
 5      44,1GB  54,6GB  10,5GB  logical
 6      54,6GB  65,0GB  10,5GB  logical   ext4            boot
 7      65,0GB  80,0GB  15,0GB  logical
        80,0GB  80,0GB  56,8kB            Free Space

Jedyna różnica to wolne 2047 sektorów przed rozszerzoną partycją. Normalnie, to wolne miejsce by było przed pierwszym dyskiem na rozszerzonej partycji. Nie wpływa to jednak na nic.

By system się zabootował prawidłowo, trzeba jeszcze zreinstalować extlinuxa, tworzymy zatem środowisko pod chroot:

# cryptsetup luksOpen /dev/sda2 sda2_crypt
Hasło dla /dev/sda2: 
# mount /dev/mapper/sda2_crypt /mnt
# mount /dev/sda6 /mnt/boot/
# mount -o bind /dev/ /mnt/dev/
# mount -o bind /dev/pts /mnt/dev/pts
# mount -o bind /proc /mnt/proc
# mount -o bind /sys /mnt/sys
# chroot /mnt/

I wgrywamy MBR i VBR:

# dd bs=440 conv=notrunc count=1 if=/usr/lib/syslinux/mbr.bin of=/dev/sda
1+0 przeczytanych recordów
1+0 zapisanych recordów
skopiowane 440 bajtów (440 B), 0,0300519 s, 14,6 kB/s  
# extlinux --install /boot/extlinux/
/boot/extlinux/ is device /dev/sda6

Po resecie nawet windows się odpalił. Znaczy, że wszystko wróciło do normy.

OSnews Wykop Blip Flaker Kciuk Śledzik Facebook Identi.ca Twitter del.icio.us Google Bookmarks