]> git.plutz.net Git - blast/commitdiff
split up target make files starting with raspberrypi
authorPaul Hänsch <paul@plutz.net>
Sat, 11 Apr 2026 11:09:28 +0000 (13:09 +0200)
committerPaul Hänsch <paul@plutz.net>
Sat, 11 Apr 2026 11:09:28 +0000 (13:09 +0200)
Makefile
targets/raspberrypi.mk [new file with mode: 0644]

index 254c083dd011695d83438e11bd3dc63fe675d5c8..ef72cc3a685e294516088c002e13355449d321a8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,26 +5,17 @@ comma_:= ,
 space_:= ${nul_} ${nul_}
 
 .PHONY: clean .FORCE _target
-.PHONY: _qemu _bootstrap _install _copy _config 
-.PHONY: _partition_gpt _partition_raspi _sparse _partcopy _mbr
-.PHONY: _format _format_root _format_boot
-.PHONY: _bootloader_raspi _bootloader_pc _bootloader_iso
-.PHONY: _mount _mount_root _mount_boot _efi_mount
-.PHONY: _umount _umount_root _umount_boot _efi_umount
-.PHONY: _squash_modules _squash _isosquash _iso_image
+.PHONY: _bootstrap _install _copy _config 
+
+_install: _bootstrap
+_copy: _install
+_config: _copy
+_target: _config
 
 ARCH := amd64
 BOOTSTRAP := http://deb.debian.org/debian
 PACKAGES := ${PACKAGES} apt busybox-static debian-archive-keyring init systemd
 
-# Partition Table (2M) + Boot Partition (126M)+ Root Partition + Slack Space (1M) = 2048M
-BOOT_MB := 254
-ROOT_MB := 1791
-
-fstype := ext4
-
-ISOLABEL := Blast
-
 config.mk:
        cp "config.example" "$@"
 
@@ -35,7 +26,7 @@ else
 endif
 
 ifndef release
-  release := bullseye
+  release := trixie
 endif
 
 KEYRING := keys/debian-archive-${release}-automatic.gpg
@@ -47,132 +38,7 @@ ifndef SOURCES
   endef
 endif
 
-ifdef disk
-  VOLUME := ${disk}
-  PBOOT := ${disk}1
-  PROOT := ${disk}2
-  SYSROOT := hdd_mount/
-  CFGROOT := hdd_mount/
-  
-  _target: _mbr _umount _config _install _partition_gpt
-  
-  _partition_gpt:
-  _format: _partition_gpt
-  _mount: _format
-  _bootstrap: _mount
-  _install: _bootstrap _mount
-  _config: _install _mount
-  _bootloader_pc: _mount
-  _umount: _mount _config _bootloader_pc
-  _mbr: _umount _bootloader_pc
-
-else ifdef image
-  VOLUME := ${image}
-  PBOOT := part_boot.img
-  PROOT := part_root.img
-  SYSROOT := sys_root_${release}_${ARCH}/
-  CFGROOT := img_mount/
-  
-  _target: _mbr _umount _config _install
-  
-  _bootstrap:
-  _install: _bootstrap
-  _sparse:
-  _format: _sparse
-  _partition_gpt: _sparse
-  _partcopy: _partition_gpt _format
-  _img_mount: _partcopy
-  _copy: _install _img_mount
-  _config: _copy _img_mount
-  _bootloader_pc: _img_mount
-  _umount: _img_mount _config _bootloader_pc
-  _mbr: _partcopy _bootloader_pc
-
-else ifdef subvol
-  SYSROOT := sys_root_${release}_${ARCH}/
-  CFGROOT := cfg_root/
-
-  _target: _install _config ${subvol}
-  
-  _bootstrap:
-  _install: _bootstrap
-  _copy: _install
-  _config: _copy
-
-  ${subvol}: _config
-       btrfs sub snap "${CFGROOT}" "$@"
-
-else ifdef squash
-  SQUASH := ${squash}
-  SYSROOT := sys_root_${release}_${ARCH}/
-  CFGROOT := cfg_root/
-
-  PACKAGES += squashfs-tools nbd-client
-  
-  _target: _squash _install _config
-  
-  _bootstrap:
-  _install: _bootstrap
-  _copy: _install
-  _config: _copy _squash_modules
-  _squash: _config
-
-else ifdef iso
-  ISO := ${iso}
-  ISOROOT := iso_root/
-  SYSROOT := sys_root_${release}_${ARCH}/
-  CFGROOT := cfg_root/
-  BOOT_MB := 2
-  PBOOT := ${ISOROOT}/efi.img
-
-  PACKAGES += squashfs-tools
-  
-  _target: _iso_image _install _config
-  
-  _bootstrap:
-  _install: _bootstrap
-  _copy: _install
-  _config: _copy _squash_modules
-  _isosquash: _config
-  _bootloader_iso: _config
-  _iso_image: _bootloader_iso _isosquash # _efi_umount
-
-else ifdef raspi
-  ARCH := arm64
-
-  VOLUME := ${raspi}
-  PBOOT := rpi_boot.img
-  PROOT := rpi_root.img
-  SYSROOT := sys_root_${release}_${ARCH}/
-  CFGROOT := img_mount/
-  
-  define SOURCES := 
-  deb  http://deb.debian.org/debian    ${release}      main    non-free-firmware
-  deb  https://deb.debian.org/debian-security/ ${release}/updates      main
-  endef
-
-  PACKAGES += firmware-brcm80211 bluez-firmware initramfs-tools e2fsprogs raspi-firmware linux-image-arm64
-
-  _target: _umount _config
-  
-  _qemu:
-  _bootstrap: _qemu
-  _install: _bootstrap
-  _sparse:
-  _format: _sparse
-  _partition_raspi: _sparse
-  _partcopy: _partition_raspi _format
-  _img_mount: _partcopy
-  _copy: _install _img_mount
-  _config: _copy _img_mount
-  _bootloader_raspi: _img_mount
-  _umount: _copy _config _bootloader_raspi
-
-else
-  _target:
-       false
-
-endif
+include $(addsuffix .mk, $(addprefix targets/, ${target}))
 
 include modules/default.mk
 ifdef modules
