I have one PC running a 1TB hard disk with 57 partitions mostly filled with operating systems. Recently I acquired a 128GB Solid State Disk (SSD) for trying it with the Linux and MS systems. The SSD works no different from any 2.5" hard disk except it is a bit faster and consumes a lot less current.

In the last couple of hours I managed to migrate a Vista-64, Win7-64 and Opensuse 11.2 from the 1TB mechical hard disk to the 128Gb SSD. The former is in a mobile rig that I can pull out in seconds while the second is hooked up as an eSata external hard disk inserted into a docking station. If I pull away the internal 1TB hard disk the external hard disk (SSD) will boot normally as the first and the only bootable disk.

In the original 1TB internal hard disk I have the Vista, swap, Win7 and Opensuse in partition No. 1, 5, 7 and 12 respectively in 50, 1, 50 and 20Gb sizes. In the external SSD the Linux is placed in the sda6 while the other remain in sda1, sda5 and sda7 as before. It is not a good idea to change a MS system partition size during migration due to its inbuilt protection but for Linux it is just a simple file-copying.

There following points may be of interest to the multi-booters

  • How to clone a big disk to a small disk

  • How to manipulate the MS boot loaders

  • How to migrate these systems

  • How to make the boot loaders work after migration

Migration of Vista - cloning the whole hard disk

My Vista in the first partition of the hard disk actually has both NTLDR (for booting Win2k and XP) and bootmgr (for booting one Vista and two Win7, one 32-bit and one 64-bit, only the latter is migrated). Thus I have an interest to preserve the MS boot loaders in the Vista partition. I did this by clone the 1TB disk, known as device sda, into the 128 SSD, device sdb, using a root terminal command from a Linux.
dd if=/dev/sda of=/dev/sdb bs=32256
This was a brutal act of forcing a 128Gb device to receive a 1TB data. However if one understands how a hard disk works then the above operation yields the desirable result.

The new disk was rejected by all operating systems as I expected because the SSD partition table claims to have 1TB size boundary when physically it has only 128Gb. An operating system does not know what to do with it and to play safe none of them would mount it and so in theory the disk is an outcast, except some Linux commands can be used to good effect in such a situation. After all Linux is the mother of all utilities!

With the normal mechanical hard disks the only Linux program that would still read such a disk would be the "fdisk" program but for some reasons this doesn't work on the SSD. My last resort was the terminal program "sfdisk" which must be used with care as it wipes any partition table.

Basically my strategy was to just to delete all the partitions except the first one and the SSD disk should be readable again so that I can access the Vista partition. My Win7 and Opensuse were located in areas exceeding the 128Gb boundary and must be done separately. I seldom use the "sfdisk" program but it is possibly the most lethal partitioning software for the PC. Basically I open up a text terminal in Linux displaying the geometry of the 1TB. The 50Gb the Vista partition occupies from 1st to 6079th cylinder.

I used these root terminal commands to repartition my unreadable hard disk with the first partition starting from default (1st cylinder), size=6078 cylinders, Type 7 for NTFS and * for marking it bootable. These are identical to the original 1TB
sfdisk /dev/sdb << EOF
As you can see the commands are very simple and every user can try it by viewing the man page of sfdisk.

I then powered the PC, removed the internal 1TB internal hard disk, left the bare SSD inserted in the docking station externally, slip in a Grub floppy, powered up the PC and fired up Vista by these commands in a Grub prompt
root (hd0,0)
chainloader +1
The above step is necessary because my 1TB disk has been managed by Grub from Ubuntu 9.10 in sda16 which was no longer available in the SSD. When Grub has been broken without a home it can't boot. However my new sda1 has been cloned by dd and so the original MS boot loader inside the boot sector of sda1 would be intact. So any Grub can fire it up. I just used a floppy but the legacy Grub in a CD, say as a stand alone boot loader or from a selected iso can also do the same job.

By the way re-partitioning of a hard disk doesn't alter the partition interior. Therefore as long as I retain the relevant parts of my partition table I can still access the health data.

During the cloning of the disk the "dd" command was forced to stop when the SSD ran out of space. Thus the majority of the first 128Gb data is still good and I am using only the first 50Gb of it for the Vista.

