Virtualize Fixup Legacy Windows 2000 XP on Ubuntu

I got handed a 40Gb disk....

=Virtualising a Win 2000 machine=

Well I plugged it into my older test pc with an IDE slot, a lot safer when trying to clone via USB [if there are any bad sectors a USB adapter will usually fall over in my experience]

Sounded like a chainsaw, best thing to do is dd it quick and presume worst case, i.e. it is full of bad sectors and other reading problems. ddrescue time! (the newer ddrescue is in a package called gddrescue, but the program within is ddrescue, just to confuse.)

Over ten years worth of power on hours and 160 reboots! pretty impressive!?!



Backup old disk with gddrescue
Boot from a live linux - I used Ubuntu 14.10, enable universe repository and 'sudo apt-get install gddrescue'

Assuming /dev/sda is the old drive, and /media/somewhere is target, target file 40Gb.dd and write to logfile 'logfile' in current working directory (which is a writeable temporary home directory in Ubuntu live boot)

This is a brilliant program will cope with knackered disks and read at max speed of the drive if its working ok, so no reason not to use it and use dd or such.

sudo ddrescue /dev/sda /media/somewhere/40Gb.dd logfile

Assuming that went ok, now start working with the 40Gb.dd image and turn the horrid thing off to save my ears!

Check image looks right
$ fdisk -l 40Gb.dd

Disk 40Gb.dd: 37.3 GiB, 40027029504 bytes, 78177792 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xd59cd59c

Device       Boot Start      End  Sectors  Size Id Type 40Gb.dd1     *       63 78156224 78156162 37.3G  7 HPFS/NTFS/exFAT

To check the end is correct, do this, the last sector should be a copy of the first boot sector $ hexdump -C -s $((63*512)) -n 512 40Gb.dd $ hexdump -C -s $((78156224*512)) -n 512 40Gb.dd
 * 1) first boot sector
 * 1) backup copy at end (-s skip = end sector * bytes/sector)

They should both have the NTFS signature

$ hexdump -C -s $((78156224*512)) -n 512 40Gb.dd 951238000 eb 52 90 4e 54 46 53 20  20 20 20 00 02 04 00 00  |.R.NTFS    .....| 951238010 00 00 00 00 00 f8 00 00  3f 00 ff 00 3f 00 00 00  |........?...?...| 951238020 00 00 00 00 80 00 80 00  81 91 a8 04 00 00 00 00  |................| 

Test the image
If you now use qemu/kvm/VMM or such that can run raw disks, create a virtual machine and try booting it, it will most likely start to boot and BSOD very quickly with stop error 7b.

Mount new image as block device
To do most of the rest, the image needs mounting as a block device. There are other ways, but this is easiest.

sudo modprobe nbd sudo qemu-nbd -c /dev/nbd0 40Gb.dd
 * 1) mount disk image on virtual block device nbd0

Import registry with reged (chntpw) to fix booting issues (stop error 7b)
The CriticalDeviceDatabase in the Windows registry will need fixing up to work with the Virtual machines IDE 'hardware'. The below should fix it to work on most.

(It would be easier to do this if you have access to the original machine before the drive gets removed etc as you can run the .reg file in windows, but I didn't.)

Save this reg file out as 07b_fixup.reg

udisks --mount /dev/nbd0p1 sudo add-apt-repository universe sudo apt-get update sudo apt-get install chntpw reged -I -v /media/disk/WINNT/system32/config/system HKEY_LOCAL_MACHINE\\SYSTEM 07b_fixup.reg udisks --unmount /dev/nbd0p1
 * 1) mount first partition p1, this will get mounted on /media/disk by default in ubuntu with udisks
 * 1) import the reg file (below), should be no errors.
 * 1) unmount partition


 * Note qemu/kvm/vmm by default uses ven_8086&dev_7010, i.e. 8086:7010 (Intel 82371SB PIIX3 IDE), 8086:2922 (82801IR/IO/IH ICH9R SATA) , 1000:0012 (LSI Logic / Symbios 53c895a SCSI)
 * Note I think virtualbox by default uses ven_8086&dev_7111

Test it boots
It should now boot.


 * If it doesn't, check these exists (remount partition), the Intel one being what matters (assuming your VM is using an Intel IDE driver). If they don't you will need to obtain them from a Win2000 CD, expand and copy here.

/media/disk/WINNT/system32/drivers/pciide.sys

/media/disk/WINNT/system32/drivers/intelide.sys

