# #
###############################################################################
+# Pakfire configuration file
+PAKFIRE_CONFIG="/etc/pakfire/distros/ipfire3.conf"
+
+# Packages to install in the live system
+PACKAGES=(
+ "@Base"
+ "kernel"
+)
+
+# Compress as best as we can
+ZSTD_COMPRESSION_LEVEL=22
+
+# Grub modules to install
+GRUB_MODULES=(
+ biosdisk
+ iso9660
+ linux
+ linux16
+ normal
+ search
+)
+
+allocate_file() {
+ local path="${1}"
+ local size="${2}"
+
+ dd if=/dev/zero of="${path}" bs=1k count="${size}"
+}
+
+make_live_system_image() {
+ local filename="${1}"
+
+ local tempdir="$(mktemp -d)"
+
+ # Install a very basic system
+ # XXX --arch="${arch}"
+ if ! pakfire --config="${PAKFIRE_CONFIG}" --root="${tempdir}" \
+ install --without-recommends "${PACKAGES[@]}"; then
+ echo "Could not install live system" >&2
+ rm -rf "${tempdir}"
+ return 1
+ fi
+
+ # Create a squashfs image
+ if ! mksquashfs "${tempdir}" "${filename}" \
+ -comp zstd -Xcompression-level "${ZSTD_COMPRESSION_LEVEL}"; then
+ rm -rf "${tempdir}"
+ return 1
+ fi
+
+ # Cleanup
+ rm -rf "${tempdir}"
+ return 0
+}
+
+make_boot_catalog() {
+ local path="${1}"
+
+ allocate_file "${path}" 2
+}
+
+make_grub_bios_image() {
+ local path="${1}"
+
+ local core_img="$(mktemp)"
+
+ # Create a standalone image
+ if ! grub-mkstandalone \
+ --format="${grub_arch}-pc" \
+ --output="${core_img}" \
+ --modules="${GRUB_MODULES[@]}" \
+ --install-modules="${GRUB_MODULES[@]}" \
+ --fonts="" --locales=""; then
+ unlink "${core_img}"
+ return 1
+ fi
+
+ # Append cdboot.img with the generated core.img
+ if ! cat "/usr/lib/grub/${grub_arch}-pc/cdboot.img" "${core_img}" > "${path}"; then
+ unlink "${core_img}" "${path}"
+ return 1
+ fi
+
+ # Cleanup
+ unlink "${core_img}"
+
+ return 0
+}
+
+make_grub_efi_image() {
+ local path="${1}"
+
+ # Allocate file
+ if ! allocate_file "${path}" 2880; then
+ return 1
+ fi
+
+ # Format it with FAT
+ if ! mkdosfs -F 12 -n "BRICKLAYER_EFI" "${path}"; then
+ echo "Could not format the EFI filesystem" >&2
+ return 1
+ fi
+
+ local tempdir="$(mktemp -d)"
+
+ # Mount the disk
+ if ! mount -o loop "${path}" "${tempdir}"; then
+ echo "Could not mount EFI filesystem" >&2
+ return 1
+ fi
+
+ mkdir -p "${tempdir}/EFI/BOOT"
+
+ # Generate a GRUB image
+ if ! grub-mkstandalone \
+ --format="${grub_arch}-efi" \
+ --output="${tempdir}/EFI/BOOT/bootx64.efi" \
+ --fonts="" --locales=""; then
+ echo "Could not generate GRUB EFI image" >&2
+ umount "${tempdir}"
+ rm -rf "${tempdir}"
+ return 1
+ fi
+
+ if ! umount "${tempdir}"; then
+ rm -rf "${tempdir}"
+ return 1
+ fi
+
+ return 0
+}
+
mkimage() {
local filename="${1}"
local r=0
# Create a temporary working directory
local tempdir="$(mktemp -d)"
+ # Create a directory for all the boot stuff
+ mkdir -p "${tempdir}/boot"
+
# Create argument list for xorriso
local args=(
# Emulate running as mkisofs
-as mkisofs
+ # Generate Joilet directory information
+ -J
+
+ # Generate rationalized Rock Ridge directory information
+ -r
+
# Be less verbose
- -quiet
+ #-quiet
# The name of the volume
-volid "${name}"
+ # Set ISO9660 conformance level
-iso-level 3
- -eltorito-alt-boot
- -no-emul-boot
# Where to write the output to?
-output "${filename}"
"${tempdir}"
)
- # Append EFI arguments
- if [ "${efi}" = "true" ]; then
+ # Determine GRUB architecture
+ local grub_arch="${arch}"
+ case "${arch}" in
+ aarch64)
+ grub_arch="arm64"
+ ;;
+
+ x86_64)
+ grub_arch="i386"
+ ;;
+ esac
+
+ # Generate GRUB BIOS image
+ if [ "${has_bios_boot}" = "true" ]; then
+ if ! make_grub_bios_image "${tempdir}/boot/biosboot.img"; then
+ rm -rf "${tempdir}"
+ return 1
+ fi
+
+ # Make boot catalog
+ if ! make_boot_catalog "${tempdir}/boot/boot.catalog"; then
+ rm -rf "${tempdir}"
+ return 1
+ fi
+
+ # Append to xorriso command line
+ args+=(
+ -no-emul-boot
+ -boot-load-size 4
+ -boot-info-table
+ -b "boot/biosboot.img"
+ -c "boot/boot.catalog"
+
+ # Enable hybrid boot mode
+ --grub2-boot-info
+ --grub2-mbr "/usr/lib/grub/${grub_arch}-pc/boot_hybrid.img"
+ )
+ fi
+
+ # Generate GRUB EFI image
+ if [ "${has_efi_boot}" = "true" ]; then
+ if ! make_grub_efi_image "${tempdir}/boot/efiboot.img"; then
+ rm -rf "${tempdir}"
+ return 1
+ fi
+
+ # Append to xorriso command line
args+=(
- -e "EFI/efiboot.img"
+ -eltorito-alt-boot
+ -e "boot/efiboot.img"
+ -no-emul-boot
+ -isohybrid-gpt-basdat
)
fi
+ # Create the live system image
+ if ! make_live_system_image "${tempdir}/live-os.img"; then
+ rm -rf "${tempdir}"
+ return 1
+ fi
+
+ # Master the ISO file
if ! xorriso "${args[@]}"; then
r=1
fi
main() {
local arch="$(uname -m)"
- local efi="true"
local filename
while [ $# -gt 0 ]; do
arch="${1#*=}"
;;
- --disable-efi)
- efi="false"
- ;;
-
*.iso)
if [ -n "${filename}" ]; then
echo "Filename has already been set" >&2
return 2
fi
+ local has_bios_boot="false"
+ local has_efi_boot="false"
+
+ # Configure some architecture-dependent environment variables
+ case "${arch}" in
+ aarch64)
+ has_efi_boot="true"
+ ;;
+
+ x86_64)
+ has_bios_boot="true"
+ #has_efi_boot="true"
+ ;;
+
+ # Throw an error on unhandled architectures
+ *)
+ echo "Unknown architecture: ${arch}" >&2
+ return 2
+ ;;
+ esac
+
# Make image and delete it if something went wrong
if ! mkimage "${filename}"; then
- unlink "${filename}"
+ rm -f "${filename}"
return 1
fi