From 3e7604601a5c70444955b16020e02148b419b985 Mon Sep 17 00:00:00 2001 From: Oliver Smith Date: Sat, 11 Apr 2020 11:47:41 +0200 Subject: [PATCH] main/postmarketos-mkinitfs: split mkinitfs funcs (!1123) Split mkinitfs.sh into two files, so the functions (now in mkinitfs_functions.sh) can be sourced in a test. Such a test will be added in the next commit. Move $BINARIES_EXTRA into the get_binaries_extra() function, so its $(find...) does not get executed when sourcing the functions file. Move $BINARIES into get_binaries() too for consistency. --- .gitlab-ci/shellcheck.sh | 1 + main/postmarketos-mkinitfs/APKBUILD | 15 +- main/postmarketos-mkinitfs/mkinitfs.sh | 405 +---------------- .../mkinitfs_functions.sh | 413 ++++++++++++++++++ 4 files changed, 429 insertions(+), 405 deletions(-) create mode 100644 main/postmarketos-mkinitfs/mkinitfs_functions.sh diff --git a/.gitlab-ci/shellcheck.sh b/.gitlab-ci/shellcheck.sh index 97954721d..51024f92a 100755 --- a/.gitlab-ci/shellcheck.sh +++ b/.gitlab-ci/shellcheck.sh @@ -19,6 +19,7 @@ sh_files=" ./main/postmarketos-mkinitfs/init.sh.in ./main/postmarketos-mkinitfs/init_functions.sh ./main/postmarketos-mkinitfs/mkinitfs.sh + ./main/postmarketos-mkinitfs/mkinitfs_functions.sh ./main/postmarketos-mkinitfs-hook-debug-shell/20-debug-shell.sh ./main/postmarketos-update-kernel/update-kernel.sh ./main/mdss-fb-init-hack/mdss-fb-init-hack.sh diff --git a/main/postmarketos-mkinitfs/APKBUILD b/main/postmarketos-mkinitfs/APKBUILD index ba73bc65f..af571ead6 100644 --- a/main/postmarketos-mkinitfs/APKBUILD +++ b/main/postmarketos-mkinitfs/APKBUILD @@ -1,5 +1,5 @@ pkgname=postmarketos-mkinitfs -pkgver=0.11.0 +pkgver=0.11.1 pkgrel=0 pkgdesc="Tool to generate initramfs images for postmarketOS" url="https://postmarketos.org" @@ -7,22 +7,29 @@ url="https://postmarketos.org" depends="busybox-extras lddtree cryptsetup kmod multipath-tools device-mapper parted e2fsprogs e2fsprogs-extra osk-sdl charging-sdl triggerhappy xz bzip2 lz4" triggers="$pkgname.trigger=/etc/postmarketos-mkinitfs/hooks:/usr/share/kernel/*" -source="init.sh.in init_functions.sh mkinitfs.sh" +source="init.sh.in + init_functions.sh + mkinitfs.sh + mkinitfs_functions.sh + " arch="noarch" license="GPL2" provides="mkinitfs=0.0.1" options="!check" package() { - for file in init.sh.in init_functions.sh; do + for file in init.sh.in init_functions.sh mkinitfs_functions.sh; do install -Dm644 "$srcdir/$file" \ "$pkgdir/usr/share/postmarketos-mkinitfs/$file" done + install -Dm755 "$srcdir/mkinitfs.sh" \ "$pkgdir/sbin/mkinitfs" + mkdir -p "$pkgdir/etc/postmarketos-mkinitfs/hooks/" } sha512sums="1d49db8a48ad513cc548b8a0ea23cc64518e71c93863155b4e9d2271fb46090506331c03d6955d693c8568c248ecc76b218efe4a6f6bba57c41c5f6d775dc61b init.sh.in 315cc6e8a73f9984e6843395d68734d26ac2fffce34039ec5f229ebcd818bdb353318398d6c824cede5d0b36e13d7589a1f1d3295d8162279b5dc6a2b939da88 init_functions.sh -f746738f8485d16a6014a9dc75a5bfdd21a34ef2d25f90a3684388d44ce8a68912f9b1b736e45b85dd068ccbbb7c902c531723234dca243c40f0ecf577561e65 mkinitfs.sh" +7201d4640a3e9ead8a47ffd9916b068476b7d950760a84c37e02268c942d49896bc986da6bdee27e832639c90775354d68046a6475205d8d1da995b068120d8f mkinitfs.sh +a3e61f10ab63000b7ee2aafe021c248367ac2dd0ac6e5c263cfaf9d510e64b6e3dc9983e3b49e47fb7d8734ebcc277948003af01fa79f5f11703f7fb79281f4b mkinitfs_functions.sh" diff --git a/main/postmarketos-mkinitfs/mkinitfs.sh b/main/postmarketos-mkinitfs/mkinitfs.sh index 12d439229..67ac5115b 100644 --- a/main/postmarketos-mkinitfs/mkinitfs.sh +++ b/main/postmarketos-mkinitfs/mkinitfs.sh @@ -1,406 +1,9 @@ #!/bin/sh -# Declare used deviceinfo variables to pass shellcheck (order alphabetically) -deviceinfo_append_dtb="" -deviceinfo_arch="" -deviceinfo_bootimg_append_seandroidenforce="" -deviceinfo_bootimg_blobpack="" -deviceinfo_bootimg_dtb_second="" -deviceinfo_bootimg_mtk_mkimage="" -deviceinfo_bootimg_qcdt="" -deviceinfo_dtb="" -deviceinfo_flash_offset_base="" -deviceinfo_flash_offset_kernel="" -deviceinfo_flash_offset_ramdisk="" -deviceinfo_flash_offset_second="" -deviceinfo_flash_offset_tags="" -deviceinfo_flash_pagesize="" -deviceinfo_generate_bootimg="" -deviceinfo_generate_legacy_uboot_initfs="" -deviceinfo_initfs_compression="" -deviceinfo_kernel_cmdline="" -deviceinfo_legacy_uboot_load_address="" -deviceinfo_modules_initfs="" - - -source_deviceinfo() -{ - if [ ! -e "/etc/deviceinfo" ]; then - echo "NOTE: deviceinfo (from device package) not installed yet," \ - "not building the initramfs now (it should get built later" \ - "automatically.)" - exit 0 - fi - # shellcheck disable=SC1091 - . /etc/deviceinfo -} - -parse_commandline() -{ - if [ "$1" != "-o" ]; then - echo "postmarketos-mkinitfs" - echo "usage: $(basename "$0") -o OUTFILE KERNELVERSION" - exit 1 - fi - - outfile=$2 - outfile_extra=$2-extra - kernel=$3 -} - -# Verify that each file required by the installed hooks exists and exit with an -# error if they don't. -check_hook_files() -{ - for file in "/etc/postmarketos-mkinitfs/files"/*.files; do - [ -f "$file" ] || continue - while IFS= read -r line; do - if ! [ -f "$line" ]; then - echo "ERROR: File ${line} specified in ${file} does not exist!" - exit 1 - fi - done < "$file" - done -} - -create_folders() -{ - for dir in /bin /sbin /usr/bin /usr/sbin /proc /sys /dev /tmp /lib \ - /boot /sysroot /etc; do - mkdir -p "$tmpdir$dir" - done -} - -get_modules_by_globs() -{ - globs=" - # base.modules - kernel/drivers/block/loop.ko - kernel/fs/overlayfs - - # cryptsetup.modules - kernel/crypto/* - kernel/arch/*/crypto/* - kernel/drivers/md/dm-crypt.ko - - # required for modprobe - modules.* - " - - for glob in $globs; do - for file in /lib/modules/$kernel/$glob; do - if [ -d "$file" ]; then - find "$file" -type f - elif [ -e "$file" ]; then - echo "$file" - fi - done - done -} - -# NOTE: This does not work with busybox' modprobe -# That's why postmarketos-mkinitfs depends on kmod -get_modules_by_name() -{ - { - echo "Scanning kernel module dependencies..." - echo "NOTE: ** modprobe warnings below can be ignored ** if your device does not run the" - echo "mainline kernel yet (most devices!) or if the related kernel options are enabled" - echo "with 'y' instead of 'm' (module)." - } >&2 - - MODULES="dm_crypt ext4 usb_f_rndis \ - ${deviceinfo_modules_initfs}" - - # shellcheck disable=SC2086 - modprobe \ - -a \ - --dry-run \ - --show-depends \ - --set-version="$kernel" \ - $MODULES \ - | sort -u \ - | cut -d ' ' -f 2 -} - -get_modules() -{ - get_modules_by_globs - get_modules_by_name -} - -# Get the paths to all binaries and their dependencies -BINARIES="/bin/busybox /bin/busybox-extras /usr/sbin/telnetd /sbin/kpartx" -BINARIES_EXTRA=" - $(find /usr/lib/directfb-* -name '*.so') - /lib/libz.so.1 - /sbin/cryptsetup - /sbin/dmsetup - /sbin/e2fsck - /usr/bin/charging-sdl - /usr/bin/osk-sdl - /usr/lib/libGL.so.1 - /usr/lib/libts* - /usr/lib/ts/* - /usr/sbin/parted - /usr/sbin/resize2fs - /usr/sbin/thd -" -get_binaries() -{ - for file in "/etc/postmarketos-mkinitfs/files"/*.files; do - [ -f "$file" ] || continue - while IFS= read -r line; do - BINARIES="${BINARIES} ${line}" - done < "$file" - done - # shellcheck disable=SC2086 - sudo -u nobody lddtree -l $BINARIES | sort -u -} - -# Collect non-binary files for osk-sdl and its dependencies -# This gets called as $(get_osk_config), so the exit code can be checked/handled. -get_osk_config() -{ - fontpath=$(awk '/^keyboard-font/{print $3}' /etc/osk.conf) - if [ ! -f "$fontpath" ]; then - echo "ERROR: failed to parse 'keyboard-font' from osk-sdl config!" - exit 1 - fi - ret=" - /etc/osk.conf - /etc/ts.conf - /etc/pointercal - /etc/fb.modes - /etc/directfbrc - $fontpath - " - echo "${ret}" -} - -get_binaries_extra() -{ - tmp1=$(mktemp /tmp/mkinitfs.XXXXXX) - get_binaries > "$tmp1" - tmp2=$(mktemp /tmp/mkinitfs.XXXXXX) - - # shellcheck disable=SC2086 - sudo -u nobody lddtree -l $BINARIES_EXTRA | sort -u > "$tmp2" - ret=$(comm -13 "$tmp1" "$tmp2") - rm "$tmp1" "$tmp2" - echo "${ret}" -} - -# Copy files to the destination specified -# $1: files -# $2: destination -copy_files() -{ - for file in $1; do - [ -e "$file" ] || continue - cp -a --parents "$file" "$2" - done -} - -create_device_nodes() -{ - mknod -m 666 "$tmpdir/dev/null" c 1 3 - mknod -m 644 "$tmpdir/dev/random" c 1 8 - mknod -m 644 "$tmpdir/dev/urandom" c 1 9 -} - -replace_init_variables() -{ - sed -i "s:@INITRAMFS_EXTRA@:${outfile_extra}:g" "$tmpdir/init" -} - -# Create a cpio image of the specified folder -# $1: folder -# $2: outfile -create_cpio_image() -{ - if ! cd "$1"; then - echo "ERROR: failed to cd to '$1'" - exit 1 - fi - [ -z "$deviceinfo_initfs_compression" ] && deviceinfo_initfs_compression='gzip -1' - find . -print0 \ - | cpio --quiet -o -H newc \ - | $deviceinfo_initfs_compression > "$2" -} - -# Required command check with useful error message -# $1: command (e.g. "mkimage") -# $2: package (e.g. "uboot-tools") -# $3: related deviceinfo variable (e.g. "generate_bootimg") -require_package() -{ - [ "$(command -v "$1")" = "" ] || return - echo "ERROR: 'deviceinfo_$3' is set, but the package '$2' was not" - echo "installed! Please add '$2' to the depends= line of your device's" - echo "APKBUILD. See also: " - exit 1 -} - -# Legacy u-boot images -create_uboot_files() -{ - arch="arm" - if [ "${deviceinfo_arch}" = "aarch64" ]; then - arch="arm64" - fi - - [ "${deviceinfo_generate_legacy_uboot_initfs}" = "true" ] || return - require_package "mkimage" "uboot-tools" "generate_legacy_uboot_initfs" - - echo "==> initramfs: creating uInitrd" - # shellcheck disable=SC2039 - mkimage -A $arch -T ramdisk -C none -n uInitrd -d "$outfile" \ - "${outfile/initramfs-/uInitrd-}" || exit 1 - - echo "==> kernel: creating uImage" - # shellcheck disable=SC2039 - kernelfile="${outfile/initramfs-/vmlinuz-}" - if [ "${deviceinfo_append_dtb}" = "true" ]; then - kernelfile="${kernelfile}-dtb" - fi - - if [ -z "$deviceinfo_legacy_uboot_load_address" ]; then - deviceinfo_legacy_uboot_load_address="80008000" - fi - - # shellcheck disable=SC2039 - mkimage -A $arch -O linux -T kernel -C none -a "$deviceinfo_legacy_uboot_load_address" \ - -e "$deviceinfo_legacy_uboot_load_address" \ - -n postmarketos -d "$kernelfile" "${outfile/initramfs-/uImage-}" || exit 1 -} - -# Android devices -create_bootimg() -{ - [ "${deviceinfo_generate_bootimg}" = "true" ] || return - require_package "mkbootimg-osm0sis" "mkbootimg" "generate_bootimg" - - echo "==> initramfs: creating boot.img" - _base="${deviceinfo_flash_offset_base}" - [ -z "$_base" ] && _base="0x10000000" - - if [ "${deviceinfo_bootimg_mtk_mkimage}" = "true" ]; then - require_package "mtk-mkimage" "mtk-mkimage" "bootimg_mtk_mkimage" - mv "$outfile" "$outfile-orig" - mtk-mkimage ROOTFS "$outfile-orig" "$outfile" - fi - - # shellcheck disable=SC2039 - kernelfile="${outfile/initramfs-/vmlinuz-}" - if [ "${deviceinfo_append_dtb}" = "true" ]; then - kernelfile="${kernelfile}-dtb" - fi - _second="" - if [ "${deviceinfo_bootimg_dtb_second}" = "true" ]; then - if [ -z "${deviceinfo_dtb}" ]; then - echo "ERROR: deviceinfo_bootimg_dtb_second is set, but" - echo "'deviceinfo_dtb' is missing. Set 'deviceinfo_dtb'" - echo "to the device tree blob for your device." - echo "See also: " - exit 1 - fi - dtb="/usr/share/dtb/${deviceinfo_dtb}.dtb" - _second="--second $dtb" - if ! [ -e "$dtb" ]; then - echo "ERROR: File not found: $dtb. Please set 'deviceinfo_dtb'" - echo "to the relative path to the device tree blob for your" - echo "device (without .dtb)." - echo "See also: " - exit 1 - fi - fi - _dt="" - if [ "${deviceinfo_bootimg_qcdt}" = "true" ]; then - _dt="--dt /boot/dt.img" - if ! [ -e "/boot/dt.img" ]; then - echo "ERROR: File not found: /boot/dt.img, but" - echo "'deviceinfo_bootimg_qcdt' is set. Please verify that your" - echo "device is a QCDT device by analyzing the boot.img file" - echo "(e.g. 'pmbootstrap bootimg_analyze path/to/twrp.img')" - echo "and based on that, set the deviceinfo variable to false or" - echo "adjust your linux APKBUILD to properly generate the dt.img" - echo "file. See also: " - exit 1 - fi - fi - # shellcheck disable=SC2039 - mkbootimg-osm0sis \ - --kernel "${kernelfile}" \ - --ramdisk "$outfile" \ - --base "${_base}" \ - --second_offset "${deviceinfo_flash_offset_second}" \ - --cmdline "${deviceinfo_kernel_cmdline}" \ - --kernel_offset "${deviceinfo_flash_offset_kernel}" \ - --ramdisk_offset "${deviceinfo_flash_offset_ramdisk}" \ - --tags_offset "${deviceinfo_flash_offset_tags}" \ - --pagesize "${deviceinfo_flash_pagesize}" \ - "${_second}" \ - "${_dt}" \ - -o "${outfile/initramfs-/boot.img-}" || exit 1 - if [ "${deviceinfo_bootimg_blobpack}" = "true" ]; then - echo "==> initramfs: creating blob" - # shellcheck disable=SC2039 - blobpack "${outfile/initramfs-/blob-}" LNX \ - "${outfile/initramfs-/boot.img-}" || exit 1 - fi - if [ "${deviceinfo_bootimg_append_seandroidenforce}" = "true" ]; then - echo "==> initramfs: appending 'SEANDROIDENFORCE' to boot.img" - # shellcheck disable=SC2039 disable=SC2039 - echo -n "SEANDROIDENFORCE" >> "${outfile/initramfs-/boot.img-}" - fi -} - -# Append the correct device tree to the linux image file or copy the dtb to the boot partition -append_or_copy_dtb() -{ - [ -n "${deviceinfo_dtb}" ] || return - dtb="/usr/share/dtb/${deviceinfo_dtb}.dtb" - # shellcheck disable=SC2039 - kernel="${outfile/initramfs-/vmlinuz-}" - echo "==> kernel: device-tree blob operations" - if ! [ -e "$dtb" ]; then - echo "ERROR: File not found: $dtb" - exit 1 - fi - if [ "${deviceinfo_append_dtb}" = "true" ]; then - echo "==> kernel: appending device-tree ${deviceinfo_dtb}" - cat "$kernel" "$dtb" > "${kernel}-dtb" - else - echo "==> kernel: copying dtb ${deviceinfo_dtb} to boot partition" - cp "$dtb" "$(dirname "${outfile}")" - fi -} - -# Create the initramfs-extra archive -# $1: outfile -generate_initramfs_extra() -{ - echo "==> initramfs: creating $1" - - osk_conf="$(get_osk_config)" - if [ $? -eq 1 ]; then - echo "ERROR: Font specified in /etc/osk.conf does not exist!" - exit 1 - fi - - # Set up initramfs-extra in temp folder - tmpdir_extra=$(mktemp -d /tmp/mkinitfs.XXXXXX) - mkdir -p "$tmpdir_extra" - copy_files "$(get_binaries_extra)" "$tmpdir_extra" - copy_files "$osk_conf" "$tmpdir_extra" - create_cpio_image "$tmpdir_extra" "$1.new" - rm -rf "$tmpdir_extra" - - # Replace old initramfs-extra *after* we are done to make sure - # it does not become corrupted if something goes wrong. - mv "$1.new" "$1" -} +outfile="" +outfile_extra="" +# shellcheck disable=SC1091 +. /usr/share/postmarketos-mkinitfs/mkinitfs_functions.sh # initialize source_deviceinfo diff --git a/main/postmarketos-mkinitfs/mkinitfs_functions.sh b/main/postmarketos-mkinitfs/mkinitfs_functions.sh new file mode 100644 index 000000000..5e290445f --- /dev/null +++ b/main/postmarketos-mkinitfs/mkinitfs_functions.sh @@ -0,0 +1,413 @@ +#!/bin/sh + +# Declare used deviceinfo variables to pass shellcheck (order alphabetically) +deviceinfo_append_dtb="" +deviceinfo_arch="" +deviceinfo_bootimg_append_seandroidenforce="" +deviceinfo_bootimg_blobpack="" +deviceinfo_bootimg_dtb_second="" +deviceinfo_bootimg_mtk_mkimage="" +deviceinfo_bootimg_qcdt="" +deviceinfo_dtb="" +deviceinfo_flash_offset_base="" +deviceinfo_flash_offset_kernel="" +deviceinfo_flash_offset_ramdisk="" +deviceinfo_flash_offset_second="" +deviceinfo_flash_offset_tags="" +deviceinfo_flash_pagesize="" +deviceinfo_generate_bootimg="" +deviceinfo_generate_legacy_uboot_initfs="" +deviceinfo_initfs_compression="" +deviceinfo_kernel_cmdline="" +deviceinfo_legacy_uboot_load_address="" +deviceinfo_modules_initfs="" + +# Overwritten by mkinitfs.sh +tmpdir="" + +source_deviceinfo() +{ + if [ ! -e "/etc/deviceinfo" ]; then + echo "NOTE: deviceinfo (from device package) not installed yet," \ + "not building the initramfs now (it should get built later" \ + "automatically.)" + exit 0 + fi + # shellcheck disable=SC1091 + . /etc/deviceinfo +} + +parse_commandline() +{ + if [ "$1" != "-o" ]; then + echo "postmarketos-mkinitfs" + echo "usage: $(basename "$0") -o OUTFILE KERNELVERSION" + exit 1 + fi + + outfile=$2 + outfile_extra=$2-extra + kernel=$3 +} + +# Verify that each file required by the installed hooks exists and exit with an +# error if they don't. +check_hook_files() +{ + for file in "/etc/postmarketos-mkinitfs/files"/*.files; do + [ -f "$file" ] || continue + while IFS= read -r line; do + if ! [ -f "$line" ]; then + echo "ERROR: File ${line} specified in ${file} does not exist!" + exit 1 + fi + done < "$file" + done +} + +create_folders() +{ + for dir in /bin /sbin /usr/bin /usr/sbin /proc /sys /dev /tmp /lib \ + /boot /sysroot /etc; do + mkdir -p "$tmpdir$dir" + done +} + +get_modules_by_globs() +{ + globs=" + # base.modules + kernel/drivers/block/loop.ko + kernel/fs/overlayfs + + # cryptsetup.modules + kernel/crypto/* + kernel/arch/*/crypto/* + kernel/drivers/md/dm-crypt.ko + + # required for modprobe + modules.* + " + + for glob in $globs; do + for file in /lib/modules/$kernel/$glob; do + if [ -d "$file" ]; then + find "$file" -type f + elif [ -e "$file" ]; then + echo "$file" + fi + done + done +} + +# NOTE: This does not work with busybox' modprobe +# That's why postmarketos-mkinitfs depends on kmod +get_modules_by_name() +{ + { + echo "Scanning kernel module dependencies..." + echo "NOTE: ** modprobe warnings below can be ignored ** if your device does not run the" + echo "mainline kernel yet (most devices!) or if the related kernel options are enabled" + echo "with 'y' instead of 'm' (module)." + } >&2 + + + MODULES="dm_crypt ext4 usb_f_rndis \ + ${deviceinfo_modules_initfs}" + + # shellcheck disable=SC2086 + modprobe \ + -a \ + --dry-run \ + --show-depends \ + --set-version="$kernel" \ + $MODULES \ + | sort -u \ + | cut -d ' ' -f 2 +} + +get_modules() +{ + get_modules_by_globs + get_modules_by_name +} + +# Get the paths to all binaries and their dependencies +get_binaries() +{ + BINARIES=" + /bin/busybox + /bin/busybox-extras + /usr/sbin/telnetd + /sbin/kpartx + " + + for file in "/etc/postmarketos-mkinitfs/files"/*.files; do + [ -f "$file" ] || continue + while IFS= read -r line; do + BINARIES="${BINARIES} ${line}" + done < "$file" + done + # shellcheck disable=SC2086 + sudo -u nobody lddtree -l $BINARIES | sort -u +} + +# Collect non-binary files for osk-sdl and its dependencies +# This gets called as $(get_osk_config), so the exit code can be checked/handled. +get_osk_config() +{ + fontpath=$(awk '/^keyboard-font/{print $3}' /etc/osk.conf) + if [ ! -f "$fontpath" ]; then + echo "ERROR: failed to parse 'keyboard-font' from osk-sdl config!" + exit 1 + fi + ret=" + /etc/osk.conf + /etc/ts.conf + /etc/pointercal + /etc/fb.modes + /etc/directfbrc + $fontpath + " + echo "${ret}" +} + +get_binaries_extra() +{ + BINARIES_EXTRA=" + $(find /usr/lib/directfb-* -name '*.so') + /lib/libz.so.1 + /sbin/cryptsetup + /sbin/dmsetup + /sbin/e2fsck + /usr/bin/charging-sdl + /usr/bin/osk-sdl + /usr/lib/libGL.so.1 + /usr/lib/libts* + /usr/lib/ts/* + /usr/sbin/parted + /usr/sbin/resize2fs + /usr/sbin/thd + " + + tmp1=$(mktemp /tmp/mkinitfs.XXXXXX) + get_binaries > "$tmp1" + tmp2=$(mktemp /tmp/mkinitfs.XXXXXX) + + # shellcheck disable=SC2086 + sudo -u nobody lddtree -l $BINARIES_EXTRA | sort -u > "$tmp2" + ret=$(comm -13 "$tmp1" "$tmp2") + rm "$tmp1" "$tmp2" + echo "${ret}" +} + +# Copy files to the destination specified +# $1: files +# $2: destination +copy_files() +{ + for file in $1; do + [ -e "$file" ] || continue + cp -a --parents "$file" "$2" + done +} + +create_device_nodes() +{ + mknod -m 666 "$tmpdir/dev/null" c 1 3 + mknod -m 644 "$tmpdir/dev/random" c 1 8 + mknod -m 644 "$tmpdir/dev/urandom" c 1 9 +} + +replace_init_variables() +{ + sed -i "s:@INITRAMFS_EXTRA@:${outfile_extra}:g" "$tmpdir/init" +} + +# Create a cpio image of the specified folder +# $1: folder +# $2: outfile +create_cpio_image() +{ + if ! cd "$1"; then + echo "ERROR: failed to cd to '$1'" + exit 1 + fi + [ -z "$deviceinfo_initfs_compression" ] && deviceinfo_initfs_compression='gzip -1' + find . -print0 \ + | cpio --quiet -o -H newc \ + | $deviceinfo_initfs_compression > "$2" +} + +# Required command check with useful error message +# $1: command (e.g. "mkimage") +# $2: package (e.g. "uboot-tools") +# $3: related deviceinfo variable (e.g. "generate_bootimg") +require_package() +{ + [ "$(command -v "$1")" = "" ] || return + echo "ERROR: 'deviceinfo_$3' is set, but the package '$2' was not" + echo "installed! Please add '$2' to the depends= line of your device's" + echo "APKBUILD. See also: " + exit 1 +} + +# Legacy u-boot images +create_uboot_files() +{ + arch="arm" + if [ "${deviceinfo_arch}" = "aarch64" ]; then + arch="arm64" + fi + + [ "${deviceinfo_generate_legacy_uboot_initfs}" = "true" ] || return + require_package "mkimage" "uboot-tools" "generate_legacy_uboot_initfs" + + echo "==> initramfs: creating uInitrd" + # shellcheck disable=SC2039 + mkimage -A $arch -T ramdisk -C none -n uInitrd -d "$outfile" \ + "${outfile/initramfs-/uInitrd-}" || exit 1 + + echo "==> kernel: creating uImage" + # shellcheck disable=SC2039 + kernelfile="${outfile/initramfs-/vmlinuz-}" + if [ "${deviceinfo_append_dtb}" = "true" ]; then + kernelfile="${kernelfile}-dtb" + fi + + if [ -z "$deviceinfo_legacy_uboot_load_address" ]; then + deviceinfo_legacy_uboot_load_address="80008000" + fi + + # shellcheck disable=SC2039 + mkimage -A $arch -O linux -T kernel -C none -a "$deviceinfo_legacy_uboot_load_address" \ + -e "$deviceinfo_legacy_uboot_load_address" \ + -n postmarketos -d "$kernelfile" "${outfile/initramfs-/uImage-}" || exit 1 +} + +# Android devices +create_bootimg() +{ + [ "${deviceinfo_generate_bootimg}" = "true" ] || return + require_package "mkbootimg-osm0sis" "mkbootimg" "generate_bootimg" + + echo "==> initramfs: creating boot.img" + _base="${deviceinfo_flash_offset_base}" + [ -z "$_base" ] && _base="0x10000000" + + if [ "${deviceinfo_bootimg_mtk_mkimage}" = "true" ]; then + require_package "mtk-mkimage" "mtk-mkimage" "bootimg_mtk_mkimage" + mv "$outfile" "$outfile-orig" + mtk-mkimage ROOTFS "$outfile-orig" "$outfile" + fi + + # shellcheck disable=SC2039 + kernelfile="${outfile/initramfs-/vmlinuz-}" + if [ "${deviceinfo_append_dtb}" = "true" ]; then + kernelfile="${kernelfile}-dtb" + fi + _second="" + if [ "${deviceinfo_bootimg_dtb_second}" = "true" ]; then + if [ -z "${deviceinfo_dtb}" ]; then + echo "ERROR: deviceinfo_bootimg_dtb_second is set, but" + echo "'deviceinfo_dtb' is missing. Set 'deviceinfo_dtb'" + echo "to the device tree blob for your device." + echo "See also: " + exit 1 + fi + dtb="/usr/share/dtb/${deviceinfo_dtb}.dtb" + _second="--second $dtb" + if ! [ -e "$dtb" ]; then + echo "ERROR: File not found: $dtb. Please set 'deviceinfo_dtb'" + echo "to the relative path to the device tree blob for your" + echo "device (without .dtb)." + echo "See also: " + exit 1 + fi + fi + _dt="" + if [ "${deviceinfo_bootimg_qcdt}" = "true" ]; then + _dt="--dt /boot/dt.img" + if ! [ -e "/boot/dt.img" ]; then + echo "ERROR: File not found: /boot/dt.img, but" + echo "'deviceinfo_bootimg_qcdt' is set. Please verify that your" + echo "device is a QCDT device by analyzing the boot.img file" + echo "(e.g. 'pmbootstrap bootimg_analyze path/to/twrp.img')" + echo "and based on that, set the deviceinfo variable to false or" + echo "adjust your linux APKBUILD to properly generate the dt.img" + echo "file. See also: " + exit 1 + fi + fi + # shellcheck disable=SC2039 + mkbootimg-osm0sis \ + --kernel "${kernelfile}" \ + --ramdisk "$outfile" \ + --base "${_base}" \ + --second_offset "${deviceinfo_flash_offset_second}" \ + --cmdline "${deviceinfo_kernel_cmdline}" \ + --kernel_offset "${deviceinfo_flash_offset_kernel}" \ + --ramdisk_offset "${deviceinfo_flash_offset_ramdisk}" \ + --tags_offset "${deviceinfo_flash_offset_tags}" \ + --pagesize "${deviceinfo_flash_pagesize}" \ + "${_second}" \ + "${_dt}" \ + -o "${outfile/initramfs-/boot.img-}" || exit 1 + if [ "${deviceinfo_bootimg_blobpack}" = "true" ]; then + echo "==> initramfs: creating blob" + # shellcheck disable=SC2039 + blobpack "${outfile/initramfs-/blob-}" LNX \ + "${outfile/initramfs-/boot.img-}" || exit 1 + fi + if [ "${deviceinfo_bootimg_append_seandroidenforce}" = "true" ]; then + echo "==> initramfs: appending 'SEANDROIDENFORCE' to boot.img" + # shellcheck disable=SC2039 disable=SC2039 + echo -n "SEANDROIDENFORCE" >> "${outfile/initramfs-/boot.img-}" + fi +} + +# Append the correct device tree to the linux image file or copy the dtb to the boot partition +append_or_copy_dtb() +{ + [ -n "${deviceinfo_dtb}" ] || return + dtb="/usr/share/dtb/${deviceinfo_dtb}.dtb" + # shellcheck disable=SC2039 + kernel="${outfile/initramfs-/vmlinuz-}" + echo "==> kernel: device-tree blob operations" + if ! [ -e "$dtb" ]; then + echo "ERROR: File not found: $dtb" + exit 1 + fi + if [ "${deviceinfo_append_dtb}" = "true" ]; then + echo "==> kernel: appending device-tree ${deviceinfo_dtb}" + cat "$kernel" "$dtb" > "${kernel}-dtb" + else + echo "==> kernel: copying dtb ${deviceinfo_dtb} to boot partition" + cp "$dtb" "$(dirname "${outfile}")" + fi +} + +# Create the initramfs-extra archive +# $1: outfile +generate_initramfs_extra() +{ + echo "==> initramfs: creating $1" + + osk_conf="$(get_osk_config)" + if [ $? -eq 1 ]; then + echo "ERROR: Font specified in /etc/osk.conf does not exist!" + exit 1 + fi + + # Set up initramfs-extra in temp folder + tmpdir_extra=$(mktemp -d /tmp/mkinitfs.XXXXXX) + mkdir -p "$tmpdir_extra" + copy_files "$(get_binaries_extra)" "$tmpdir_extra" + copy_files "$osk_conf" "$tmpdir_extra" + create_cpio_image "$tmpdir_extra" "$1.new" + rm -rf "$tmpdir_extra" + + # Replace old initramfs-extra *after* we are done to make sure + # it does not become corrupted if something goes wrong. + mv "$1.new" "$1" +}