(On XP this will be /WINDOWS/ not /WINNT/, most of info here is as relevant to XP and Win2000)


 * Having further BSOD's can easily cause ntfs corruption and if the 7b returns it can be one of above files has been freshly corrupted.


 * Check the CurrentControlSet is ControlSet001 (check HKLM\SYSTEM\Select\Current is 1) otherwise you will need to adjust all the registry file key names or change Current.


 * Stop error is 0x000007e - If the CPU type is changing from AMD to Intel or vice versa, you will need to remove/set to manual the original CPU's service in the registry too, I think this only applies to XP not win2k?


 * Stop Error (in XP at least) 0x000000CE is also CPU AmdK7 Service is trying to start on Intel hardware, change start type to 4 to disable

So going from Intel to AMD, Remove whole key or set start to 4: HKLM\SYSTEM\CurrentControlSet\Services\Intelppm

Virtualising an AMD pc on Intel, do same to AMD service, not sure of its name though, key starts AMDsomething!


 * Stop error 0x00000024 can just mean you need to run chkdsk /f c: after some previous crash

[HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4D36E967-E325-11CE-BFC1-08002BE10318}] or {4F919108-4ADF-11D5-882D-00B0D02FE381} it can also cause a 0x0000007b stop error. nulling the contents of the LowerFilter can fix, e.g. [HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Control\Class\{4F919108-4ADF-11D5-882D-00B0D02FE381}] "LowerFilters"=hex(7):00
 * If you are trying to fix another BSOD bootup problem and have been disabling services via setting Start=0x0000004 - if this service is set as a LowerFilter in a drive relevant Class, say


 * Double check you are setting the correct / active ControlSet i.e. ControlSet001 or ControlSet002 or ControlSet003 !!

Mount image and shrink filesystem and partition
Assuming above works, you can now shrink it down.

This can be done from terminal but so much easier from gparted

sudo gparted /dev/nbd0

Shrink partition and filesystem down as far as you want - in this case the filesystem was only 2.5Gb so I shrunk it to about 3Gb.

Check it looks about right, check the start sector stayed the same, old disks will be 63, (newer OS's are likely to be Mb aligned and start at 2048). (You will need to use ntfsfixboot if you changed it which isn't great on non-real disks)

Check new smaller disk looks right
$ fdisk -l /dev/nbd0

Disk /dev/nbd0: 37.3 GiB, 40027029504 bytes, 78177792 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xd59cd59c

Device     Boot Start     End Sectors Size Id Type /dev/nbd0p1 *      63 6146047 6145985   3G  7 HPFS/NTFS/exFAT

Looks good to me.

Check the end is correct, so should have a NTFS boot sector copy.

$ hexdump -C -s $((6146047*512)) -n 512 40Gb.dd bb8ffe00 eb 52 90 4e 54 46 53 20  20 20 20 00 02 04 00 00  |.R.NTFS    .....| bb8ffe10 00 00 00 00 00 f8 00 00  3f 00 ff 00 3f 00 00 00  |........?...?...| bb8ffe20 00 00 00 00 80 00 80 00  bc c7 5d 00 00 00 00 00  |..........].....| 

Cut disk down to partition
Use the end sector count from fdisk, so assuming each sector is the default 512 bytes (also the default dd bs=512, so count can be in sectors.)

sudo qemu-nbd -d /dev/nbd0 dd if=40Gb.dd of=XGb.dd count=$((6146047+1)) 6146048+0 records in 6146048+0 records out 3146776576 bytes (3.1 GB) copied, 80.0636 s, 39.3 MB/s
 * 1) unmount the block device, you are working with a raw disk again (plain file)
 * 1) copy out the actual partition/data used

To check you cut it right, the last sector (last 512 bytes) should still show correctly as a NTFS boot sector copy, doing this. hexdump -C -s $((6146047*512)) -n 512 XGb.dd hexdump -C -s $((6146047*512)) XGb.dd
 * 1) should be same as missing a -n length out, as it is the end

That should now be it, it should boot and be nice and small!

The 4Gb problem
Unfortunately for me this didn't boot with an error from the MBR 'A disk read error occurred', after a lot of dicking about I found out if the physical image size is less than 4Gb it won't work, no matter what the partition size - at least with Win2000 and Qemu.

Cutting it down to exactly 4Gb, it was then ok.

dd if=40Gb.dd of=4Gb.dd bs=1G count=4
 * Note Use G not GB as that gives it multiples of 1000 not 1024!

(Thus this is a 4Gb disk with a 3Gb partition and filesystem.)

$ fdisk -l 4Gb.dd

Disk 4Gb.dd: 4 GiB, 4294967296 bytes, 8388608 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xd59cd59c