@@ -197,25 +63,6 @@ cfg_root/: sys_root_${release}_${ARCH}/ _install
        btrfs sub snap "$<" "$@" || mkdir "$@"
        chmod 755 "$@"
 
-${ISOROOT}:
-       -btrfs sub del "$@" || rm -r "$@"
-       btrfs subvol create "$@" || mkdir "$@"
-       mkdir "$@/live"
-       chmod 755 "$@" "$@/live"
-
-img_mount/:
-       mkdir -p -m 755 "$@"
-       chmod 755 "$@"
-
-hdd_mount/:
-       mkdir -p -m 755 "$@"
-
-_qemu: ${SYSROOT}/usr/bin/qemu-arm64-static
-${SYSROOT}/usr/bin/qemu-arm64-static: /usr/bin/qemu-arm64-static ${SYSROOT}
-       mkdir -p -m 755 "$${SYSROOT}"/usr/bin
-       chmod 755 "$${SYSROOT}"/usr
-       cp -p "$<" "$@"
-
 _bootstrap: ${SYSROOT}/bin/sh
 ${SYSROOT}/bin/sh: | ${SYSROOT}
        debootstrap --variant=minbase --arch="$${ARCH}" \
@@ -265,216 +112,12 @@ _copy: ${SYSROOT} ${CFGROOT}
 _config: ${CFGROOT}
        -ln -sf /dev/null "$${CFGROOT}/etc/systemd/network/99-default.link"
        printf '\nsession       optional        pam_mkhomedir.so umask=0027\n' >>"$${CFGROOT}/etc/pam.d/common-session"
-       printf 'LABEL=FSROOT / ${fstype} auto,nofail,rw 0 0\nLABEL=BOOT /boot vfat auto,nofail,ro 0 0\n' \
-               >"$${CFGROOT}/etc/fstab"
        mountpoint "$${CFGROOT}/proc" || mount -o bind /proc "$${CFGROOT}/proc"
        chroot "$${CFGROOT}" update-initramfs -u
        -umount "$${CFGROOT}/proc"
 
