Aaron Lauterer

Move GRUB and boot partition to another disk

Linux linux grub boot

This guide describes how to move GRUB and /boot to another disk in order to boot the existing system from it. It is for legacy BIOS (non UEFI) systems and Debian based Linux distributions, though the overall steps should be fairly similar.

Backstory🔗

I have an old HP Microserver Gen 8 used as backup server. Additionally, to the 4 disks in the main drive bay I have added an SSD as boot and system drive in the ODD slot. The problem with this old hardware, and its BIOS is that in order to boot from the additional SSD, the RAID controller needs to be used as the BIOS cannot detect the SSD in SATA AHCI mode.

This means that I needed to configure RAID 0's for all the drives in the machine in order to have them exposed as single drives to the OS to use them for the ZFS pool holding all the data. This is of course not the best idea as the RAID controller adds another level of complexity and abstraction and hides the disks from the OS to a certain degree (e.g. SMART data).

In order to finally switch over to SATA AHCI mode I needed another way to boot the system. Luckily, one can place an SD card or USB flash drive in the server which will be available as another disk and the BIOS can boot from it. Using the SD card only as /boot should keep writes to it to a minimum and thus a short lifetime due to wearout should be no issue.

Guide🔗

Start by booting from a live CD.

Determine disks🔗

Using lsblk you can determine which disks are present. In my example, the main OS disk is sda and the other disk (SD card) from which I want to boot is sdb.

Another way to determine which disk is which is using the output of ls -l /dev/disk/by-id. This will print certain values of each disk such as make, model and serial number and which sdX it is. In the case of the SD card in the HP Microserver it showed up as

usb-HP_iLO_Internal_SD-CARD_000002660A01-0:0 -> ../../sdb

Create partition and file system🔗

Once we determined which disk we want to use to boot from in the future, we need to partition it with parted.

Consider the size of the new boot partition. I did set it quite large here at about 5 GiB. We need to set the boot flag for the partition so older BIOS' will consider booting from it. This was definitely necessary for my Microserver.

parted /dev/sdb
(parted) mklabel msdos
(parted) mkpart primary ext4 2048s 5G
(parted) set 1 boot

Next we need to format the partition with a file system.

mkfs.ext4 /dev/sdb1

Chroot into OS🔗

After this we need to chroot into the installed OS from our live CD. First we need to mount the system disk and bind mount the dev, sys, and proc directory to it.

mount /dev/sda1 /mnt
mount --bind /sys/ /mnt/sys/
mount --bind /proc/ /mnt/proc/
mount --bind /dev/ /mnt/dev/

Now we can chroot into the installed OS by running

chroot /mnt

Changing /boot🔗

Right now /boot usually should be just a directory on the installed OS' root file system.

Let's change to the root of the installed OS.

cd /

First we rename the directory to have it on the side.

mv /boot /boot_old

Next we create an empty directory of the same name.

mkdir boot

After this we need to add an entry to the /etc/fstab file so that the new boot partition will be mounted automatically.

Edit it with your editor of choice, the line should look like this:

UUID=712371b3-b4de-49ab-aaed-2a7097630b3a /boot               ext4    errors=remount-ro 0       1

By using the UUID of the partition we can make sure that the partition will be mounted even if the sdX naming might be changing. To find out the UUID run ls -l /dev/disk/by-uuid. You will see which UUID points to your partition, in my case sdb1.

By running mount -a we can test if the entry in /etc/fstab works correctly. The command mount should now show a line like the following:

/dev/sdb1 on /boot type ext4 (rw,relatime,errors=remount-ro)

Finally, for this step, we need to copy over the contents of the old /boot directory to the new one.

cp -r /boot_old/* /boot

Install Grub🔗

To install GRUB in the MBR of the new disk run the following command:

grub-install /dev/sdb

At last, we need to run the following command:

update-grub

Final steps🔗

This should be it. Shutdown the running live CD and change the boot order in the machine's BIOS. If you do this on an HP Microserver Gen 8, you should now change from the RAID controller to the SATA AHCI setting and change the boot order to USB.

On the next boot, the machine should load GRUB and the kernel image from the new disk.

Further thoughts🔗

If you want to achieve something similar with an UEFI booting system, it should be enough to move the EFI partition to the new disk and use efibootmgr to create or update the boot entry on the motherboard.

Got any hints or questions? blog@aaronlauterer.com