Device    Boot Start     End Sectors Size Id Type 4Gb.dd1   *       63 6146047 6145985   3G  7 HPFS/NTFS/exFAT

At this point test boot again and it worked fine, you could re-expand the filesystem and partition with gparted to fit the full 4Gb.


 * Note If you resize back up, the final NTFS boot sector copy may not be at the very end of the disk so don't panic if it's all 0's. (it should exist not far back from the end though - perhaps to do with gparted doing some end Mb alignment or something?)

=Quick one-shot guide / Overview=

sudo ddrescue /dev/sda /media/somewhere/40Gb.dd logfile
 * 1) extract old disk

sudo modprobe nbd sudo qemu-nbd -c /dev/nbd0 40Gb.dd udisks --mount /dev/nbd0p1 sudo add-apt-repository universe sudo apt-get update sudo apt-get install chntpw reged -I -v /media/disk/WINNT/system32/config/system HKEY_LOCAL_MACHINE\\SYSTEM 07b_fixup.reg udisks --unmount /dev/nbd0p1 sudo gparted /dev/nbd0 fdisk -l /dev/nbd0 sudo qemu-nbd -d /dev/nbd0 dd if=40Gb.dd of=XGb.dd count=$((fdisk_end_sector+1))
 * 1) insert nbd module
 * 1) mount disk image on virtual block device nbd0
 * 1) mount first partition p1, this will get mounted on /media/disk by default in ubuntu with udisks
 * 1) install reged / chntpw if not already installed
 * 1) import the reg file to fix CDDB, should be no errors.
 * 1) unmount partition
 * 1) resize partition/filesystem
 * 1) note the new end sector from fdisk below
 * 1) unmount block device
 * 1) copy out the actual partition/data used

=Debugging errors=

Boot errors
A good way to find out what is going on if you have a problem is look at the MBR and boot sector, as the errors are in here in plain text for issues involving them

This will dump the MBR and boot sector, if boot sector starts at 63

$ hexdump -C -n $((512*64)) 40Gb.dd

These errors are from the MBR

00000120 32 e4 8a 56 00 cd 13 eb  d6 61 f9 c3 49 6e 76 61  |2..V.....a..Inva| 00000130 6c 69 64 20 70 61 72 74  69 74 69 6f 6e 20 74 61  |lid partition ta| 00000140 62 6c 65 00 45 72 72 6f  72 20 6c 6f 61 64 69 6e  |ble.Error loadin| 00000150 67 20 6f 70 65 72 61 74  69 6e 67 20 73 79 73 74  |g operating syst| 00000160 65 6d 00 4d 69 73 73 69  6e 67 20 6f 70 65 72 61  |em.Missing opera| 00000170 74 69 6e 67 20 73 79 73  74 65 6d 00 00 00 00 00  |ting system.....|

these are from the NTFS boot sector

00007f80 eb f2 c3 0d 0a 41 20 64  69 73 6b 20 72 65 61 64  |.....A disk read| 00007f90 20 65 72 72 6f 72 20 6f  63 63 75 72 72 65 64 00  | error occurred.| 00007fa0 0d 0a 4e 54 4c 44 52 20  69 73 20 6d 69 73 73 69  |..NTLDR is missi| 00007fb0 6e 67 00 0d 0a 4e 54 4c  44 52 20 69 73 20 63 6f  |ng...NTLDR is co| 00007fc0 6d 70 72 65 73 73 65 64  00 0d 0a 50 72 65 73 73  |mpressed...Press| 00007fd0 20 43 74 72 6c 2b 41 6c  74 2b 44 65 6c 20 74 6f  | Ctrl+Alt+Del to| 00007fe0 20 72 65 73 74 61 72 74  0d 0a 00 00 00 00 00 00  | restart........|

=Press Ctrl+Alt+Del to restart=

If you get "Press Ctrl+Alt+Del to restart" it may be because the head setting isn't correct for the hardware.

I just had an old Win2000 P4 pc die and on trying the cloned IDE drive in various other newer donor machines found it wouldn't boot with 'A disk read error occurred, Press Ctrl+Alt+Del to restart'

240 heads implies 'Large' Mode, 255 heads LBA - I think. The original was 240 heads so presume newer machine only liked LBA mode, thus change heads to 255.

Working with raw image from dd (or gddrescue etc) from a 40Gb IDE WD drive with fdisk....

Expert command (m for help): p Disk WD40Gb.raw: 37.3 GiB, 40020664320 bytes, 78165360 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x70347034

