从Linux克隆Windows分区


12

所以我有一个120 GB的Intel SSD,有一个用于Windows的分区和一个用于Ubuntu的分区。Ubuntu是我的主要操作系统,Windows是游戏。但是现在我想安装Mac OS X,并且希望将其安装在SSD上,因此我希望将Windows移至其他驱动器(我从外壳中取出旧的160GB外部硬盘,用作测试驱动器。无论如何,我还是将游戏放在其他外部设备上,因此,除了启动时间外,性能不会受到影响。

最好的方法是什么?有克隆分区的好工具吗?我之所以这样问,是因为Google在克隆您实际使用/已安装Ubuntu的驱动器方面取得了很多成果,而不是告诉我如何将完全不相关的分区克隆到另一个不相关的位置。

哦,新的Windows分区是否可以让我运行它而无需任何先前的克隆后调整?关于此的任何其他信息将不胜感激。

(我这样做是因为我需要用XCode抓爪子,而且​​MacBook Pro快要死了)。


好吧,您只需要cfdiskdd。唯一值得怀疑的是引导扇区。哪个版本的Windows?
XXL

Windows7。我确实记得安装它是一件痛苦的事,因为存在一些与分区相关的问题。
故障

您有W7光盘可供使用吗?
XXL

不能完全确定我将其放置在哪里,但是如果需要的话,我可以对其进行挖掘。
故障

Answers:


7

您将需要用dd克隆2个分区-一个分区是bootloader / bootmanager驻留的位置(为了链式加载OS所需)[ System Reserved,通常为100M],另一个分区是实际的W7安装。

使用cfdisk检查分区表-它会为您提供直观的表示形式。然后删除目标驱动器上的所有分区-cfdisk是您的朋友。

克隆的语法可以在wiki上找到这里。您还需要一个合适的MBR(它可能已经在您的测试驱动器上存在了)。

您可能还需要将可引导标志分配给[System Reserved]分区(应该是第一个克隆的分区)-cfdisk可以完成此操作。

如果失败,则只需从W7安装光盘启动,然后按照此处的Vista 指南进行操作即可。

更新

忘了提到整个过程中可能并不那么明显的一个重要部分。你或者可以克隆分区表关原驱动器,并删除一切,但2与Windows相关的分区或重建与他们CFDISK / 分手相同大小。

以下是一些示例(假设sda是您的源驱动器,而sdb是目标驱动器):

dd if = / dev / sda bs = 1 skip = 446 count = 66 of = / dev / sdb seek = 446(这会将您当前的DOS分区表以及MBR签名有效地克隆到输出驱动器)

dd if = / dev / sda bs = 1 skip = 440 count = 72 of = / dev / sdb seek = 440(这也会复制磁盘ID,如果丢失,有时会导致引导失败-但是,此类磁盘不会能够在Windows环境中一起工作,直到ID更改)

parted / dev / sda usp(这是检查源驱动器上当前分区表和扇区大小的方法,以便以后使用cfdiskparted自身在目标上进行复制)


这很痛苦,通常不会启动
sehe11,2011年

为什么?如果引导过程存在问题-从W7安装光盘实例化命令提示符会话并执行bootrec / fixmbr,则bootrec / fixbootbootrec / rebuildbcd应该能够解决该问题。
XXL

很公平。过去我对我失败。我敢肯定,这就是为什么我发现了有关utils来防止不幸的原因。另外,使用dd复制分区至少不是很有效
2011年

因为它使用逐个扇区的副本,并且会复制分配的文件系统中的空白空间?我认为,在OP中,这可能完全不相关。我们甚至不知道该分区是否已满,更不用说他需要等待几分钟(时间收益可能很小),而不是尝试一个不太明确的替代解决方案
-XXL,

但是它具有能够复制到不同大小的分区的独特优势。DD假定目标大小完全相同(尽管可能更大)。这可能是一个阻碍问题,尤其是在涉及SSD时(它们容量不是“无限”的
2011年

4

看一下

  • ntfsclone(仅复制正在使用的扇区)
  • fixntfs.c修复启动信息偏移

IIRC Trinity Rescue Kit包含必要的软件以及许多其他软件(ssh,partimage,fdisk,fdisk,cfdi​​sk,parted,gparted,testdisk,ntfsfix; ntfs-3g安装,rsync等)。

/*
 * fixntfs: change some attributes of an NTFS bootsector
 *
 * brought to you by Phoenix
 * url: www.grhack.gr/phoenix
 * mail: phoenix@grhack.gr
 * irc: phoenix -> #grhack -> undernet
 */

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
    FILE *fd;
    FILE *idfd;
    struct stat fst;
    unsigned char cab[32];
    unsigned short log_heads;
    unsigned short ntfs_heads;
    unsigned short force_heads;
    unsigned short ntfs_cab;
    unsigned long long sectors;
    unsigned long long new_sectors;

    log_heads = 0;
    ntfs_heads = 0;
    force_heads = 0;
    ntfs_cab = 0;

    if(argc < 2)
    {
        fprintf(stderr, "Usage:\n\t%s <device> <total_sectors> <force_heads>\n", argv[0]);
        exit(0);
    }

    fprintf(stderr, "Stating file %s... ", argv[1]);

    stat(argv[1], &fst);

    if(!S_ISBLK(fst.st_mode))
    {
        fprintf(stderr, "not a block device\n");
        exit(-1);
    }

    fprintf(stderr, "a block device\n");


    fprintf(stderr, "Opening device %s rw... ", argv[1]);

    fd = fopen(argv[1], "r+");

    if(!fd)
    {
        perror("open device");
        exit(-1);
    }

    fprintf(stderr, "ok\n");


    fprintf(stderr, "Checking partition... ");

    fseek(fd, 3, SEEK_SET);

    if(fread(cab, 1, 4, fd) != 4)
    {
        perror("read system_id");
        exit(-1);
    }

    cab[5] = 0;

    if(strncmp(cab, "NTFS", 4))
    {
        fprintf(stderr, "%s\n", cab);
        exit(-1);
    }

    fprintf(stderr, "%s\n", cab);


    fprintf(stderr, "Reading NTFS bootsector heads... ");

    fseek(fd, 0x1a, SEEK_SET);

    ntfs_heads = 0;

    fread(&ntfs_heads, 1, 2, fd);

    fprintf(stderr, "%u\n", ntfs_heads);


    fprintf(stderr, "Reading NTFS bootsector sectors... ");

    fseek(fd, 0x18, SEEK_SET);

    ntfs_cab = 0;

    fread(&ntfs_cab, 1, 2, fd);

    fprintf(stderr, "%u\n", ntfs_cab);


    fprintf(stderr, "Reading NTFS bootsector sectors_per_cluster... ");

    fseek(fd, 0x0d, SEEK_SET);

    ntfs_cab = 0;

    fread(&ntfs_cab, 1, 1, fd);

    fprintf(stderr, "%u\n", ntfs_cab);


    fprintf(stderr, "Reading NTFS bootsector sectors_size... ");

    fseek(fd, 0x0b, SEEK_SET);

    ntfs_cab = 0;

    fread(&ntfs_cab, 1, 2, fd);

    fprintf(stderr, "%u\n", ntfs_cab);


    fprintf(stderr, "Reading NTFS bootsector boot_loader_routine_jump... ");

    fseek(fd, 0, SEEK_SET);

    bzero(cab, sizeof(cab));

    fread(cab, 1, 3, fd);

    fprintf(stderr, "0x%x 0x%x 0x%x\n", cab[0], cab[1], cab[2]);

    fprintf(stderr, "Reading NTFS bootsector total_sectors... ");

    fseek(fd, 0x28, SEEK_SET);

    sectors = 0;

    fread(&sectors, 1, 8, fd);

    fprintf(stderr, "%Lu\n", sectors);


    fprintf(stderr, "Reading device logical heads... ");

    sprintf(cab, "/proc/ide/hd%c/geometry", *(strrchr(argv[1],'/') + 3));

    idfd = fopen(cab, "r");

    if(!idfd)
    {
        perror(cab);
        exit(-1);
    }

    fscanf(idfd, "%*s %*s\n");

    fscanf(idfd, "%*s %s\n", cab);

    *(strrchr(cab, '/')) = 0;

    log_heads = (unsigned short) atoi(strchr(cab, '/') + 1);

    fprintf(stderr, "%u\n", log_heads);

    if(argc == 4)
    {
        force_heads=atoi(argv[3]);
        fprintf(stderr, "Forcing heads to %u\n", force_heads);
        log_heads=force_heads;
    }

    if(fclose(fd) == EOF)
    {
        perror("close device");
        exit(-1);
    }

    if(log_heads != ntfs_heads)
    {
        fprintf(stderr, "Heads are different... Logical=%u NTFS=%u\n\n"
                "Update NTFS bootsector? (y/n) ",
                log_heads, ntfs_heads);

        if(getc(stdin) == 'y')
        {
            fd = fopen(argv[1], "r+");

            if(!fd)
            {
                perror("open device");
                exit(-1);
            }

            ntfs_heads = log_heads;

            fseek(fd, 0x1a, SEEK_SET);

            fwrite(&ntfs_heads, 1, 2, fd);


            fprintf(stderr, "\nBootsector updated... Verifying... ");

            fclose(fd);

            fd = fopen(argv[1], "r");

            if(!fd)
            {
                perror("open device");
                exit(-1);
            }

            fseek(fd, 0x1a, SEEK_SET);

            ntfs_heads = 0;

            fread(&ntfs_heads, 1, 2, fd);

            if(ntfs_heads == log_heads)
            {
                fprintf(stderr, "ok\n\n");
            }
            else
            {
                fprintf(stderr, "error [%u]\n", ntfs_heads);
                exit(-1);
            }
            fclose(fd);
        }
        else
        {
            fprintf(stderr, "\nHeads update cancelled...\n");
        }

        getc(stdin);
    }

    if(argc >= 3 && atoll(argv[2]))
    {
        fprintf(stderr, "Update NTFS bootsector total_sectors from %Lu to %Lu? (y/n) ",
                sectors, atoll(argv[2]));

        if(getc(stdin) == 'y')
        {
            fd = fopen(argv[1], "r+");

            if(!fd)
            {
                perror("open device");
                exit(-1);
            }

            new_sectors = atoll(argv[2]);

            fseek(fd, 0x28, SEEK_SET);

            fwrite(&new_sectors, 1, 8, fd);


            fprintf(stderr, "\nBootsector updated... Verifying... ");

            fclose(fd);

            fd = fopen(argv[1], "r");

            if(!fd)
            {
                perror("open device");
                exit(-1);
            }

            fseek(fd, 0x28, SEEK_SET);

            sectors = 0;

            fread(&sectors, 1, 8, fd);

            if(sectors == new_sectors)
            {
                fprintf(stderr, "ok\n\n");
            }
            else
            {
                fprintf(stderr, "error [%Lu]\n", sectors);
                exit(-1);
            }

            fclose(fd);
        }
        else
        {
            fprintf(stderr, "\nTotal_sectors update cancelled...\n");
        }
        getc(stdin);
    }

    return(1);
}

2

这个克隆Windows驱动器的方法对我非常有用。由于这是我第一次能够将Windows安装转移到新的硬盘驱动器,因此我将在这里分享我的程序,以帮助下一位Googler访问。

我的情况是:
Manager的Windows 7 x64已使其128G SSD最大化,因此我购买了240 GB的替代品。

问题:
我有两个SATA驱动器扩展坞,但是linux不能同时识别这两个扩展坞,从而阻止了它们之间的轻松复制。

硬件:
我将设置双网卡防火墙,因此我在这台计算机上安装了源SSD。目标240G SSD进入外部扩展坞。

处理:
1)我拿起的第一个USB随身碟上有Linux Mint live CD,它变成/dev/sda1
2)检测到并变成了“旧” 128G SSD,/dev/sdb1并且/dev/sdb2
3)# fdisk -l /dev/sdb从教程中使用并将源分区窗口的信息复制到Gedit。
-请注意,本教程包含该-u选项,但是对我而言,fdisk已经在显示块(所需的输出),因此包括该开关将提供错误的信息。
4)插入并打开带有目标240G SSD的驱动器扩展坞,该驱动器变为/dev/sdc
5)用于fdisk /dev/sdc/dev/sdc完全匹配的分区上创建分区/dev/sdb,包括启动和系统标志。
6)dd if=/dev/sdb of=/dev/sda bs=446 count=1将MBR复制到目标驱动器。
-该指南现在建议使用hdparm打开DMA,但命令对我来说失败
7)ntfsclone -O /dev/sdc1 /dev/sdb1复制Windows隐藏的系统分区。
- -O--overwrite选项用于设置目标,使命令向后显示。拥有ntfsclone的Linux Mint live CD的荣誉,因为我之前从未听说过此命令,也不必进入网络。
8)ntfsclone -O /dev/sdc2 /dev/sdb2用于复制Windows“ C驱动器”。这花了一些啤酒来完成。
9)为了调整分区的大小,我使用了gparted
10)在Windows计算机中重新安装了新的SSD并运行了checkdisk(我离开了教程并且没有注意到他这样做了)。
11)重新启动Windows,一切恢复正常,但有更多可用空间。


1
  1. 我在Ubuntu应用程序菜单中搜索“ Disks ”,然后打开了Disks Utility应用程序。
  2. 我选择了要复制的分区。然后单击 设置图标,然后选择“ 创建磁盘映像 ”。
  3. 它会采取一段时间来产生恢复映像
  4. 完成生成恢复映像后,我单击了要克隆以前的分区的分区。
  5. 然后再次单击设置图标,然后选择“ Restore Disk Image ”并选择先前生成的磁盘映像文件。
  6. 然后等待它完成。

我刚刚浏览了Disks Utility应用程序,仅此而已。 我没有安装任何东西。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.