My next step is to clone the Win7 and copy the Opensuse partition. I did this by powering down the PC, reinstating the internal 1TB disk and booting up a Linux (any one will do). Again I opened up two root terminals. One for using "fdisk -l" to display the partition sizes in cylinder unit and another to create sdb2 as an extended partition using command
fdisk /dev/sdb
The extended partition is for absorbing all the remaining space in the SSD. Inside the extended partition I created sdb5 as Type 82 for swap, sdb6 as Type 83 for Linux and sdb7 as Type 7 for NTFS partition. The crucial point here is I must make my new Win7 partition in the SSD exactly in size, down to the exact 6078 cylinders, as the old Win7 of the 1TB disk. The size of the swap and Linux partition, namely sdb5 and sdb6, are immaterial as I explained below. The SSD is recognised as device sdb when the internal disk is present but becomes device sda once the internal 1TB disk is removed. A mobo always detects the internal disks before the external disks.

Once I have the receiving partitions of Opensuse and Win7 ready I could carry out the migration.

Migration of Opensuse (or any Linux) - by copying the files & fixing the boot loader

After the necessary partitions have been created there are 4 essential steps of formatting, mounting, copying and booting

To format the new partition is by command in root
mkfs.ext3 /dev/sdb6
To mount the source sda12 and the target sdb6 partition
mkdir /mnt/sda12
mount /dev/sda12 /mnt/sda12
mkdir /mnt/sdb6
mount /dev/sdb6 /mnt/sdb6
To copy the files from sda12 to sdb6
cd /mnt/sda12
tar cf - . | ( cd /mnt/sdb6; tar xf -)
To boot the Linux at the new location two files in the new SSD Linux partition must be altered. They are "/etc/fstab" and /boot/grub/menu.lst" which must have the reference of sda12 changed to sdb6.

I list the key sections of the two old files here, mark the relevant parts in blue which need alteration and then list the new files mark the changes in red.

Listing of old etc/fstab in sda12
/dev/disk/by-id/ata-SAMSUNG_HD103UJ_S13PJ1KQ623145-part5 swap                 swap       defaults              0 0
/dev/disk/by-id/ata-SAMSUNG_HD103UJ_S13PJ1KQ623145-part12 /                    ext3       acl,user_xattr        1 1
/dev/disk/by-id/ata-SAMSUNG_HD103UJ_S13PJ1KQ623145-part1 /windows/C           ntfs-3g    users,gid=users,fmask=133,dmask=022,locale=en_GB.UTF-8 0 0
/dev/disk/by-id/ata-SAMSUNG_HD103UJ_S13PJ1KQ623145-part6 /windows/D           ntfs-3g    users,gid=users,fmask=133,dmask=022,locale=en_GB.UTF-8 0 0
/dev/disk/by-id/ata-SAMSUNG_HD103UJ_S13PJ1KQ623145-part7 /windows/E           ntfs-3g    users,gid=users,fmask=133,dmask=022,locale=en_GB.UTF-8 0 0
/dev/disk/by-id/ata-SAMSUNG_HD103UJ_S13PJ1KQ623145-part8 /windows/F           ntfs-3g    users,gid=users,fmask=133,dmask=022,locale=en_GB.UTF-8 0 0
proc                 /proc                proc       defaults              0 0
sysfs                /sys                 sysfs      noauto                0 0
debugfs              /sys/kernel/debug    debugfs    noauto                0 0
devpts               /dev/pts             devpts     mode=0620,gid=5       0 0
New /etc/fstab of sdb6
/dev/sda5  swap                 swap       defaults              0 0
/dev/sda6 /                    ext3       acl,user_xattr        1 1
/dev/sda1 /windows/C           ntfs-3g    users,gid=users,fmask=133,dmask=022,locale=en_GB.UTF-8 0 0
/dev/sda7 /windows/D           ntfs-3g    users,gid=users,fmask=133,dmask=022,locale=en_GB.UTF-8 0 0
proc                 /proc                proc       defaults              0 0
sysfs                /sys                 sysfs      noauto         0 0
debugfs              /sys/kernel/debug    debugfs    noauto     0 0
devpts               /dev/pts             devpts     mode=0620,gid=5       0 0
Old /boot/grub/menu.lst from sda12
default 0
timeout 8
##YaST - generic_mbr
gfxmenu (hd0,11)/boot/message
##YaST - activate