Device     Boot    Start      End  Sectors Id Type            Start-C/H/S   End-C/H/S Attrs WD40Gb.raw1 *         63 20971439 20971377  7 HPFS/NTFS/exFAT       0/1/1 1023/63/239    80 WD40Gb.raw2     20971440 78155279 57183840  f W95 Ext'd (LBA)    1023/1/0 1023/63/239    00 WD40Gb.raw5     20971503 78155279 57183777  7 HPFS/NTFS/exFAT    1023/1/1 1023/63/239    00

240 heads [239 above] (need 255). To fix this you need to re-create the partition table with 255 heads and then alter the NTFS boot sector to also have 255 heads. (using ntfsfixboot. In ubuntu 15.04 at least this comes with package 'partclone' in /usr/sbin/partclone.ntfsfixboot )

Nuke old partition table
Run fdisk


 * Make a note of the start and end sectors. Delete each partition 5,2,1
 * Write and exit

Re-create partition it with correct geometry
$ sudo fdisk -H255 -S63 WD40Gb.raw

Welcome to fdisk (util-linux 2.25.2). Changes will remain in memory only, until you decide to write them. Be careful before using the write command.

Command (m for help): c DOS Compatibility flag is set (DEPRECATED!)

Command (m for help): n Partition type p  primary (0 primary, 0 extended, 4 free) e  extended (container for logical partitions) Select (default p):

Using default response p. Partition number (1-4, default 1): First sector (63-78165359, default 63): Last sector, +sectors or +size{K,M,G,T,P} (63-78165359, default 78165359): 20971439

Created a new partition 1 of type 'Linux' and of size 10 GiB.

Command (m for help): t Selected partition 1 Hex code (type L to list all codes): 7 Changed type of partition 'Linux' to 'HPFS/NTFS/exFAT'.

Command (m for help): n Partition type p  primary (1 primary, 0 extended, 3 free) e  extended (container for logical partitions) Select (default p): e Partition number (2-4, default 2): First sector (20971440-78165359, default 20971440): Last sector, +sectors or +size{K,M,G,T,P} (20971440-78165359, default 78165359): 78155279

Created a new partition 2 of type 'Extended' and of size 27.3 GiB.

Command (m for help): t Partition number (1,2, default 2): Hex code (type L to list all codes): f You cannot change a partition into an extended one or vice versa. Delete it first.

Type of partition 2 is unchanged: Extended.

Command (m for help): n Partition type p  primary (1 primary, 1 extended, 2 free) l  logical (numbered from 5) Select (default p): l

Adding logical partition 5 First sector (20971503-78155279, default 20971503): Last sector, +sectors or +size{K,M,G,T,P} (20971503-78155279, default 78155279):

Created a new partition 5 of type 'Linux' and of size 27.3 GiB.

Command (m for help): t Partition number (1,2,5, default 5): 5 Hex code (type L to list all codes): 7

Changed type of partition 'Linux' to 'HPFS/NTFS/exFAT'.

Command (m for help): a Partition number (1,2,5, default 5): 1

The bootable flag on partition 1 is enabled now.

Command (m for help): x

Expert command (m for help): p Disk WD40Gb.raw: 37.3 GiB, 40020664320 bytes, 78165360 sectors Geometry: 255 heads, 63 sectors/track, 4865 cylinders Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0x70347034

Device     Boot    Start      End  Sectors Id Type            Start-C/H/S   End-C/H/S Attrs WD40Gb.raw1 *         63 20971439 20971377  7 HPFS/NTFS/exFAT       0/1/1 1023/63/254    00 WD40Gb.raw2     20971440 78155279 57183840  5 Extended        1023/63/254 1023/63/254    00 WD40Gb.raw5     20971503 78155279 57183777  7 HPFS/NTFS/exFAT 1023/63/254 1023/63/254    00

Expert command (m for help): r

Command (m for help): w

The partition table has been altered. Synching disks.

ntfsfixboot
Fixup first and backup boot sectors to 255 heads.

This will lack the bios entry as you are mounting it directly - it doesn't see it as a real partition and hence cant see the BIOS geometry as 255 head and say its not right. (on a real partition you get 4 lines with the BIOS bit)

Manually specify start sector 63, 255 heads and 63 sectors.

