Moving a NTFS partition

Incomplete! Vista still won't boot!

In brief:

  1. Netboot a real operating system.
  2. dd (or ntfsclone) the partitions to safety.
  3. Repartition disk, but do not change the geometry, and in this simpler example, do not change the partition number.
  4. Restore the ntfs volume in the new partition location.
  5. Set the value for "hidden sectors" to the absolute number of the sector on disk at which the boot sector you are editing is located.

Netboot

e.g., here I netboot NetBSD-amd64/current, but e.g. an ubuntu install disk is also very easy to netboot.

Save the partition

# disklabel -t wd0
TOSHIBA MK1652GS|Automatically generated label:\
        :dt=ESDI:se#512:ns#63:nt#16:sc#1008:nc#310101:\
        :pd#312581808:od#0:\
        :pe#110229488:oe#3074048:te=NTFS:
disklabel: boot block size 0
disklabel: super block size 0
# mount -t nfs quantz:/attic /attic
# dd if=/dev/rwd0e bs=1m | progress -l 55114744k dd of=/attic/rwd0e.raw bs=1m

Time passes... and just to be paranoid:

# dd if=/dev/rwd0d of=/attic/bootblocks.raw bs=1m count=1

(Rather more than just the bootblocks.)

Repartition the disk

# fdisk wd0
Disk: /dev/rwd0d
NetBSD disklabel disk geometry:
cylinders: 310101, heads: 16, sectors/track: 63 (1008 sectors/cylinder)
total sectors: 312581808

BIOS disk geometry:
cylinders: 255, heads: 255, sectors/track: 63 (16065 sectors/cylinder)
total sectors: 312581808

Partition table:
0: NTFS, OS/2 HPFS, QNX2 or Advanced UNIX (sysid 7)
    start 3074048, size 110229488 (53823 MB, Cyls 191/89/27-7052/208/52), Active
1: <UNUSED>
2: <UNUSED>
3: <UNUSED>
First active partition: 0
Drive serial number: 959758887 (0x3934c227)

So, we simply want to move the partition to the "beginning" of the disk which usually means sector 63.

# fdisk -B -0 -u -s 7/63/110229488 -c /usr/mdec/mbr_bootsel wd0
Disk: /dev/rwd0d
NetBSD disklabel disk geometry:
cylinders: 310101, heads: 16, sectors/track: 63 (1008 sectors/cylinder)
total sectors: 312581808

BIOS disk geometry:
cylinders: 255, heads: 255, sectors/track: 63 (16065 sectors/cylinder)
total sectors: 312581808

Do you want to change our idea of what BIOS thinks? [n] n
The data for partition 0 is:
NTFS, OS/2 HPFS, QNX2 or Advanced UNIX (sysid 7)
    start 3074048, size 110229488 (53823 MB, Cyls 191/89/27-7052/208/52), Active
sysid: [0..255 default: 7] 
start: [0..19457cyl default: 63, 0cyl, 0MB] 
size: [0..19457cyl default: 110229488, 6861cyl, 53823MB] 
bootmenu: [] Vista
The bootselect code is not installed, do you want to install it now? [n] y
Update the bootcode from /usr/mdec/mbr_bootsel? [n] y
Update the bootcode from /usr/mdec/mbr_bootsel? [n] y

Boot selector configuration:
Timeout value (0 to 3600 seconds, -1 => never): [-1..3600 default: 10] 
Select the default boot option. Options are:

0: The first active partition
1: Vista
2: Harddisk 0
Default boot option: [0..2 default: 0] 

We haven't written the MBR back to disk yet.  This is your last chance.
Partition table:
0: NTFS, OS/2 HPFS, QNX2 or Advanced UNIX (sysid 7)
    bootmenu: Vista
    start 63, size 110229488 (53823 MB, Cyls 0-6861/120/26), Active
        PBR is not bootable: All bytes are identical (0x00)
1: <UNUSED>
2: <UNUSED>
3: <UNUSED>
Bootselector enabled, timeout 10 seconds.
First active partition: 0
Drive serial number: 959758887 (0x3934c227)
Should we write new partition table? [n] y
# mbrlabel -w wd0
Found NTFS partition; size 110229488 (53822 MB), offset 63
  adding NTFS partition to slot a.

5 partitions:
#        size    offset     fstype [fsize bsize cpg/sgs]
 a: 110229488        63       NTFS                     # (Cyl.      0*- 109354*)
 d: 312581808         0     unused      0     0        # (Cyl.      0 - 310100)
 e: 110229488   3074048       NTFS                     # (Cyl.   3049*- 112404*)

