From 68c91c801f5d790893f72e98d621b1e16f3d13d8 Mon Sep 17 00:00:00 2001 From: Jeremy Soller Date: Sun, 28 Aug 2022 15:24:34 -0600 Subject: [PATCH] Support booting both BIOS and UEFI from the same image --- Makefile | 6 +--- mk/config.mk | 4 +++ mk/disk.mk | 72 +++--------------------------------------- mk/disk.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++ mk/qemu.mk | 16 ++++------ 5 files changed, 103 insertions(+), 83 deletions(-) create mode 100755 mk/disk.sh diff --git a/Makefile b/Makefile index 77d152d..ea8d81a 100644 --- a/Makefile +++ b/Makefile @@ -69,16 +69,12 @@ ci-img: FORCE $(MAKE) INSTALLER_FLAGS= \ build/harddrive.bin.gz \ build/livedisk.bin.gz \ - build/livedisk.iso.gz \ - build/harddrive-efi.bin.gz \ - build/livedisk-efi.bin.gz + build/livedisk.iso.gz rm -rf build/img mkdir -p build/img cp "build/harddrive.bin.gz" "build/img/redox_$(IMG_TAG)_harddrive.bin.gz" cp "build/livedisk.bin.gz" "build/img/redox_$(IMG_TAG)_livedisk.bin.gz" cp "build/livedisk.iso.gz" "build/img/redox_$(IMG_TAG)_livedisk.iso.gz" - cp "build/harddrive-efi.bin.gz" "build/img/redox_$(IMG_TAG)_harddrive-efi.bin.gz" - cp "build/livedisk-efi.bin.gz" "build/img/redox_$(IMG_TAG)_livedisk-efi.bin.gz" cd build/img && sha256sum -b * > SHA256SUM # CI packaging target diff --git a/mk/config.mk b/mk/config.mk index dc1431b..0c30a98 100644 --- a/mk/config.mk +++ b/mk/config.mk @@ -58,9 +58,13 @@ INSTALLER=\ ## Bootloader variables ifeq ($(ARCH),x86_64) + BOOTLOADER_BIOS=build/bootloader.bin + BOOTLOADER_BIOS_LIVE=build/bootloader-live.bin BOOTLOADER_EFI_PATH=efi/boot/bootx64.efi BOOTLOADER_TARGET=x86-unknown-none else ifeq ($(ARCH),i686) + BOOTLOADER_BIOS=build/bootloader.bin + BOOTLOADER_BIOS_LIVE=build/bootloader-live.bin BOOTLOADER_EFI_PATH=efi/boot/bootia32.efi BOOTLOADER_TARGET=x86-unknown-none else ifeq ($(ARCH),aarch64) diff --git a/mk/disk.mk b/mk/disk.mk index 30e8752..141ded2 100644 --- a/mk/disk.mk +++ b/mk/disk.mk @@ -1,20 +1,8 @@ -build/harddrive.bin: build/bootloader.bin build/filesystem.bin - dd if=/dev/zero of=$@.partial bs=1M count=$$(expr $$(du -m build/filesystem.bin | cut -f1) + 2) - $(PARTED) -s -a minimal $@.partial mklabel msdos - $(PARTED) -s -a minimal $@.partial mkpart primary 2048s $$(expr $$(du -m build/filesystem.bin | cut -f1) \* 2048 + 2048)s - dd if=$< of=$@.partial bs=1 count=446 conv=notrunc - dd if=$< of=$@.partial bs=512 skip=1 seek=1 conv=notrunc - dd if=build/filesystem.bin of=$@.partial bs=1M seek=1 conv=notrunc - mv $@.partial $@ +build/harddrive.bin: build/bootloader.efi build/filesystem.bin $(BOOTLOADER_BIOS) + env PARTED=$(PARTED) ./mk/disk.sh $@ build/filesystem.bin $< $(BOOTLOADER_EFI_PATH) $(BOOTLOADER_BIOS) -build/livedisk.bin: build/bootloader-live.bin build/filesystem.bin - dd if=/dev/zero of=$@.partial bs=1M count=$$(expr $$(du -m build/filesystem.bin | cut -f1) + 2) - $(PARTED) -s -a minimal $@.partial mklabel msdos - $(PARTED) -s -a minimal $@.partial mkpart primary 2048s $$(expr $$(du -m build/filesystem.bin | cut -f1) \* 2048 + 2048)s - dd if=$< of=$@.partial bs=1 count=446 conv=notrunc - dd if=$< of=$@.partial bs=512 skip=1 seek=1 conv=notrunc - dd if=build/filesystem.bin of=$@.partial bs=1M seek=1 conv=notrunc - mv $@.partial $@ +build/livedisk.bin: build/bootloader-live.efi build/filesystem.bin $(BOOTLOADER_BIOS_LIVE) + env PARTED=$(PARTED) ./mk/disk.sh $@ build/filesystem.bin $< $(BOOTLOADER_EFI_PATH) $(BOOTLOADER_BIOS_LIVE) build/livedisk.iso: build/livedisk.bin.gz rm -rf build/iso/ @@ -25,55 +13,3 @@ build/livedisk.iso: build/livedisk.bin.gz -no-emul-boot -boot-load-size 4 -boot-info-table \ build/iso/ isohybrid $@ - -build/harddrive-efi.bin: build/bootloader.efi build/filesystem.bin - # TODO: Validate the correctness of this \ - # Populate an EFI system partition \ - dd if=/dev/zero of=$@.esp bs=1048576 count=$$(expr $$(du -m $< | cut -f1) + 1) && \ - mkfs.vfat $@.esp && \ - mmd -i $@.esp efi && \ - mmd -i $@.esp efi/boot && \ - mcopy -i $@.esp $< ::$(BOOTLOADER_EFI_PATH) && \ - # Create the disk \ - dd if=/dev/zero of=$@ bs=1048576 count=$$(expr $$(du -m $< | cut -f1) + 2 + $$(du -m build/filesystem.bin | cut -f1)) && \ - # Create partition table \ - $(PARTED) -s -a minimal $@ mklabel gpt && \ - efi_disk_size=$$(du -m $< | cut -f1) && \ - efi_disk_blkcount=$$(expr $$efi_disk_size \* $$(expr 1048576 / 512)) && \ - efi_end=$$(expr 2048 + $$efi_disk_blkcount) && \ - efi_last=$$(expr $$efi_end - 1) && \ - $(PARTED) -s -a minimal $@ mkpart EFI fat32 2048s "$${efi_last}s" && \ - fs_disk_size=$$(du -m build/filesystem.bin | cut -f1) && \ - fs_disk_blkcount=$$(expr $$fs_disk_size \* $$(expr 1048576 / 512)) && \ - $(PARTED) -s -a minimal $@ mkpart redox ext4 "$${efi_end}s" $$(expr $$efi_end + $$fs_disk_blkcount)s && \ - $(PARTED) -s -a minimal $@ set 1 boot on && \ - $(PARTED) -s -a minimal $@ set 1 esp on && \ - # Write the partitions \ - dd if=$@.esp bs=512 seek=2048 conv=notrunc count=$$efi_disk_blkcount of=$@ && \ - dd if=build/filesystem.bin seek=$$efi_end bs=512 conv=notrunc of=$@ count=$$fs_disk_blkcount - -build/livedisk-efi.bin: build/bootloader-live.efi build/filesystem.bin - # TODO: Validate the correctness of this \ - # Populate an EFI system partition \ - dd if=/dev/zero of=$@.esp bs=1048576 count=$$(expr $$(du -m $< | cut -f1) + 1) && \ - mkfs.vfat $@.esp && \ - mmd -i $@.esp efi && \ - mmd -i $@.esp efi/boot && \ - mcopy -i $@.esp $< ::$(BOOTLOADER_EFI_PATH) && \ - # Create the disk \ - dd if=/dev/zero of=$@ bs=1048576 count=$$(expr $$(du -m $< | cut -f1) + 2 + $$(du -m build/filesystem.bin | cut -f1)) && \ - # Create partition table \ - $(PARTED) -s -a minimal $@ mklabel gpt && \ - efi_disk_size=$$(du -m $< | cut -f1) && \ - efi_disk_blkcount=$$(expr $$efi_disk_size \* $$(expr 1048576 / 512)) && \ - efi_end=$$(expr 2048 + $$efi_disk_blkcount) && \ - efi_last=$$(expr $$efi_end - 1) && \ - $(PARTED) -s -a minimal $@ mkpart EFI fat32 2048s "$${efi_last}s" && \ - fs_disk_size=$$(du -m build/filesystem.bin | cut -f1) && \ - fs_disk_blkcount=$$(expr $$fs_disk_size \* $$(expr 1048576 / 512)) && \ - $(PARTED) -s -a minimal $@ mkpart redox ext4 "$${efi_end}s" $$(expr $$efi_end + $$fs_disk_blkcount)s && \ - $(PARTED) -s -a minimal $@ set 1 boot on && \ - $(PARTED) -s -a minimal $@ set 1 esp on && \ - # Write the partitions \ - dd if=$@.esp bs=512 seek=2048 conv=notrunc count=$$efi_disk_blkcount of=$@ && \ - dd if=build/filesystem.bin seek=$$efi_end bs=512 conv=notrunc of=$@ count=$$fs_disk_blkcount diff --git a/mk/disk.sh b/mk/disk.sh new file mode 100755 index 0000000..5cacb65 --- /dev/null +++ b/mk/disk.sh @@ -0,0 +1,88 @@ +#!/usr/bin/env bash + +#TODO: move to installer + +function usage { + echo "$0 [disk] [filesystem] [bootloader.efi] [bootloader.efi path] " >&2 + exit 1 +} + +if [ -z "$1" ] +then + echo "invalid disk '$1'" >&2 + usage +fi +DISK="$1" + +if [ ! -f "$2" ] +then + echo "invalid filesystem '$2'" >&2 + usage +fi +FILESYSTEM="$2" + +if [ ! -f "$3" ] +then + echo "invalid bootloader.efi '$3'" >&2 + usage +fi +BOOTLOADER_EFI="$3" + +if [ ! -n "$4" ] +then + echo "invalid bootloader.efi path '$4'" >&2 + usage +fi +BOOTLOADER_EFI_PATH="$4" + +# Optional argument +if [ -n "$5" -a ! -f "$5" ] +then + echo "invalid bootloader.bios '$5'" >&2 +fi +BOOTLOADER_BIOS="$5" + +set -ex + +# Calculate partition sizes +MiB=1048576 + +fs_disk_size="$(du -m "${FILESYSTEM}" | cut -f1)" +fs_disk_blkcount="$(expr "${fs_disk_size}" \* "$(expr "${MiB}" / 512)")" +fs_start="2048" +fs_end="$(expr "${fs_start}" + "${fs_disk_blkcount}")" +fs_last="$(expr "${fs_end}" - 1)" + +efi_disk_size="$(expr "$(du -m "${BOOTLOADER_EFI}" | cut -f1)" + 1)" +efi_disk_blkcount="$(expr "$efi_disk_size" \* "$(expr "${MiB}" / 512)")" +efi_start="${fs_end}" +efi_end="$(expr "${efi_start}" + "${efi_disk_blkcount}")" +efi_last="$(expr "${efi_end}" - 1)" + +# Populate an EFI system partition +dd if=/dev/zero of="${DISK}.esp" bs="${MiB}" count="${efi_disk_size}" +mkfs.vfat "${DISK}.esp" +mmd -i "${DISK}.esp" efi +mmd -i "${DISK}.esp" efi/boot +mcopy -i "${DISK}.esp" "${BOOTLOADER_EFI}" "::${BOOTLOADER_EFI_PATH}" + +# Create the disk +dd if=/dev/zero of="${DISK}" bs="${MiB}" count="$(expr "$(du -m "${DISK}.esp" | cut -f1)" + 2 + "$(du -m "${FILESYSTEM}" | cut -f1)")" + +# Create partition table +"${PARTED}" -s -a minimal "${DISK}" mklabel gpt +"${PARTED}" -s -a minimal "${DISK}" mkpart redox ext4 "${fs_start}s" "${fs_last}"s +"${PARTED}" -s -a minimal "${DISK}" mkpart EFI fat32 "${efi_start}"s "${efi_last}s" +"${PARTED}" -s -a minimal "${DISK}" set 2 boot on +"${PARTED}" -s -a minimal "${DISK}" set 2 esp on + +# Write the partitions +dd if="${FILESYSTEM}" of="${DISK}" bs=512 seek="${fs_start}" count="${fs_disk_blkcount}" conv=notrunc +dd if="${DISK}.esp" of="${DISK}" bs=512 seek="${efi_start}" count="${efi_disk_blkcount}" conv=notrunc + +# Write BIOS bootloader if applicable +if [ -n "${BOOTLOADER_BIOS}" ] +then + dd if="${BOOTLOADER_BIOS}" of="${DISK}" bs=1 count=446 conv=notrunc + dd if="${BOOTLOADER_BIOS}" of="${DISK}" bs=512 skip=34 seek=34 conv=notrunc +fi diff --git a/mk/qemu.mk b/mk/qemu.mk index a6eb7fb..71e43fc 100644 --- a/mk/qemu.mk +++ b/mk/qemu.mk @@ -34,18 +34,14 @@ endif ifeq ($(efi),yes) FIRMWARE=build/firmware.rom QEMUFLAGS+=-bios build/firmware.rom - ifeq ($(live),yes) - HARDDRIVE=build/livedisk-efi.bin - else - HARDDRIVE=build/harddrive-efi.bin - endif else FIRMWARE= - ifeq ($(live),yes) - HARDDRIVE=build/livedisk.bin - else - HARDDRIVE=build/harddrive.bin - endif +endif + +ifeq ($(live),yes) + HARDDRIVE=build/livedisk.bin +else + HARDDRIVE=build/harddrive.bin endif QEMU=SDL_VIDEO_X11_DGAMOUSE=0 qemu-system-$(QEMU_ARCH)