$ sudo modprobe nbd $ sudo qemu-nbd -c /dev/nbd0 WD40Gb.raw $ sudo /usr/sbin/partclone.ntfsfixboot -p -b -s 63 -h 255 -t 63 /dev/nbd0p1 ntfsfixboot version 1.0 Heads	Sectors	Start filesystem:	240	63	63 backup sector	240	63	63 target:		255	63	63 Changes will be written to disk only with -w flag $ sudo /usr/sbin/partclone.ntfsfixboot -w -b -s 63 -t 63 -h 255 /dev/nbd0p1 ntfsfixboot version 1.0 done! $ sudo /usr/sbin/partclone.ntfsfixboot -p -b -s 63 -t 63 -h 255 /dev/nbd0p1 ntfsfixboot version 1.0 Heads	Sectors	Start filesystem:	255	63	63 backup sector	255	63	63 target:		255	63	63 No changes neccessary. $ sudo qemu-nbd -d /dev/nbd0 /dev/nbd0 disconnected

Now you should find it boots without error :)

Other possibilities
Setting these two conditions on the fixed up 255 LBA mode drive above gives...
 * CHS mode set when drive set for 255 head LBA = 'Missing operating system'
 * Large mode set when drive set for 255 head LBA = 'A disk read error occurred, Press Ctrl+Alt+Del to restart'

On another 20Gb drive, the above two conditions also can generate 'Invalid partition boot sector Press any key to restart loading operation system' on another drive I tried. (this was drive used page top for extracting second partition) Expert command (m for help): p Disk /dev/sdd: 19 GiB, 20404101120 bytes, 39851760 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disklabel type: dos Disk identifier: 0xac84ac84

Device    Boot Start      End  Sectors Id Type               Start-C/H/S   End-C/H/S Attrs /dev/sdd1         63    32129    32067 12 Compaq diagnostics       0/1/1    1/63/254    00 /dev/sdd2 *    32130 39825134 39793005  c W95 FAT32 (LBA)          2/1/0 1022/63/254    80

Error comes from below, dont understand how its getting to here (starts offset 0x23000) as its in the first non-set bootable partition!!

sudo hexdump -C -s $((512*280)) -n 1024 /dev/sdd .......... 000232a0 10 c3 28 07 44 69 73 6b  20 72 65 61 64 20 65 72  |..(.Disk read er| 000232b0  72 6f 72 20 6c 6f 61 64  69 6e 67 20 6f 70 65 72  |ror loading oper| 000232c0  61 74 69 6e 67 20 73 79  73 74 65 6d 35 07 0d 0a  |ating system5...| 000232d0  50 72 65 73 73 20 61 6e  79 20 6b 65 79 20 74 6f  |Press any key to| 000232e0  20 72 65 73 74 61 72 74  20 6c 6f 61 64 69 6e 67  | restart loading| 000232f0  20 6f 70 65 72 61 74 69  6f 6e 20 73 79 73 74 65  | operation syste| 00023300  6d 0d 0a 70 31 0d 0a 50  72 65 73 73 20 3c 46 31  |m..p1..Press  to enter HP U| 00023320  74 69 6c 69 74 79 20 50  61 72 74 69 74 69 6f 6e  |tility Partition| 00023330  2e 2e 2e 20 20 20 20 20  20 20 20 20 20 0d 0a 20  |...          .. | 00023340  20 20 20 20 20 20 20 20  20 20 6f 72 20 61 6e 79  |          or any| 00023350  20 6f 74 68 65 72 20 6b  65 79 20 74 6f 20 70 72  | other key to pr| 00023360 6f 63 65 65 64 20 20 20  20 20 20 20 20 20 20 20  |oceed           | 00023370 20 20 20 20 20 21 1f 0d  0a 45 6e 74 65 72 69 6e  |     !...Enterin| 00023380 67 20 48 50 20 55 74 69  6c 69 74 79 20 50 61 72  |g HP Utility Par| 00023390 74 69 74 69 6f 6e 0d 0a  28 07 55 74 69 6c 69 74  |tition..(.Utilit| 000233a0  79 20 50 61 72 74 69 74  69 6f 6e 20 73 74 61 72  |y Partition star| 000233b0  74 75 70 20 69 6e 74 65  72 6e 61 6c 20 65 72 72  |tup internal err| 000233c0  6f 72 19 07 4e 6f 20 61  63 74 69 76 65 20 70 61  |or..No active pa| 000233d0  72 74 69 74 69 6f 6e 20  66 6f 75 6e 64 1d 07 49  |rtition found..I| 000233e0  6e 76 61 6c 69 64 20 70  61 72 74 69 74 69 6f 6e  |nvalid partition| 000233f0  20 62 6f 6f 74 20 73 65  63 74 6f 72 3c 07 0d 0a  | boot sector<...|

=Other things to do=

Change the HAL to ACPI Multiprocessor PC if you are upgrading from an ancient to old pc with a dual core CPU!

In Win2000 you can do this in device manager > update driver > show all > pick it from list.

=Comments=