1
1
openwrt/target/linux/x86/image/Makefile
Keno Fischer c7e8cffcb2
x86: add onie-installer image type
The current documentation for using OpenWRT on Mellanox Spectrum
switches (https://openwrt.org/toh/mellanox/spectrum) suggests
reflashing the entire harddrive from the recovery USB. This is not
the most friendly way to install a new OS on these switches. From
factory, they come with ONIE (Open Network Install Environment),
which is a linux-based preboot environment for fetching an OS
image from the network and installing it on disk. The installer
is a self-executing bash script that executes inside the ONIE
environment. The installer is expected to preserve the ONIE partition
for use as recovery environement. To be a better citizen on
these platforms, it would be preferrable to provide OpenWRT as
an ONIE-compatible installer.

This PR adds an ONIE_INSTALLER_IMAGES build option that produces
an ONIE compatible .bin. The generated .bin follows the ONIE demo
installer pattern [1]: it creates a new GPT partition
labelled OPENWRT-ROOT on the ONIE install device, formats ext4, extracts
the OpenWrt rootfs and kernel into it, installs GRUB into the existing
UEFI ESP under bootloader-id "OpenWrt", and adds a NVRAM boot entry via
efibootmgr.  ONIE-BOOT is preserved so ONIE rescue remains available.

Tested with the config at [2] on a Mellanox Spectrum SN3800 to produce
a booting OpenWRT install.

[1] https://github.com/opencomputeproject/onie/demo/installer/grub-arch/install.sh
[2] https://gist.github.com/Keno/abc8c5b72645e73fadd1ff0d9616b23d

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Signed-off-by: Keno Fischer <keno@juliahub.com>
Link: https://github.com/openwrt/openwrt/pull/23062
Signed-off-by: Jonas Jelonek <jelonek.jonas@gmail.com>
2026-05-23 17:23:53 +02:00

179 lines
7.0 KiB
Makefile

# SPDX-License-Identifier: GPL-2.0-only
#
# Copyright (C) 2006-2020 OpenWrt.org
include $(TOPDIR)/rules.mk
include $(INCLUDE_DIR)/image.mk
GRUB2_VARIANT =
GRUB_TERMINALS =
GRUB_SERIAL_CONFIG =
GRUB_TERMINAL_CONFIG =
GRUB_CONSOLE_CMDLINE =
ifneq ($(CONFIG_GRUB_CONSOLE),)
GRUB_CONSOLE_CMDLINE += console=tty1
GRUB_TERMINALS += console
endif
GRUB_SERIAL:=$(call qstrip,$(CONFIG_TARGET_SERIAL))
GRUB_CONSOLE_CMDLINE += console=$(GRUB_SERIAL),$(CONFIG_GRUB_BAUDRATE)n8$(if $(CONFIG_GRUB_FLOWCONTROL),r,)
GRUB_SERIAL_CONFIG := serial --unit=0 --speed=$(CONFIG_GRUB_BAUDRATE) --word=8 --parity=no --stop=1 --rtscts=$(if $(CONFIG_GRUB_FLOWCONTROL),on,off)
GRUB_TERMINALS += serial
GRUB_TERMINAL_CONFIG := terminal_input $(GRUB_TERMINALS); terminal_output $(GRUB_TERMINALS)
ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
ROOTPART:=$(if $(ROOTPART),$(ROOTPART),PARTUUID=$(IMG_PART_SIGNATURE)-02)
GPT_ROOTPART:=$(call qstrip,$(CONFIG_TARGET_ROOTFS_PARTNAME))
GPT_ROOTPART:=$(if $(GPT_ROOTPART),$(GPT_ROOTPART),PARTUUID=$(shell echo $(IMG_PART_DISKGUID) | sed 's/00$$/02/'))
GRUB_TIMEOUT:=$(call qstrip,$(CONFIG_GRUB_TIMEOUT))
GRUB_TITLE:=$(call qstrip,$(CONFIG_GRUB_TITLE))
BOOTOPTS:=$(call qstrip,$(CONFIG_GRUB_BOOTOPTS))
define Build/combined
$(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz
-$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/
$(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img $@.boot/boot/grub/
$(CP) $(STAGING_DIR_IMAGE)/grub2/$(if $(filter $(1),efi),gpt,$(GRUB2_VARIANT))-core.img \
$@.boot/boot/grub/core.img
$(if $(filter $(1),efi),
$(INSTALL_DIR) $@.boot/efi/boot
$(CP) $(STAGING_DIR_IMAGE)/grub2/boot$(if $(CONFIG_x86_64),x64,ia32).efi $@.boot/efi/boot/
)
PADDING="1" SIGNATURE="$(IMG_PART_SIGNATURE)" \
$(if $(filter $(1),efi),GUID="$(IMG_PART_DISKGUID)") $(SCRIPT_DIR)/gen_image_generic.sh \
$@ \
$(CONFIG_TARGET_KERNEL_PARTSIZE) $@.boot \
$(CONFIG_TARGET_ROOTFS_PARTSIZE) $(IMAGE_ROOTFS) \
256
endef
define Build/grub-config
rm -fR $@.boot
$(INSTALL_DIR) $@.boot/boot/grub
sed \
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
-e 's#@ROOTPART@#root=$(ROOTPART) rootwait#g' \
-e 's#@GPT_ROOTPART@#root=$(GPT_ROOTPART) rootwait#g' \
-e 's#@CMDLINE@#$(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE)#g' \
-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
./grub-$(1).cfg > $@.boot/boot/grub/grub.cfg
endef
define Build/grub-install
rm -fR $@.grub2
$(INSTALL_DIR) $@.grub2
$(CP) $(STAGING_DIR_IMAGE)/grub2/boot.img $@.grub2/
$(CP) $(STAGING_DIR_IMAGE)/grub2/$(if $(filter $(1),efi),gpt,$(GRUB2_VARIANT))-core.img $@.grub2/core.img
echo '(hd0) $@' > $@.grub2/device.map
$(STAGING_DIR_HOST)/bin/grub-bios-setup \
-m "$@.grub2/device.map" \
-d "$@.grub2" \
-r "hd0,$(if $(filter $(1),efi),gpt1,msdos1)" \
$@
endef
define Build/onie-installer
rm -rf $@.onie
mkdir -p $@.onie/payload
$(TAR) --numeric-owner --owner=0 --group=0 --sort=name \
$(if $(SOURCE_DATE_EPOCH),--mtime=@$(SOURCE_DATE_EPOCH)) \
-C $(TARGET_DIR)/ -cf - . | gzip -9n > $@.onie/payload/rootfs.tar.gz
$(CP) $(KDIR)/$(KERNEL_NAME) $@.onie/payload/vmlinuz
$(TAR) --numeric-owner --owner=0 --group=0 --sort=name \
$(if $(SOURCE_DATE_EPOCH),--mtime=@$(SOURCE_DATE_EPOCH)) \
-C $@.onie/payload -cf $@.onie/payload.tar .
sed \
-e 's#@SERIAL_CONFIG@#$(strip $(GRUB_SERIAL_CONFIG))#g' \
-e 's#@TERMINAL_CONFIG@#$(strip $(GRUB_TERMINAL_CONFIG))#g' \
-e 's#@CMDLINE@#$(strip $(BOOTOPTS) $(GRUB_CONSOLE_CMDLINE))#g' \
-e 's#@TITLE@#$(GRUB_TITLE)#g' \
-e 's#@TIMEOUT@#$(GRUB_TIMEOUT)#g' \
./onie-install.sh.in > $@.onie/installer.sh
script_len=$$(wc -c < $@.onie/installer.sh | tr -d ' '); \
sed -i "s/__PYLOAD__/$$(printf '%010d' $$script_len)/" $@.onie/installer.sh
cat $@.onie/installer.sh $@.onie/payload.tar > $@
chmod +x $@
endef
define Build/iso
$(CP) $(KDIR)/$(KERNEL_NAME) $@.boot/boot/vmlinuz
cat \
$(STAGING_DIR_IMAGE)/grub2/cdboot.img \
$(STAGING_DIR_IMAGE)/grub2/eltorito.img \
> $@.boot/boot/grub/eltorito.img
-$(CP) $(STAGING_DIR_ROOT)/boot/. $@.boot/boot/
$(if $(filter $(1),efi),
mkfs.fat -C $@.boot/boot/grub/isoboot.img -S 512 1440
mmd -i $@.boot/boot/grub/isoboot.img ::/efi ::/efi/boot
mcopy -i $@.boot/boot/grub/isoboot.img \
$(STAGING_DIR_IMAGE)/grub2/iso-boot$(if $(CONFIG_x86_64),x64,ia32).efi \
::/efi/boot/boot$(if $(CONFIG_x86_64),x64,ia32).efi
)
mkisofs -R -b boot/grub/eltorito.img -no-emul-boot -boot-info-table \
$(if $(filter $(1),efi),-boot-load-size 4 -c boot.cat -eltorito-alt-boot -b boot/grub/isoboot.img -no-emul-boot) \
-o $@ $@.boot $(TARGET_DIR)
endef
DEVICE_VARS += GRUB2_VARIANT
define Device/Default
ARTIFACT/image.iso := grub-config iso | iso
IMAGE/combined.img := grub-config pc | combined | grub-install | append-metadata
IMAGE/combined.img.gz := grub-config pc | combined | grub-install | gzip | append-metadata
IMAGE/combined.vdi := grub-config pc | combined | grub-install | qemu-image vdi
IMAGE/combined.vmdk := grub-config pc | combined | grub-install | qemu-image vmdk
IMAGE/combined.vhdx := grub-config pc | combined | grub-install | qemu-image vhdx -o subformat=dynamic
IMAGE/rootfs.img := append-rootfs | pad-to $(ROOTFS_PARTSIZE)
IMAGE/rootfs.img.gz := append-rootfs | pad-to $(ROOTFS_PARTSIZE) | gzip
ARTIFACT/image-efi.iso := grub-config iso | iso efi
IMAGE/combined-efi.img := grub-config efi | combined efi | grub-install efi | append-metadata
IMAGE/combined-efi.img.gz := grub-config efi | combined efi | grub-install efi | gzip | append-metadata
IMAGE/combined-efi.vdi := grub-config efi | combined efi | grub-install efi | qemu-image vdi
IMAGE/combined-efi.vmdk := grub-config efi | combined efi | grub-install efi | qemu-image vmdk
IMAGE/combined-efi.vhdx := grub-config efi | combined efi | grub-install efi | qemu-image vhdx -o subformat=dynamic
ARTIFACT/onie-installer.bin := onie-installer
ifeq ($(CONFIG_TARGET_IMAGES_GZIP),y)
IMAGES-y := rootfs.img.gz
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img.gz
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img.gz
else
IMAGES-y := rootfs.img
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.img
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.img
endif
KERNEL := kernel-bin
KERNEL_INSTALL := 1
KERNEL_NAME := bzImage
ifeq ($(CONFIG_ISO_IMAGES),y)
ARTIFACTS-$$(CONFIG_GRUB_IMAGES) += image.iso
ARTIFACTS-$$(CONFIG_GRUB_EFI_IMAGES) += image-efi.iso
endif
ARTIFACTS-$$(CONFIG_ONIE_INSTALLER_IMAGES) += onie-installer.bin
ifeq ($(CONFIG_VDI_IMAGES),y)
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vdi
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vdi
endif
ifeq ($(CONFIG_VMDK_IMAGES),y)
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vmdk
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vmdk
endif
ifeq ($(CONFIG_VHDX_IMAGES),y)
IMAGES-$$(CONFIG_GRUB_IMAGES) += combined.vhdx
IMAGES-$$(CONFIG_GRUB_EFI_IMAGES) += combined-efi.vhdx
endif
IMAGES := $$(IMAGES-y)
ARTIFACTS := $$(ARTIFACTS-y)
SUPPORTED_DEVICES :=
endef
include $(SUBTARGET).mk
$(eval $(call BuildImage))