Updating in-core disk label.
# disklabel -t wd0
TOSHIBA MK1652GS|Automatically generated label:\
        :dt=ESDI:se#512:ns#63:nt#16:sc#1008:nc#310101:\
        :pa#110229488:oa#63:ta=NTFS:\
        :pd#312581808:od#0:\
        :pe#110229488:oe#3074048:te=NTFS:
disklabel: boot block size 0
disklabel: super block size 0
disklabel: partitions a and e overlap

Write saved partition back

# dd if=/attic/rwd0e.raw bs=1m | progress -l 55114744k dd of=/dev/rwd0a bs=1m

More time passes...

Hidden sectors

Quoting Anton: The hidden sectors field is a 32-bit field at byte offset 0x11 inside the BIOS parameter block which in turn is at offset 0x0b inside the NTFS boot sector. The NTFS boot sector is the first sector of the partition... The value is stored little endian.

# hexdump -n 32 -C /dev/rwd0a
00000000  eb 52 90 4e 54 46 53 20  20 20 20 00 02 08 00 00  |.R.NTFS    .....|
00000010  00 00 00 00 00 f8 00 00  3f 00 ff 00 00 e8 2e 00  |........?.......|
00000020

So currently, the hidden sectors field (at 0x11 + 0x0b = 0x1c) contains the value 0x002ee800 = 3074048, which matches the offset of wd0e. So, we need to write 63 = 0x3f there instead. Knock together a quick programme to do this:

#include <err.h>
#include <stdint.h>
#include <stdio.h>

int main()
{
        FILE *p;
        off_t offset = 0x11 + 0x0b;
        uint32_t val = 63;

        p = fopen("/dev/wd0a","w");
        if (p == NULL) err(1, "fopen");
        if (fseeko(p, offset, SEEK_SET) == -1) err(1, "fseeko");
        fputc(val       & 0xff, p);
        fputc(val >>  8 & 0xff, p);
        fputc(val >> 16 & 0xff, p);
        fputc(val >> 24 & 0xff, p);
        if (fclose(p) == EOF) err(1, "fclose");

        return 0;
}

(N.B. wd0a, not rwd0a) and now:

# hexdump -n 32 -C /dev/rwd0a
00000000  eb 52 90 4e 54 46 53 20  20 20 20 00 02 08 00 00  |.R.NTFS    .....|
00000010  00 00 00 00 00 f8 00 00  3f 00 ff 00 3f 00 00 00  |........?...?...|
00000020

Boot into Vista

Windows failed to start. A recent hardware or software change might be the cause. To fix the problem:

  1. Insert your Windows installation disc and restart your computer.
  2. Choose your langage settings, and then click Next.
  3. Click Repair your computer.

If you do not have this disc, contact your system administrator or computer manufacturer for assistance.

File: \Windows\system32\winload.exe
Status: 0xc0000225
Info: The selected entry could not be loaded because the application is
      missing or corrupt.

which is fine if your laptop manufacturer supplies an installation disk as opposed to a disk image.

So, boot back into NetBSD,

mount -t ntfs /dev/wd0a /mnt

have a look around in the /mnt/Windows/System32 directory, and a helpful kernel message appears:

ntfs_procfixups: magic doesn't match: 00000000 != 58444e49

(58444e49 = INDX) ntfsinfo for:

... but who knows how to fix that? Maybe this will help?

Optionally store partition as backup

If the nfs server's NetBSD kernel was compiled with

options 	VND_COMPRESSION

you can keep the raw partition as backup, but save some disk space with

quantz# cd /attic
quantz# vndcompress rwd0e.raw rwd0e.cloop2
Using blocksize: 65536 (1221008 complete blocks)

To check it is valid

quantz# vnconfig -z vnd0 rwd0e.cloop2
quantz# mount -t ntfs /dev/vnd0a /mnt
quantz# cd /mnt

and have a look.

Acknowledgements

A big thank you to Anton Altaparmakov for guidance and explaining where hidden sectors are hidden!

Useful links

Patrick Welche, Inference Group, Cavendish Laboratory.

AEGIS logo The Dasher project is supported by the Gatsby Foundation
and by the European Commission in the context of
the AEGIS project — open Accessibility Everywhere: Groundwork, Infrastructure, Standards)