Migrating an i386 installation to AMD64 without reinstall

This is a method I came up with when I upgraded one of my machines to AMD64. The old i386 installation booted up just fine on AMD64 hardware but the system wasn't taking full advantage of the hardware so I wanted to migrate the OS to AMD64 version of FreeBSD without doing a full reinstall. This method uses cross-compilation of world and kernel and a second bootable disk for holding the upgraded installation.

  • Make a backup of your current system first!

    I was the dare-devil and didn't make a backup but for safety you should make one before proceeding further.

  • Cross-compiling world and kernel.

    Cross-compiling world and kernel needs the system sources that match your installed system at /usr/src, refer to the Handbook on how to get the sources. This is the invocation I used for launching the build on the old i386 system (in /usr/src):

    env TARGET=amd64 TARGET_ARCH=amd64 make buildworld buildkernel KERNCONF=GENERIC

    I wasn't sure if I really needed to use env(1) or if it's enough to set the variables in the arguments for make(1) but this worked at least. I specified the KERNCONF explicitly because I used a custom kernel on my old system and there is a line in my /etc/make.conf for setting that kernel configuration. The custom i386 kernel config doesn't work for building an AMD64 kernel so I went with GENERIC on the AMD64 system.

  • Copy over the current installation to the second disk.

    The second disk needs to be connected for this step and it should be empty. I used these steps roughly to first partition/newfs(8) the second disk and then dump(8)/restore(8) for transferring the installation over. I'm using ada0 for the disk with the i386 installation and ada1 for the second disk.

    gpart destroy -F ada1
    gpart create -s GPT ada1
    gpart add -t freebsd-boot -s 512k ada1
    gpart add -t freebsd-swap -s 8G -l fwswap2 ada1
    gpart add -t freebsd-ufs -l fwroot2 ada1
    gpart bootcode -b /boot/pmbr -p /boot/gptboot -i 1 ada1
    newfs -U /dev/gpt/fwroot2

    Note about the labels, the old install used names fwswap and fwroot and I wanted to be sure there's no conflict at any point. Adjust the labels match your system where appropriate. If you're not yet using labels (!!!) you have to use the raw partition names such as ada1p3 instead when creating and mounting the new filesystem(s).

    If you have more partitions than just one for the root filesystem create them as well here and remember to newfs(8) and mount(8) them as well.

    Next the copy of the system to the new disk:

    mount /dev/gpt/fwroot2 /mnt
    dump -C16 -b64 -0uanL -h0 -f - / | (cd /mnt && restore -ruf -)

    Again, if you have more than one partition repeat the procedure for the other partitions.
  • Installing the cross-compiled world and kernel.

    This will install the cross-compiled world and kernel over the copy of the system that was created in the previous step (again run in /usr/src):

    env TARGET=amd64 TARGET_ARCH=amd64 make installworld installkernel KERNCONF=GENERIC DESTDIR=/mnt

    Next you need to run mergemaster(8) to update a few configuration files that are slightly different on AMD64 compared to i386:

    mergemaster -A amd64 -D /mnt -Ui

  • Cleanup and fixing settings.

    Before you can boot with new disk that now holds the upgraded installation you have fix at least /mnt/etc/fstab that still references labels on the old disk. I changed references to fwroot to fwroot2 and references to fwswap to fwswap2. I also needed to check /mnt/boot/loader.conf for any settings that were referencing drivers that were only usable on the old i386 installation and remove them. Finally unmount the new disk (if you have multiple filesystems you have to unmount them in reverse order of mounting):

    umount /mnt

    Powerdown your system:

    shutdown -p now

    Remove the old disk and boot from the new disk. Depending on if you want to keep using the new disk as the HD in the system you don't have to do anything more. I was using a small SSD as the second disk so I had to do another system transfer back to the old disk using again dump(8)/restore(8).

  • Post-upgrade tasks.

    Wipe /usr/obj completely with rm -rf /usr/obj/*, the old contents of the directory are no longer usable when the host architecture is AMD64.

  • Installed ports/packages.

    You will very soon notice that many of the i386 packages installed on your system fail to work on the new AMD64 installation. First thing to do is to forcefully re-install ports-mgmt/pkg and then force re-installation of all packages. I'm assuming here that you are using the official packages (I wasn't and the procedure was a bit more complicated):

    /usr/sbin/pkg bootstrap -f
    pkg clean -ay
    pkg upgrade -f
 
Last edited:
Back
Top