###Don't change this comment - YaST2 identifier: Original name: linux###
    title openSUSE 11.2
    root (hd0,11)
    kernel /boot/vmlinuz root=/dev/disk/by-id/ata-SAMSUNG_HD103UJ_S13PJ1KQ623145-art12 resume=/dev/disk/by-id/ata-SAMSUNG_HD103UJ_S13PJ1KQ623145-part5 splash=silent quiet showopts vga=0x31a
    initrd /boot/initrd
New /boot/grub/menu.lst for the new sdb6
default 0
#timeout 8
##YaST - generic_mbr
gfxmenu (hd0,5)/boot/message
##YaST - activate

###Don't change this comment - YaST2 identifier: Original name: linux###
    title openSUSE 11.2
    root (hd0,5)
    kernel /boot/vmlinuz-2.6.29-6-default root=/dev/sda6 resume=/dev/sda5 splash=silent quiet showopts vga=0x31a
    initrd /boot/initrd-2.6.29-6-default
After the above two files have been corrected to reflect the system has been moved from sda12 to sda6 my Opensuse was ready for booting. Again this was done by powering down, removing the internal hard disk, putting a Grub floppy in, booting up to a Grub prompt and issuing these Grub commands:
root (hd0,5)
setup (hd0,5)
setup (hd0)
The above instructs Grub to select the 6th partition of the first disk, since Grub counts from zero, as the root partition and install itself first within that partition and then in the MBR. To put Grub inside the root partition of a Linux is optional but from now on my Opensuse can be booted by any other boot loader or chainloaded by another Grub (or Lilo).

When I withdrew the floppy the Grub in the MBR now takes charge and boots to either Vista or Opensuse Linux. It was time to migrate and fix the Win7.

Migrating of Win7 - cloning the partition and fixing the boot loader

The same command for cloning the hard disk is used to clone the partition. My source WIn7 was in sda7 and the recipient partition is sdb7, both have exactly the same number of cylinders and same geometry. The command to clone sda12 into sdb6 is simply
dd if=/dev/sda12 of=/dev/sdb6 bs=32256
Before cloning partition sdb was blank and cannot be mounted as there was no filing system inside. After cloning the Win7 partition was not yet bootable. If one wished to see if the cloning works or not just ask a Linux to mount it. If the partition can be mounted without error that means Linux can locate the filing index and the content can be displayed, using commands like
mkdir /mnt/sdb6
mount /dev/sdb6 /mnt/sdb6
ls /mnt/sdb6
To fixed Win7 boot loader one can use the BCDedit.exe available in Vista. Alternatively one can download the free utilities, one of which is EasyBCD installable in Vista and Win7. This graphic tool will lists the entries for bootmgr, which is common to both Vista and Win7, and the user can overwrite any setting. The amendment amounted to no more than letting the EasyBCD to run through the bootmgr configuration and generate the necessary ID number for the Win7 as Vista's configuration remains unchanged and valid. In the Easy BCD I just made sure the partition=D was for Win7 as Vista occupies partition=C.

Finally I had all three operating systems up and running in the faster but smaller SSD. The migration and the write-up took me about half a day. This is the first time I moved Win7 to a different logical partition.

By the way MS system boot loaders are only downward compatible. This is to say Win2k's NTLDR can't boot Xp but Xp's version can boot both. Vista and Win7 use a new common boot loader which I call bootmgr. It doesn't boot Win2k or XP but only the NTLDR. Thus in my case Grub boot everybody. When It boots Vista it actually passes the control to bootmgr. Bootmgr controls NTLDR and would pass the control to it if the user select Win2k or XP, otherwise it is bootmgr's duty to fire Vista or Win7. If one have several MS Windows the bootmgr would take control at the first partition recognised by MS systems. Thus Win2k, Xp, Vista and Win7 can all be installed in logical partitions as long as a primary partition is available to house bootmgr and NTLDR.

For completness I enclose the output of "fdisk -l" showing the partition layout of my 1TB hard disk and 128Gb SSD.
linux-mtbg:/home/saikee # fdisk -l

Disk /dev/sda: 1000.2 GB, 1000204886016 bytes
255 heads, 63 sectors/track, 121601 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0xc100c100

   Device Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1        6079    48828512    7  HPFS/NTFS
