I grabbed a copy of the Windows 7 release candidate off a colleague at work today. Yeah I’m a Linux guy but it’s good to keep tabs on what the dark side is doing, so I thought I’d upgrade Vista SP1 on my laptop to Win 7. My laptop is a dual boot setup with Ubuntu 9.04 as well as Windows, and of course I want to keep a backup of the Vista partition so I can revert to it when the RC expires in March 2010 (I would probably pay to upgrade to Win7 if the cost was sub $50, but this is not likely).
Listing the partitions to begin with:
sudo fdisk -l
My hard disk is partitioned with Windows on a primary partition an Linux on an extended one. Sda1 is my Vista partition, sda5 is Linux root and sda7 is my storage space.
Disk /dev/sda: 500.1 GB, 500107862016 bytes
255 heads, 63 sectors/track, 60801 cylinders
Units = cylinders of 16065 * 512 = 8225280 bytes
Disk identifier: 0x2af0e241
Device Boot Start End Blocks Id System
/dev/sda1 * 1 9710 77994551 7 HPFS/NTFS
/dev/sda2 9711 60801 410388457+ 5 Extended
/dev/sda5 9711 22764 104856223+ 83 Linux
/dev/sda6 60410 60801 3148708+ 82 Linux swap / Solaris
/dev/sda7 22765 60409 302383431 83 Linux
I want to make a backup of sda1, which is an 80gb NTFS partition, to a file on sda7. A straight dd copy would result in an 80gb file which is a bit much, so there are a couple of tricks that can be used to get the file size down.
The first is zeroing out the empty space parts of the drive. Deleting files on a hard drive doesn’t blank the space it previously occupied, it simply marks it as unused space so that it can be used for something else. Since dd is a low level copy, it copies everything, including blocks that have deleted data which we don’t want. So to make sure this data is erased we mount the filesystem and create a file full of zeros on it (easiest way to do this is to simply click on it by going to places if you use Gnome, otherwise you can use the mount command if you wish e.g. “mount -t ntfs-3g /dev/sda1 /mnt/windows”):
dd if=/dev/zero of=/media/disk/zeroFile.tmp bs=4M
The bs=4M parameter isn’t essential, but it makes the process significantly faster.
Once dd process stops, the partition should be full and you can delete zeroFile.tmp. You now know that the free space has no data in it.
Taking a straight dd image now would still result in an 80gb file however, as dd will simply copy all the zeroes verbatim. Fortunately blank space will compress down to nothing, so we can pipe the output from dd through gzip. The parameters I’ve used are “c” (which writes output to std out), and “9” for best compression.
In effect we will have 3 programs running:
- dd bs=4M if=/dev/sda1
- gzip -c9
- dd bs=4M of=/media/disk/Vista.img.gz
When you exclude the “if=” or “of=” parameters, dd reads or writes from stdin/stdout, depending on which is omitted. So the first dd is reading the partition and outputting to stdout, and the second one is reading from stdin and writing it to the file. Gzip sits in the middle compressing the stream.
The full command is thus:
dd bs=4M if=/dev/sda1 | gzip -c9 | dd bs=4M of=/media/disk/Vista.img.gz
To restore the partition you would use:
dd if=/media/disk/Vista.img.gz | gzip -dc | dd of=/dev/sda1
(bearing in mind of course that this overwrites sda1 with whatever is in the image file)
I don’t know how Windows 7 handles foreign bootloaders yet, but before installing Windows it would also be wise to backup your mbr, which is the first 512 bytes on your hard drive:
dd if=/dev/sda of=bootSectorBackup.img bs=512 count=1
And to restore it:
dd if=bootSectorBackup.img of=/dev/sda bs=512 count=1
Note that in this case the block size (bs) and count parameters are very important, as they define how much of the disk is overwritten. Also if Windows does overwrite the bootloader, you’ll need a Linux boot CD to restore your MBR.
Right, now I just need to go and install Win 7.
If you want to check the status of the dd copy (see this post), it’s more useful to send the sigusr1 command to the “read” instance of dd (the one with the if= parameter), as that way you can see how much of the disk has been read. If you sent it to the output instance, you’d get the amount of data which has been written to disk, and this is after it has been compressed so unless you know what size the resulting file is going to be it’s not much use!