-${SQUASH}: ${CFGROOT} .FORCE
-       -rm "$${SQUASH}"
-       mksquashfs "$${CFGROOT}" "$${SQUASH}" -comp xz
-
-_squash_modules: ${CFGROOT}
-       printf '%s\n' squashfs nbd >>"${CFGROOT}/etc/initramfs-tools/modules"
-
-_squash: ${SQUASH} _squash_modules
-
-_isosquash: ${ISOROOT}/live/live.squashfs
-${ISOROOT}/live/live.squashfs: ${CFGROOT} ${ISOROOT} .FORCE
-       -rm "$@"
-       { cd "$${CFGROOT}"; printf '%s\n' boot/*; } \
-       | mksquashfs "$${CFGROOT}" "$@" -comp xz -ef /dev/stdin
-
-${VOLUME}: .FORCE
-       ! printf '%s\n' "$${VOLUME}" |grep -q '^/dev/'  # abort if volume should be real device
-       dd count=0 of="$${VOLUME}"  # truncate
-       dd bs=1M count=0 seek=$$((3 + ${BOOT_MB} + ${ROOT_MB})) of="$${VOLUME}"
-       chmod g+w "$${VOLUME}"
-
-${PBOOT}: .FORCE
-       ! printf '%s\n' "$${PBOOT}" |grep -q '^/dev/'  # abort if volume should be real device
-       dd count=0 of="$${PBOOT}"  # truncate
-       dd bs=1M count=0 seek=${BOOT_MB} of="$${PBOOT}"
-
-${PROOT}: .FORCE
-       ! printf '%s\n' "$${PROOT}" |grep -q '^/dev/'  # abort if volume should be real device
-       dd count=0 of="$${PROOT}"  # truncate
-       dd bs=1M count=0 seek=${ROOT_MB} of="$${PROOT}"
-
-_partition_raspi: ${VOLUME}
-       printf 'label: dos\n\n: start=2MiB, size=%iMiB, type=c\n: start=%iMiB, size=%iMiB, type=83\n' \
-               ${BOOT_MB} "$$((${BOOT_MB} + 2))" ${ROOT_MB} | sfdisk "$${VOLUME}"
-
-_partition_gpt: ${VOLUME}
-       printf 'label: gpt\n\n: start=2MiB, size=%iMiB, type=1, attrs="LegacyBIOSBootable"\n: size=%iMiB, type=20\n' \
-               ${BOOT_MB} ${ROOT_MB} | sfdisk "$${VOLUME}"
-
-_sparse: ${PBOOT} ${PROOT}
-
-ifeq "${fstype}" "ext4"
-  fsflag:=-F
-else
-  fsflag:=-f
-endif
-
-_format_root: ${PROOT}
-       -umount "$${CFGROOT}/boot" "$${CFGROOT}" "${PROOT}"
-       mkfs.${fstype} ${fsflag} -L FSROOT "$${PROOT}"
-
-_format_boot: ${PBOOT}
-       -umount "$${CFGROOT}/boot" "${PBOOT}"
-       mkfs.fat -F 32 -n BOOT "$${PBOOT}"
-
-_format: _format_root _format_boot
-
-_iso_image: ${ISOROOT}
-       grub-mkrescue --compress=xz -volid "$${ISOLABEL}" -o "$${ISO}" "$${ISOROOT}"
-
-.PHONY: _syslinux_efi32 _syslinux_efi64 _syslinux_bios
-.PHONY: _grub_efi32 _grub_efi64
-
-_syslinux_efi32: ${CFGROOT}
-       mkdir -p "$${CFGROOT}/boot/EFI/BOOT"
-       cp /usr/lib/SYSLINUX.EFI/efi32/syslinux.efi "$${CFGROOT}/boot/EFI/BOOT/BOOTIA32.EFI"
-       mkdir -p "$${CFGROOT}/boot/efi32"
-       cp $(addprefix /usr/lib/syslinux/modules/efi32/, ldlinux.e32 menu.c32 libutil.c32) "$${CFGROOT}"/boot/efi32/
-       cp /usr/lib/syslinux/modules/efi32/ldlinux.e32 "$${CFGROOT}/boot/EFI/BOOT/"  # workaround
-       printf 'PATH /efi32\nINCLUDE /bootmenu.cfg\nMENU TITLE Syslinux EFI-32\n' >"$${CFGROOT}/boot/syslia32.cfg"
-
-_syslinux_efi64: ${CFGROOT}
-       mkdir -p "$${CFGROOT}/boot/EFI/BOOT"
-       cp /usr/lib/SYSLINUX.EFI/efi64/syslinux.efi "$${CFGROOT}/boot/EFI/BOOT/BOOTX64.EFI"
-       mkdir -p "$${CFGROOT}/boot/efi64"
-       cp $(addprefix /usr/lib/syslinux/modules/efi64/, ldlinux.e64 menu.c32 libutil.c32) "$${CFGROOT}"/boot/efi64/
-       cp /usr/lib/syslinux/modules/efi64/ldlinux.e64 "$${CFGROOT}/boot/EFI/BOOT/"  # workaround
-       printf 'PATH /efi64\nINCLUDE /bootmenu.cfg\nMENU TITLE Syslinux EFI-64\n' >"$${CFGROOT}/boot/syslx64.cfg"
-
-_syslinux_bios: ${CFGROOT}
-       mkdir -p "$${CFGROOT}/boot/bios"
-       cp $(addprefix /usr/lib/syslinux/modules/bios/,  menu.c32 libutil.c32) "$${CFGROOT}"/boot/bios/
-       printf 'PATH bios\nINCLUDE bootmenu.cfg\nMENU TITLE Syslinux BIOS\n' >"$${CFGROOT}/boot/syslinux.cfg"
-
-_grub_efi32: ${CFGROOT}
-       mkdir -p "$${CFGROOT}/boot/EFI/BOOT"
-       grub-mkimage -p / -O i386-efi   fat part_gpt normal linux all_video >"$${CFGROOT}/boot/EFI/BOOT/BOOTIA32.EFI"
-
-_grub_efi64: ${CFGROOT}
-       mkdir -p "$${CFGROOT}/boot/EFI/BOOT"
-       grub-mkimage -p / -O x86_64-efi fat part_gpt normal linux all_video >"$${CFGROOT}/boot/EFI/BOOT/BOOTX64.EFI"
-
-${CFGROOT}/boot/cmdline.txt: ${CFGROOT}
-       printf 'root=/dev/mmcblk0p2 rootfstype=${fstype} fsck.repair=yes rootwait net.ifnames=0' >"$@"
-
-_bootloader_raspi: ${CFGROOT} ${CFGROOT}/boot/cmdline.txt
-
-_bootloader_pc: ${CFGROOT} _grub_efi32 _grub_efi64 _syslinux_bios #_syslinux_efi32 _syslinux_efi64
-       printf 'UI menu.c32\nDEFAULT stretch\nTIMEOUT 30\n' >"$${CFGROOT}/boot/bootmenu.cfg"
-       printf 'set timeout=3\ndefault=stretch\n\n' >"$${CFGROOT}/boot/grub.cfg"
-       k="$$(printf ' %s' "$${CFGROOT}/boot/"vmlinuz-*)"; k="$${k##*/}"; \
-       i="$$(printf ' %s' "$${CFGROOT}/boot/"initrd.img-*)";  i="$${i##*/}"; \
-       printf '\nLABEL stretch\n MENU LABEL Debian Stretch\n KERNEL /%s\n INITRD /%s\n APPEND root=LABEL=FSROOT\n' \
-               "$$k" "$$i" >>"$${CFGROOT}/boot/bootmenu.cfg"; \
-       printf '\nLABEL rescue\n MENU LABEL Rescue\n KERNEL /%s\n INITRD /%s\n APPEND root=LABEL=FSROOT init=/bin/sh\n' \
-               "$$k" "$$i" >>"$${CFGROOT}/boot/bootmenu.cfg"; \
-       printf "menuentry 'Debian Stretch' --id 'stretch' {\n linux '/%s' root=LABEL=FSROOT\n initrd '/%s'\n}\n" \
-               "$$k" "$$i" >>"$${CFGROOT}/boot/grub.cfg"; \
-       printf "menuentry 'Rescue' --id 'rescue' {\n linux '/%s' root=LABEL=FSROOT init=/bin/sh\n initrd '/%s'\n}\n" \
-               "$$k" "$$i" >>"$${CFGROOT}/boot/grub.cfg"
-
-_bootloader_iso: ${CFGROOT} ${ISOROOT}
-       mkdir -p "$${ISOROOT}/boot/grub/"
-       cp -L "$${CFGROOT}/vmlinuz" "$${CFGROOT}/initrd.img" "$${ISOROOT}"
-       printf '%s\n' "insmod all_video" "set gfxmode=auto" "load_video" "insmod gfxterm" \
-               >"$${ISOROOT}/boot/grub/grub.cfg"
-       printf '%s\n' "set timeout=10" "default=${release}" \
-               "menuentry 'Debian ${release}' --id '${release}' {" \
-               "linux '/vmlinuz' boot=live modprobe.blacklist=nbd" "initrd '/initrd.img'" "}" \
-               >>"$${ISOROOT}/boot/grub/grub.cfg"
-       -[ -f "$${ISOROOT}/install/gtk/initrd.gz" -a -f "$${ISOROOT}/install/gtk/linux" ] && \
-       printf '%s\n' "menuentry 'Install Debian ${release}' --id 'install' {" \
-               "linux '/install/gtk/linux'" "initrd '/install/gtk/initrd.gz'" "}" \
-               >>"$${ISOROOT}/boot/grub/grub.cfg"
-       -[ -f "$${ISOROOT}/install/text/initrd.gz" -a -f "$${ISOROOT}/install/text/linux" ] && \
-       printf '%s\n' "menuentry 'Install Debian ${release} (text mode)' --id 'install' {" \
-               "linux '/install/text/linux'" "initrd '/install/text/initrd.gz'" "}" \
-               >>"$${ISOROOT}/boot/grub/grub.cfg"
-
-_efi_mount: ${PBOOT}
-       -umount "efi/"
-       mkdir -p -m 755 "efi/"
-       mount -t vfat -o loop "$${PBOOT}" "efi/"
-
-_efi_umount: _efi_mount
-       sync
-       umount efi/ && rmdir efi/
-
-.PHONY: _syslinux_mbr _grub_mbr
-
-_syslinux_mbr: ${VOLUME}
-       syslinux -t 2097152 -i "$${VOLUME}"
-       dd conv=notrunc if=/usr/lib/syslinux/mbr/gptmbr.bin of="$${VOLUME}"
-
-_grub_mbr: ${VOLUME}
-       # grub-mkimage -p / -O i386-pc fat part_gpt normal linux all_video |dd conv=notrunc of="$${VOLUME}"
-
-_mbr: _syslinux_mbr # _grub_mbr
-
-_partcopy: ${VOLUME} ${PROOT} ${PBOOT}
-       dd conv=notrunc,sparse bs=1M seek=2 if="$${PBOOT}" of="$${VOLUME}"
-       dd conv=notrunc,sparse bs=1M seek=$$((2 + ${BOOT_MB})) if="$${PROOT}" of="$${VOLUME}"
-
-_mount_root: ${PROOT} ${CFGROOT}
-       mountpoint "$${CFGROOT}" \
-       || mount -t ${fstype} "$${PROOT}" "$${CFGROOT}"
-       chmod 755 "$${CFGROOT}"
-
-_mount_boot: ${PBOOT}
-       mkdir -p -m 755 "$${CFGROOT}/boot"
-       mountpoint "$${CFGROOT}/boot" \
-       || mount -t vfat "$${PBOOT}" "$${CFGROOT}/boot"
-
-ifdef disk
-  _mount_boot: _mount_root
-endif
-
-_mount: _mount_root _mount_boot
-
-_img_mount: ${CFGROOT}
-       mountpoint "$${CFGROOT}" \
-       || mount -o loop,offset="$$((${BOOT_MB} + 2))"M,sizelimit=${ROOT_MB}M \
-                -t ${fstype} "$${VOLUME}" "$${CFGROOT}"
-       chmod 755 "$${CFGROOT}"
-       mkdir -p -m 755 "$${CFGROOT}/boot"
-       mountpoint "$${CFGROOT}/boot" \
-       || mount -o loop,offset=2M,sizelimit=${BOOT_MB}M \
-                -t vfat "$${VOLUME}" "$${CFGROOT}/boot"
-
-_umount_boot: ${CFGROOT} _config
-       sync
-       -umount "$${CFGROOT}/boot"
-
-_umount_root: _umount_boot _config
-       sync
-       umount "$${CFGROOT}" && rmdir "$${CFGROOT}"
-
-_umount: _umount_boot _umount_root
-
 clean:
        [ "$${SYSROOT#/}" ] && [ "$${CFGROOT#/}" ] || false  # (abort receipe)
-       -umount img_mount/boot
-       -umount img_mount
-       -rmdir img_mount
-       -umount hdd_mount/boot
-       -umount hdd_mount
-       -rmdir hdd_mount
        if [ -d "cfg_root/" ]; then btrfs sub del "cfg_root/" || rm -r "cfg_root/"; fi
        if [ -d "iso_root/" ]; then btrfs sub del "iso_root/" || rm -r "iso_root/"; fi
        if [ -d "sys_root_${release}_${ARCH}/" ]; then btrfs sub del "sys_root_${release}_${ARCH}/" || rm -r "sys_root_${release}_${ARCH}/"; fi
-       -rm part_boot.img
-       -rm part_root.img
-       -rm rpi_boot.img
-       -rm rpi_root.img
-       -[ -f "$${SQUASH}" ] && rm "$${SQUASH}"
-       -[ -f "$${VOLUME}" ] && rm "$${VOLUME}"
-       -[ -f "$${ISO}" ] && rm "$${ISO}"
diff --git a/targets/raspberrypi.mk b/targets/raspberrypi.mk
new file mode 100644 (file)
index 0000000..13cf150
--- /dev/null
@@ -0,0 +1,142 @@
+# Partition Table (2M) + Boot Partition (126M)+ Root Partition + Slack Space (1M) = 2048M
+BOOT_MB := 254
+ROOT_MB := 1791
+
+fstype := ext4
+
+ARCH := arm64
+
+VOLUME := ${raspi}
+PBOOT := rpi_boot.img
+PROOT := rpi_root.img
+SYSROOT := sys_root_${release}_${ARCH}/
+CFGROOT := img_mount/
+
+define SOURCES := 
+deb    http://deb.debian.org/debian    ${release}      main    non-free-firmware
+deb    https://deb.debian.org/debian-security/ ${release}/updates      main
+endef
+
+PACKAGES += firmware-brcm80211 bluez-firmware initramfs-tools e2fsprogs raspi-firmware linux-image-arm64
+
+.PHONY: _raspberry_clean _qemu
+.PHONY: _partition_raspi _sparse _partcopy
+.PHONY: _format _format_root _format_boot
+.PHONY: _bootloader_raspi _raspberry_fstab
+.PHONY: _mount _mount_root _mount_boot
+.PHONY: _umount _umount_root _umount_boot
+
+_qemu: ${SYSROOT}/usr/bin/qemu-arm64-static
+_sparse: ${PBOOT} ${PROOT}
+_format: _sparse
+_bootstrap: _qemu
+_partition_raspi: _sparse
+_partcopy: _partition_raspi _format
+_img_mount: _partcopy
+_copy: _img_mount
+_bootloader_raspi: _img_mount
+_raspberry_fstab: _img_mount
+_umount: _copy _config _bootloader_raspi _raspberry_fstab
+_target: _umount
+clean: _raspberry_clean
+
+img_mount/:
+       mkdir -p -m 755 "$@"
+       chmod 755 "$@"
+
+${SYSROOT}/usr/bin/qemu-arm64-static: /usr/bin/qemu-arm64-static ${SYSROOT}
+       mkdir -p -m 755 "$${SYSROOT}"/usr/bin
+       chmod 755 "$${SYSROOT}"/usr
+       cp -p "$<" "$@"
+
+${VOLUME}: .FORCE
+       ! printf '%s\n' "$${VOLUME}" |grep -q '^/dev/'  # abort if volume should be real device
+       dd count=0 of="$${VOLUME}"  # truncate
+       dd bs=1M count=0 seek=$$((3 + ${BOOT_MB} + ${ROOT_MB})) of="$${VOLUME}"
+       chmod g+w "$${VOLUME}"
+
+${PBOOT}: .FORCE
+       ! printf '%s\n' "$${PBOOT}" |grep -q '^/dev/'  # abort if volume should be real device
+       dd count=0 of="$${PBOOT}"  # truncate
+       dd bs=1M count=0 seek=${BOOT_MB} of="$${PBOOT}"
+
+${PROOT}: .FORCE
+       ! printf '%s\n' "$${PROOT}" |grep -q '^/dev/'  # abort if volume should be real device
+       dd count=0 of="$${PROOT}"  # truncate
+       dd bs=1M count=0 seek=${ROOT_MB} of="$${PROOT}"
+
+_partition_raspi: ${VOLUME}
+       printf 'label: dos\n\n: start=2MiB, size=%iMiB, type=c\n: start=%iMiB, size=%iMiB, type=83\n' \
+               ${BOOT_MB} "$$((${BOOT_MB} + 2))" ${ROOT_MB} | sfdisk "$${VOLUME}"
+
+_raspberry_fstab:
+       printf '%%s\n' \
+              'LABEL=FSROOT / ${fstype} auto,nofail,rw 0 0' \
+              'LABEL=BOOT /boot/firmware vfat auto,nofail,ro 0 0' \
+              >"$${CFGROOT}/etc/fstab"
+
+
+ifeq "${fstype}" "ext4"
+  fsflag:=-F
+else
+  fsflag:=-f
+endif
+
+_format_root: ${PROOT}
+       -umount "$${CFGROOT}/boot/firmware" "$${CFGROOT}" "${PROOT}"
+       mkfs.${fstype} ${fsflag} -L FSROOT "$${PROOT}"
+
+_format_boot: ${PBOOT}
+       -umount "$${CFGROOT}/boot/firmware" "${PBOOT}"
+       mkfs.fat -F 32 -n BOOT "$${PBOOT}"
+
+_format: _format_root _format_boot
+
+${CFGROOT}/boot/firmware/cmdline.txt: ${CFGROOT} .FORCE
+       sed -Ei 's;root=/dev/loop[0-9]+;root=/dev/mmcblk0p2;' "$@"
+
+_bootloader_raspi: ${CFGROOT} ${CFGROOT}/boot/firmware/cmdline.txt
+
+_partcopy: ${VOLUME} ${PROOT} ${PBOOT}
+       dd conv=notrunc,sparse bs=1M seek=2 if="$${PBOOT}" of="$${VOLUME}"
+       dd conv=notrunc,sparse bs=1M seek=$$((2 + ${BOOT_MB})) if="$${PROOT}" of="$${VOLUME}"
+
+_mount_root: ${PROOT} ${CFGROOT}
+       mountpoint "$${CFGROOT}" \
+       || mount -t ${fstype} "$${PROOT}" "$${CFGROOT}"
+       chmod 755 "$${CFGROOT}"
+
+_mount_boot: ${PBOOT}
+       mkdir -p -m 755 "$${CFGROOT}/boot/firmware"
+       mountpoint "$${CFGROOT}/boot/firmware" \
+       || mount -t vfat "$${PBOOT}" "$${CFGROOT}/boot/firmware"
+
+_mount: _mount_root _mount_boot
+
+_img_mount: ${CFGROOT}
+       mountpoint "$${CFGROOT}" \
+       || mount -o loop,offset="$$((${BOOT_MB} + 2))"M,sizelimit=${ROOT_MB}M \
+                -t ${fstype} "$${VOLUME}" "$${CFGROOT}"
+       chmod 755 "$${CFGROOT}"
+       mkdir -p -m 755 "$${CFGROOT}/boot/firmware"
+       mountpoint "$${CFGROOT}/boot/firmware" \
+       || mount -o loop,offset=2M,sizelimit=${BOOT_MB}M \
+                -t vfat "$${VOLUME}" "$${CFGROOT}/boot/firmware"
+
+_umount_boot: ${CFGROOT} _config
+       sync
+       -umount "$${CFGROOT}/boot/firmware"
+
+_umount_root: _umount_boot _config
+       sync
+       umount "$${CFGROOT}" && rmdir "$${CFGROOT}"
+
+_umount: _umount_boot _umount_root
+
+_raspberry_clean:
+       -umount img_mount/boot/firmware
+       -umount img_mount
+       -rmdir img_mount
+       -rm rpi_boot.img
+       -rm rpi_root.img
+       -[ -f "$${VOLUME}" ] && rm "$${VOLUME}"