/dev/sda2           12159       18237    48829567+  83  Linux
/dev/sda3           18238      120499   821419515    5  Extended
/dev/sda4            6079       12158    48830591+   7  HPFS/NTFS
/dev/sda5           18238       18359      979933+  82  Linux swap / Solaris
/dev/sda6           18360       24438    48828512    7  HPFS/NTFS
/dev/sda7           24439       30517    48828512    7  HPFS/NTFS
/dev/sda8           30517       31733     9767488+  17  Hidden HPFS/NTFS
/dev/sda9           36597       42675    48829536   83  Linux
/dev/sda10          42676       45107    19535008+  83  Linux
/dev/sda11          45108       47539    19535008+  83  Linux
/dev/sda12          47540       49971    19535008+  83  Linux
/dev/sda13          49972       52403    19535008+  83  Linux
/dev/sda14          52404       54835    19535008+  83  Linux
/dev/sda15          54836       57267    19535008+  83  Linux
/dev/sda16          57268       59699    19535008+  83  Linux
/dev/sda17          59700       62131    19535008+  83  Linux
/dev/sda18          62132       64563    19535008+  83  Linux
/dev/sda19          64564       66995    19535008+  83  Linux
/dev/sda20          66996       69427    19535008+  83  Linux
/dev/sda21          69428       71251    14651248+  83  Linux
/dev/sda22          71252       73075    14651248+  83  Linux
/dev/sda23          73076       74899    14651248+  83  Linux
/dev/sda24          74900       76723    14651248+  83  Linux
/dev/sda25          76724       78547    14651248+  83  Linux
/dev/sda26          78548       80371    14651248+  83  Linux
/dev/sda27          80372       82195    14651248+  83  Linux
/dev/sda28          82196       84019    14651248+  83  Linux
/dev/sda29          84020       85843    14651248+  83  Linux
/dev/sda30          85844       87667    14651248+  83  Linux
/dev/sda31          87668       88883     9767488+  83  Linux
/dev/sda32          88884       90099     9767488+  83  Linux
/dev/sda33          90100       91315     9767488+  83  Linux
/dev/sda34          91316       92531     9767488+  83  Linux
/dev/sda35          92532       93747     9767488+  83  Linux
/dev/sda36          93748       94963     9767488+  83  Linux
/dev/sda37          94964       96179     9767488+  83  Linux
/dev/sda38          96180       97395     9767488+  83  Linux
/dev/sda39          97396       98611     9767488+  83  Linux
/dev/sda40          98612       99827     9767488+  83  Linux
/dev/sda41          99828      101043     9767488+  83  Linux
/dev/sda42         101044      102259     9767488+  83  Linux
/dev/sda43         102260      103475     9767488+  83  Linux
/dev/sda44         103476      104691     9767488+  83  Linux
/dev/sda45         104692      105907     9767488+  83  Linux
/dev/sda46         105908      107123     9767488+  83  Linux
/dev/sda47         107124      108339     9767488+  83  Linux
/dev/sda48         108340      109555     9767488+  83  Linux
/dev/sda49         109556      110771     9767488+  83  Linux
/dev/sda50         110772      111987     9767488+  83  Linux
/dev/sda51         111988      113203     9767488+  83  Linux
/dev/sda52         113204      114419     9767488+  83  Linux
/dev/sda53         114420      115635     9767488+  83  Linux
/dev/sda54         115636      116851     9767488+  83  Linux
/dev/sda55         116852      118067     9767488+  83  Linux
/dev/sda56         118068      119283     9767488+  83  Linux
/dev/sda57         119284      120499     9767488+  83  Linux

Partition table entries are not in disk order

Disk /dev/sdb: 128.0 GB, 128035676160 bytes
255 heads, 63 sectors/track, 15566 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0xc100c100

   Device Boot      Start         End      Blocks   Id  System
/dev/sdb1   *           1        6079    48829536    7  HPFS/NTFS
/dev/sdb2            6080       15565    76196295    5  Extended
/dev/sdb5            6080        6202      987966   82  Linux swap / Solaris
/dev/sdb6            6203        9486    26378698+  83  Linux
/dev/sdb7            9487       15565    48829536    7  HPFS/NTFS

The methods I described above are not hard and fast rules but they highlight the following

  • Cloning the whole disk is always the easiest because one doesn't have to bother with the boot loader or disk geometry.

  • Each boot loader can be fixed

  • Linux system can be copied freely between partitions and the target partition is free to change size.

  • It is a lot less work to migrate a MS system with unchanged partition size and the booting is a lot easier if the partition doesn't change position in the hard disk. However the common Vista and Win7 boot loader is a lot friendlier than the NTLDR used by Win2k and Xp.