mirror of
https://gitlab.archlinux.org/tpowa/archboot.git
synced 2024-09-20 03:50:37 +02:00
296 lines
12 KiB
Bash
296 lines
12 KiB
Bash
#!/usr/bin/env bash
|
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
|
# created by Tobias Powalowski <tpowa@archlinux.org>
|
|
. /etc/archboot/defaults
|
|
_CONFIG_DIR="/etc/archboot"
|
|
_ISODIR="$(mktemp -d ISODIR.XXX)"
|
|
|
|
_usage () {
|
|
echo "CREATE ${_ARCH} USB/CD IMAGES"
|
|
echo "-----------------------------"
|
|
echo "This will create an archboot iso image."
|
|
echo ""
|
|
echo " -g Starting generation of image."
|
|
echo " -c=CONFIG Which CONFIG should be used."
|
|
echo " ${_CONFIG_DIR} locates the configs"
|
|
echo " default=${_ARCH}.conf"
|
|
echo " -i=IMAGENAME Your IMAGENAME."
|
|
echo " -s Save init ramdisk to $(pwd)"
|
|
echo " -h This message."
|
|
echo ""
|
|
echo "usage: ${_BASENAME} <options>"
|
|
exit 0
|
|
}
|
|
|
|
_parameters() {
|
|
while [ $# -gt 0 ]; do
|
|
case ${1} in
|
|
-g|--g) export _GENERATE="1" ;;
|
|
-s|--s) _SAVE_INIT="1" ;;
|
|
-c=*|--c=*) _CONFIG="$(echo "${1}" | awk -F= '{print $2;}')" ;;
|
|
-i=*|--i=*) _IMAGENAME="$(echo "${1}" | awk -F= '{print $2;}')" ;;
|
|
-h|--h|?) _usage ;;
|
|
*) _usage ;;
|
|
esac
|
|
shift
|
|
done
|
|
}
|
|
|
|
_config() {
|
|
# set defaults, if nothing given
|
|
[[ -z "${_CONFIG}" ]] && _CONFIG="${_ARCH}.conf"
|
|
_CONFIG="${_CONFIG_DIR}/${_CONFIG}"
|
|
#shellcheck disable=SC1090
|
|
. "${_CONFIG}"
|
|
#shellcheck disable=SC2116,2086
|
|
_KERNEL="$(echo ${_KERNEL})"
|
|
#shellcheck disable=SC2154
|
|
[[ -z "${_IMAGENAME}" ]] && _IMAGENAME="archboot-$(date +%Y.%m.%d-%H.%M)-$(_kver "${_KERNEL}")-${_ARCH}"
|
|
}
|
|
|
|
### EFI status of RISCV64:
|
|
#----------------------------------------------------
|
|
# EFI is not yet working for RISCV64!
|
|
# - grub does not allow linux command in memdisk mode
|
|
# - grub itself cannot initialize efi system partion
|
|
# - refind bails out with error
|
|
# - systemd-boot does not support loading of initrd
|
|
# - unified EFI is not possible because of this:
|
|
# https://sourceware.org/bugzilla/show_bug.cgi?id=29009
|
|
# - only left option is extlinux support in u-boot loader
|
|
_prepare_kernel_initrd_files() {
|
|
mkdir -p "${_ISODIR}"/EFI/{BOOT,TOOLS}
|
|
mkdir -p "${_ISODIR}/boot"
|
|
# needed to hash the kernel for secureboot enabled systems
|
|
echo "Preparing kernel..."
|
|
if [[ "${_ARCH}" == "x86_64" || "${_ARCH}" == "riscv64" ]]; then
|
|
install -m644 "${_KERNEL}" "${_ISODIR}/boot/vmlinuz-${_ARCH}"
|
|
fi
|
|
if [[ "${_ARCH}" == "aarch64" ]]; then
|
|
install -m644 "${_KERNEL}" "${_ISODIR}/boot/Image-${_ARCH}.gz"
|
|
fi
|
|
if [[ -f "./init-${_ARCH}.img" ]]; then
|
|
echo "Using existing init-${_ARCH}.img..."
|
|
cp "./init-${_ARCH}.img" "${_ISODIR}/boot/"
|
|
else
|
|
echo "Running archboot-cpio.sh for init-${_ARCH}.img..."
|
|
archboot-cpio.sh -c "/etc/archboot/${_ARCH}-init.conf" -k "${_KERNEL}" \
|
|
-g "${_ISODIR}/boot/init-${_ARCH}.img" || exit 1
|
|
# save init ramdisk for further images
|
|
if [[ -n "${_SAVE_INIT}" ]]; then
|
|
cp "${_ISODIR}/boot/init-${_ARCH}.img" ./
|
|
fi
|
|
fi
|
|
_INITRD="initrd-${_ARCH}.img"
|
|
echo "${_CONFIG}" | rg -qw local && _INITRD="initrd-local-${_ARCH}.img"
|
|
echo "${_CONFIG}" | rg -qw latest && _INITRD="initrd-latest-${_ARCH}.img"
|
|
if [[ -f "${_INITRD}" ]]; then
|
|
echo "Using existing ${_INITRD}..."
|
|
mv "./${_INITRD}" "${_ISODIR}/boot/initrd-${_ARCH}.img"
|
|
fi
|
|
if ! [[ -f "${_ISODIR}/boot/initrd-${_ARCH}.img" ]]; then
|
|
echo "Running archboot-cpio.sh for initrd-${_ARCH}.img..."
|
|
#shellcheck disable=SC2154
|
|
archboot-cpio.sh -c "${_CONFIG}" -k "${_KERNEL}" \
|
|
-g "${_ISODIR}/boot/initrd-${_ARCH}.img" || exit 1
|
|
fi
|
|
# delete cachedir on archboot environment
|
|
if rg -qw 'archboot' /etc/hostname; then
|
|
if [[ -d "${_CACHEDIR}" ]]; then
|
|
echo "Removing ${_CACHEDIR}..."
|
|
rm -rf "${_CACHEDIR}"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
_prepare_ucode() {
|
|
# only x86_64
|
|
if [[ "${_ARCH}" == "x86_64" ]]; then
|
|
echo "Preparing intel-ucode..."
|
|
cp /boot/intel-ucode.img "${_ISODIR}/boot/"
|
|
mkdir -p "${_ISODIR}"/licenses/intel-ucode
|
|
cp /usr/share/licenses/intel-ucode/LICENSE "${_ISODIR}/licenses/intel-ucode"
|
|
fi
|
|
# both x86_64 and aarch64
|
|
if ! [[ "${_ARCH}" == "riscv64" ]]; then
|
|
echo "Preparing amd-ucode..."
|
|
cp /boot/amd-ucode.img "${_ISODIR}/boot/"
|
|
mkdir -p "${_ISODIR}"/licenses/amd-ucode
|
|
cp /usr/share/licenses/amd-ucode/LICENSE.amd-ucode "${_ISODIR}/licenses/amd-ucode"
|
|
fi
|
|
}
|
|
|
|
_prepare_fedora_shim_bootloaders_x86_64 () {
|
|
echo "Preparing fedora shim..."
|
|
# Details on shim https://www.rodsbooks.com/efi-bootloaders/secureboot.html#initial_shim
|
|
# add shim x64 signed files from fedora
|
|
cp "/usr/share/archboot/bootloader/mmx64.efi" "${_ISODIR}/EFI/BOOT/MMX64.EFI"
|
|
cp "/usr/share/archboot/bootloader/BOOTX64.efi" "${_ISODIR}/EFI/BOOT/BOOTX64.EFI"
|
|
cp "/usr/share/archboot/bootloader/mmia32.efi" "${_ISODIR}/EFI/BOOT/MMIA32.EFI"
|
|
cp "/usr/share/archboot/bootloader/BOOTIA32.efi" "${_ISODIR}/EFI/BOOT/BOOTIA32.EFI"
|
|
}
|
|
|
|
_prepare_fedora_shim_bootloaders_aarch64 () {
|
|
echo "Preparing fedora shim..."
|
|
# Details on shim https://www.rodsbooks.com/efi-bootloaders/secureboot.html#initial_shim
|
|
# add shim aa64 signed files from fedora
|
|
cp "/usr/share/archboot/bootloader/mmaa64.efi" "${_ISODIR}/EFI/BOOT/MMAA64.EFI"
|
|
cp "/usr/share/archboot/bootloader/BOOTAA64.efi" "${_ISODIR}/EFI/BOOT/BOOTAA64.EFI"
|
|
}
|
|
|
|
_prepare_uefi_shell_tianocore() {
|
|
echo "Preparing UEFI shell..."
|
|
## Installing Tianocore UDK/EDK2 UEFI X64 "Full Shell"
|
|
cp /usr/share/edk2-shell/x64/Shell_Full.efi "${_ISODIR}/EFI/TOOLS/SHELLX64.EFI"
|
|
## Installing Tianocore UDK/EDK2 UEFI IA32 "Full Shell"
|
|
cp /usr/share/edk2-shell/ia32/Shell_Full.efi "${_ISODIR}/EFI/TOOLS/SHELLIA32.EFI"
|
|
}
|
|
|
|
# build grubXXX with all modules: http://bugs.archlinux.org/task/71382
|
|
_prepare_uefi_X64() {
|
|
echo "Preparing X64 grub..."
|
|
cp /usr/share/archboot/bootloader/grubx64.efi "${_ISODIR}/EFI/BOOT/GRUBX64.EFI"
|
|
}
|
|
|
|
_prepare_uefi_IA32() {
|
|
echo "Preparing IA32 grub..."
|
|
cp /usr/share/archboot/bootloader/grubia32.efi "${_ISODIR}/EFI/BOOT/GRUBIA32.EFI"
|
|
}
|
|
|
|
# build grubXXX with all modules: http://bugs.archlinux.org/task/71382
|
|
_prepare_uefi_AA64() {
|
|
echo "Preparing AA64 grub..."
|
|
cp /usr/share/archboot/bootloader/grubaa64.efi "${_ISODIR}/EFI/BOOT/GRUBAA64.EFI"
|
|
}
|
|
|
|
_prepare_memtest() {
|
|
echo "Preparing memtest86+..."
|
|
cp /boot/memtest86+/memtest.bin "${_ISODIR}/boot/"
|
|
cp /boot/memtest86+/memtest.efi "${_ISODIR}/EFI/TOOLS/MEMTEST.EFI"
|
|
}
|
|
|
|
_prepare_background() {
|
|
echo "Preparing grub background..."
|
|
[[ -d "${_ISODIR}/boot/grub" ]] || mkdir -p "${_ISODIR}/boot/grub"
|
|
cp ${_GRUB_BACKGROUND} "${_ISODIR}/boot/grub/archboot-background.png"
|
|
}
|
|
|
|
_reproducibility() {
|
|
# Reproducibility: set all timestamps to 0
|
|
# from /usr/bin/mkinitcpio
|
|
fd . "${_ISODIR}" -u --min-depth 1 -X touch -hcd "@0"
|
|
}
|
|
|
|
_prepare_uefi_image() {
|
|
echo "Preparing UEFI image..."
|
|
## get size of boot files
|
|
BOOTSIZE=$(LANG=C.UTF-8 du -bc "${_ISODIR}"/EFI "${_ISODIR}"/boot | rg '([0-9]+).*total' -r '$1')
|
|
IMGSZ=$((BOOTSIZE/1024 + 2048)) # image size in KB
|
|
VFAT_IMAGE="${_ISODIR}/efi.img"
|
|
## Creating efi.img
|
|
mkfs.vfat -n ARCHBOOT --invariant -C "${VFAT_IMAGE}" "${IMGSZ}" >"${_NO_LOG}"
|
|
## Copying all files to UEFI vfat image
|
|
mcopy -m -i "${VFAT_IMAGE}" -s "${_ISODIR}"/EFI "${_ISODIR}"/boot ::/
|
|
# leave EFI/ and /boot/kernel for virtualbox and other restricted VM emulators :(
|
|
if [[ "${_ARCH}" == "x86_64" || "${_ARCH}" == "riscv64" ]]; then
|
|
fd -u -t f -E "vmlinuz-${_ARCH}" . "${_ISODIR}"/boot/ -X rm
|
|
fi
|
|
if [[ "${_ARCH}" == "aarch64" ]]; then
|
|
fd -u -t f -E "Image-${_ARCH}.gz" . "${_ISODIR}"/boot/ -X rm
|
|
fi
|
|
}
|
|
|
|
_prepare_extlinux_conf() {
|
|
mkdir -p "${_ISODIR}"/boot/extlinux
|
|
_TITLE="Arch Linux RISC-V 64"
|
|
echo "Preparing extlinux.conf..."
|
|
cat << EOF >> "${_ISODIR}/boot/extlinux/extlinux.conf"
|
|
menu title Welcome to Archboot - ${_TITLE}
|
|
timeout 100
|
|
default linux
|
|
label linux
|
|
menu label Boot System (automatic boot in 10 seconds...)
|
|
kernel /boot/vmlinuz-${_ARCH}
|
|
initrd /boot/init-${_ARCH}.img
|
|
append console=ttyS0,115200 console=tty0 audit=0 systemd.show_status=auto
|
|
EOF
|
|
}
|
|
|
|
# https://github.com/CoelacanthusHex/archriscv-scriptlet/blob/master/mkimg
|
|
# https://checkmk.com/linux-knowledge/mounting-partition-loop-device
|
|
# calculate mountpoint offset: sector*start
|
|
# 512*2048=1048576 == 1M
|
|
# https://reproducible-builds.org/docs/system-images/
|
|
# mkfs.ext4 does not allow reproducibility
|
|
_uboot() {
|
|
echo "Generating ${_ARCH} U-Boot image..."
|
|
## get size of boot files
|
|
BOOTSIZE=$(LANG=C.UTF-8 du -bc "${_ISODIR}"/boot | rg '([0-9]+).*total' -r '$1')
|
|
IMGSZ=$((BOOTSIZE/1024 + 2048)) # image size in KB
|
|
VFAT_IMAGE="${_ISODIR}/extlinux.img"
|
|
dd if=/dev/zero of="${VFAT_IMAGE}" bs="${IMGSZ}" count=1024 status=none
|
|
sfdisk "${VFAT_IMAGE}" &>"${_NO_LOG}" <<EOF
|
|
label: dos
|
|
label-id: 0x12345678
|
|
device: "${VFAT_IMAGE}"
|
|
unit: sectors
|
|
"${VFAT_IMAGE}"1 : start= 2048, type=83, bootable
|
|
EOF
|
|
mkfs.vfat -n "ARCHBOOT" --offset=2048 --invariant "${VFAT_IMAGE}" >"${_NO_LOG}"
|
|
## Copying all files to UEFI vfat image
|
|
mcopy -m -i "${VFAT_IMAGE}"@@1048576 -s "${_ISODIR}"/boot ::/
|
|
mv "${VFAT_IMAGE}" "${_IMAGENAME}.img"
|
|
echo "Removing extlinux config file..."
|
|
rm -r "${_ISODIR}"/boot/extlinux
|
|
}
|
|
|
|
_grub_mkrescue() {
|
|
## Generating the BIOS+ISOHYBRID+UEFI CD image
|
|
#set date for reproducibility
|
|
# --set_all_file_dates for all files
|
|
# --modification-date= for boot.catalog
|
|
# --volid set ISO label ARCHBOOT
|
|
# -- -rm_r /efi .disk/ /boot/grub/{roms,locale} ${_RESCUE_REMOVE} for removing reproducibility breakers
|
|
echo "Generating ${_ARCH} hybrid ISO..."
|
|
[[ "${_ARCH}" == "x86_64" ]] && _RESCUE_REMOVE="mach_kernel /System /boot/grub/i386-efi /boot/grub/x86_64-efi"
|
|
[[ "${_ARCH}" == "aarch64" ]] && _RESCUE_REMOVE="/boot/grub/arm64-efi"
|
|
#shellcheck disable=SC2086
|
|
grub-mkrescue --set_all_file_dates 'Jan 1 00:00:00 UTC 1970' \
|
|
--modification-date=1970010100000000 --compress=xz --fonts="ter-u16n" \
|
|
--locales="" --themes="" -o "${_IMAGENAME}.iso" "${_ISODIR}"/ \
|
|
"boot/grub/archboot-main-grub.cfg=${_GRUB_CONFIG}" \
|
|
"boot/grub/grub.cfg=/usr/share/archboot/grub/archboot-iso-grub.cfg" \
|
|
-volid "ARCHBOOT" -- -rm_r /boot/grub/{roms,locale} /efi .disk/ \
|
|
${_RESCUE_REMOVE} &> "${_IMAGENAME}.log"
|
|
}
|
|
|
|
_unify_gpt_partitions() {
|
|
# GPT partition layout:
|
|
# 1: Gap0 | 2: EFI System Partition | 3: HFS/HFS+ | 4: GAP1
|
|
echo "Creating reproducible GUID, UUIDs, hide partitions and disable automount on ISO GPT..."
|
|
sfdisk -q --disk-id "${_IMAGENAME}.iso" "00000000-0000-0000-0000-000000000000"
|
|
# --> already set 0: system partition (does not allow delete on Windows)
|
|
# --> already set 60: readonly
|
|
# --> 62: hide all partitions, Windows cannot access any files on this ISO
|
|
# Windows will now only error on 1 drive and not on all partitions
|
|
# --> 63: disable freedesktop/systemd automount by default on this ISO
|
|
for i in $(seq 1 "$(sfdisk -J "${_IMAGENAME}.iso" | rg -cw 'node')"); do
|
|
sfdisk -q --part-attrs "${_IMAGENAME}.iso" "${i}" "RequiredPartition,60,62,63"
|
|
sfdisk -q --part-uuid "${_IMAGENAME}.iso" "${i}" "${i}0000000-0000-0000-0000-000000000000"
|
|
done
|
|
}
|
|
|
|
_create_cksum() {
|
|
## create b2sums.txt
|
|
echo "Generating b2sum..."
|
|
[[ -f "b2sums.txt" ]] && rm "b2sums.txt"
|
|
[[ "$(echo ./*.iso)" == "./*.iso" ]] || cksum -a blake2b ./*.iso > "b2sums.txt"
|
|
[[ "$(echo ./*.img)" == "./*.img" ]] || cksum -a blake2b ./*.img > "b2sums.txt"
|
|
}
|
|
|
|
_cleanup_iso() {
|
|
# cleanup
|
|
echo "Removing ${_ISODIR}..."
|
|
[[ -d "${_ISODIR}" ]] && rm -r "${_ISODIR}"
|
|
}
|
|
# vim: set ft=sh ts=4 sw=4 et:
|