Hello everyone.
As a complete beginner with ZimaOS, which I’m still getting to know, I was looking to replace an Xpenology setup running on an HP ProLiant Gen8 that I’ve had for five years.
After running into a few hurdles, I wanted to write down the steps I followed, particularly to work around the fact that the Gen8 lacks UEFI support. Hopefully, this might be useful to someone—or even to me later on
.
SSD in the ODD bay + USB GRUB bootloader
The HP MicroServer Gen8 only supports Legacy BIOS, while ZimaOS expects UEFI. The clean workaround is to keep ZimaOS on the SSD and use a small internal USB stick with GRUB BIOS to boot it.
This method also preserves ZimaOS A/B updates correctly.
1. Final setup
- Final Setup
The four front drive bays remain available for storage.
2. What you need
-
HP MicroServer Gen8
-
SATA SSD connected to the ODD SATA port
-
2 USB sticks
-
SystemRescue
-
ZimaOS installer image
-
Rufus or Balena Etcher
Temporarily remove the HDDs from bays 1–4 during installation.
3. Configure the Gen8 BIOS
Press F9 during boot.
Enable AHCI:
System Options
→ SATA Controller Options
→ Embedded SATA Configuration
→ Enable SATA AHCI Support
Set USB DriveKey before Hard Drive in the boot order.
The final GRUB USB stick should preferably use the internal USB port.
4. Create a SystemRescue USB
Write SystemRescue to the first USB stick using Rufus or BalenaEtcher.
Use:
Partition scheme: MBR
Target: BIOS
Filesystem: FAT32
Boot the Gen8 from it.
5. Identify the second USB stick
Connect the USB stick that will permanently contain GRUB.
Run:
lsblk -o NAME,SIZE,MODEL,TRAN,LABEL,MOUNTPOINTS
Example:
sde 476.9G P3-512 sata
sdf 14.5G Ultra usb RESCUE1302
sdg 14.6G UDisk usb
Here:
/dev/sde = ZimaOS SSD
/dev/sdf = SystemRescue
/dev/sdg = GRUB USB
Check carefully. The device names may be different on your server.
The commands below assume the GRUB stick is /dev/sdg.
6. Prepare the GRUB USB
Erase it:
umount /dev/sdg1 2>/dev/null
umount /dev/sdg2 2>/dev/null
wipefs -a /dev/sdg
parted -s /dev/sdg mklabel msdos
parted -s /dev/sdg mkpart primary fat32 1MiB 100%
parted -s /dev/sdg set 1 boot on
partprobe /dev/sdg
mkfs.fat -F32 -n GEN8BOOT /dev/sdg1
Mount it:
mkdir -p /mnt/gen8boot
mount /dev/sdg1 /mnt/gen8boot
Install BIOS GRUB:
grub-install \
--target=i386-pc \
--boot-directory=/mnt/gen8boot/boot \
--recheck \
/dev/sdg
You should get:
Installing for i386-pc platform.
Installation finished. No error reported.
7. Temporary GRUB configuration for installing ZimaOS
Create:
cat > /mnt/gen8boot/boot/grub/grub.cfg <<'EOF'
set timeout=5
set default=0
insmod part_gpt
insmod part_msdos
insmod fat
insmod ext2
insmod search
insmod search_fs_file
insmod configfile
insmod linux
menuentry "Install / Boot ZimaOS" {
echo "Searching for ZimaOS..."
search --no-floppy --file --set=zima /EFI/BOOT/grub.cfg
if [ -z "$zima" ]; then
echo "ERROR: /EFI/BOOT/grub.cfg not found"
read
else
set root=$zima
configfile ($zima)/EFI/BOOT/grub.cfg
fi
}
EOF
Finish:
sync
umount /mnt/gen8boot
poweroff
8. Create the ZimaOS installer USB
Reuse the SystemRescue stick.
Flash the ZimaOS .img file using Balena Etcher.
Then connect:
Internal USB → GRUB stick
External USB → ZimaOS installer
ODD SATA → ZimaOS SSD
Boot the Gen8.
GRUB should display:
Install / Boot ZimaOS
Select it and install ZimaOS onto the SSD in the ODD bay.
9. First boot
After installation, remove only the ZimaOS installer USB.
Leave the GRUB USB connected.
The temporary configuration should now find:
/EFI/BOOT/grub.cfg
on the SSD and start ZimaOS.
At this point ZimaOS works, but one more step is required for OTA updates.
10. Make GRUB compatible with ZimaOS A/B updates
ZimaOS uses two system slots:
A → Kernel A + RootFS A
B → Kernel B + RootFS B
RAUC switches between them using:
/EFI/BOOT/grubenv
For example:
ORDER=B A
A_OK=1
B_OK=1
Our USB GRUB therefore needs to read and write the grubenv on the ZimaOS SSD, not one on the USB stick.
From ZimaOS:
sudo mkdir -p /mnt/gen8boot
sudo mount /dev/disk/by-label/GEN8BOOT /mnt/gen8boot
Replace the USB grub.cfg:
sudo tee /mnt/gen8boot/boot/grub/grub.cfg >/dev/null <<'EOF'
set timeout=3
set default=99
insmod part_gpt
insmod fat
insmod search
insmod search_fs_file
insmod loadenv
insmod regexp
insmod probe
insmod linux
search --no-floppy --file --set=zboot /EFI/BOOT/grubenv
if [ -z "$zboot" ]; then
echo "ERROR: ZimaOS boot partition not found."
read
fi
set ORDER="A B"
set A_OK=0
set B_OK=0
set A_TRY=0
set B_TRY=0
set MACHINE_ID=""
load_env --file=($zboot)/EFI/BOOT/grubenv \
ORDER A_OK B_OK A_TRY B_TRY MACHINE_ID
for SLOT in $ORDER; do
if [ "$SLOT" == "A" ]; then
INDEX=0
OK=$A_OK
TRY=$A_TRY
fi
if [ "$SLOT" == "B" ]; then
INDEX=1
OK=$B_OK
TRY=$B_TRY
fi
if [ "$OK" -eq 1 -a "$TRY" -lt 3 ]; then
default=$INDEX
if [ "$TRY" -eq 1 ]; then
TRY=2
elif [ "$TRY" -eq 2 ]; then
TRY=3
else
TRY=1
fi
if [ "$SLOT" == "A" ]; then
A_TRY=$TRY
fi
if [ "$SLOT" == "B" ]; then
B_TRY=$TRY
fi
break
fi
done
if [ "$default" -eq 99 ]; then
if [ "$A_OK" -eq 1 ]; then
default=2
fi
if [ "$B_OK" -eq 1 ]; then
default=3
fi
fi
if [ "$MACHINE_ID" == "" ]; then
boot_condition="systemd.condition-first-boot=true"
fi
save_env --file=($zboot)/EFI/BOOT/grubenv \
A_TRY A_OK B_TRY B_OK ORDER MACHINE_ID
default_cmdline="rootwait net.naming-scheme=v250 systemd.machine_id=$MACHINE_ID fsck.repair=yes $boot_condition"
regexp --set 1:boothd (.+),.+ ${zboot}
probe --set=rootA_uuid --part-uuid (${boothd},gpt3)
probe --set=rootB_uuid --part-uuid (${boothd},gpt5)
menuentry "ZimaOS Slot A (OK=$A_OK TRY=$A_TRY)" {
linux (${boothd},gpt2)/bzImage root=PARTUUID=$rootA_uuid $default_cmdline rauc.slot=A
}
menuentry "ZimaOS Slot B (OK=$B_OK TRY=$B_TRY)" {
linux (${boothd},gpt4)/bzImage root=PARTUUID=$rootB_uuid $default_cmdline rauc.slot=B
}
menuentry "ZimaOS Slot A - Rescue" {
linux (${boothd},gpt2)/bzImage root=PARTUUID=$rootA_uuid $default_cmdline rauc.slot=A systemd.unit=recovery.target
}
menuentry "ZimaOS Slot B - Rescue" {
linux (${boothd},gpt4)/bzImage root=PARTUUID=$rootB_uuid $default_cmdline rauc.slot=B systemd.unit=recovery.target
}
EOF
Then:
sync
sudo umount /mnt/gen8boot
sudo reboot
11. Verify A/B booting
After reboot:
sudo rauc status
You want:
Booted from: kernel.1 (B)
Activated: kernel.1 (B)
or the equivalent for A.
Check GRUB’s environment:
sudo grub-editenv /mnt/boot/EFI/BOOT/grubenv list
A healthy example:
ORDER=B A
A_OK=1
A_TRY=0
B_OK=1
B_TRY=0
MACHINE_ID=...
This means ZimaOS booted correctly from B and future updates can switch back to A.
12. Reinstall the storage drives
Shut down:
sudo poweroff
Reinstall the four HDDs.
The final boot path is:
Gen8 Legacy BIOS
↓
Internal USB GRUB
↓
Read ZimaOS grubenv
↓
Select Slot A or B
↓
Kernel on ODD SSD
↓
ZimaOS
Important
Do not permanently use only:
configfile /EFI/BOOT/grub.cfg
It can boot ZimaOS, but A/B updates may continue booting the old slot.
Also avoid changing GRUB’s $prefix to the SSD. GRUB still needs $prefix to access its BIOS modules stored on the USB stick.
Once everything works, make a backup image of the GRUB USB stick. It is the only custom component required to make ZimaOS work properly on the BIOS-only MicroServer Gen8.
I initially installed version 1.7, and the update to 1.7.1 went smoothly, without any issues.
I know it’s a bit long, but it’s worth the effort. I hope this proves useful to some people; I know the Gen8 is still widely used in DIY NAS builds, and it would be a shame for hardware that’s still running to end up in the trash ![]()
