diff --git a/extensions/lowmem.sh b/extensions/lowmem.sh new file mode 100644 index 0000000000..c2344ff802 --- /dev/null +++ b/extensions/lowmem.sh @@ -0,0 +1,63 @@ +#!/usr/bin/env bash + +# +# Armbian Optimizations for Low-Memory Boards +# +# Boards with less than *256MB* RAM need special optimizations to run Armbian smoothly. +# This extension applies the necessary *userland* (not-kernel) optimizations +# at build time. +# + +function post_family_tweaks_bsp__copy_lowmem_config() { + display_alert "${EXTENSION}" "Installing default configuration" "debug" + + # Copy /etc/default/armbian-lowmem configuration file + # Allows user to customize swapfile size / location + if [ ! -f "$destination/etc/default/armbian-lowmem" ]; then + install -m 664 "$SRC/packages/bsp/armbian-lowmem/etc/default/armbian-lowmem.dpkg-dist" "$destination/etc/default/armbian-lowmem" + fi + + return 0 +} + +function post_family_tweaks_bsp__copy_lowmem_mkswap() { + local service_name="lowmem-mkswap" + # Devices with very low memory need a swapfile to operate smoothly (apt, locale-gen, etc) + display_alert "${EXTENSION}" "Installing ${service_name}.service" "debug" + + # Copy systemd service and script to create swapfile + install -m 755 "$SRC/packages/bsp/armbian-lowmem/${service_name}.sh" "$destination/usr/bin/${service_name}.sh" + install -m 644 "$SRC/packages/bsp/armbian-lowmem/${service_name}.service" "$destination/lib/systemd/system/${service_name}.service" + + return 0 +} + +function post_family_tweaks__enable_lowmem_mkswap() { + local service_name="lowmem-mkswap" + display_alert "${EXTENSION}" "Enabling ${service_name}.service" "debug" + chroot_sdcard systemctl enable "${service_name}.service" + + return 0 +} + +function pre_umount_final_image__memory_optimize_defaults() { + local LOWMEM_TMPFS_RUN_MB=${LOWMEM_TMPFS_RUN_MB:-20} + # Optimize /etc/default settings to reduce memory usage + display_alert "${EXTENSION}" "Disabling ramlog by default to save memory" "debug" + sed -i "s/^ENABLED=.*/ENABLED=false/" "${MOUNT}"/etc/default/armbian-ramlog + + display_alert "${EXTENSION}" "Disabling zram swap by default" "debug" + sed -i "s/^#\?\s*SWAP=.*/SWAP=false/" "${MOUNT}"/etc/default/armbian-zram-config + + # /run is 10% of RAM by default + # systemd throws errors when <16MB is *free* in this partition + # during daemon-reload operations. + # Address with a fixed /run size of ${LOWMEM_TMPFS_RUN_MB} + if ! grep -qE "tmpfs[[:space:]]+/run[[:space:]]+tmpfs" "${MOUNT}/etc/fstab"; then + # Skip if /run entry already exists in fstab (userpatches, etc) + display_alert "${EXTENSION}" "Fixing /run size in /etc/fstab" "debug" + echo "tmpfs /run tmpfs rw,nosuid,nodev,noexec,relatime,size=${LOWMEM_TMPFS_RUN_MB}M,mode=755 0 0" >> "${MOUNT}"/etc/fstab + fi + + return 0 +} diff --git a/packages/bsp/armbian-lowmem/etc/default/armbian-lowmem.dpkg-dist b/packages/bsp/armbian-lowmem/etc/default/armbian-lowmem.dpkg-dist new file mode 100644 index 0000000000..1303736df5 --- /dev/null +++ b/packages/bsp/armbian-lowmem/etc/default/armbian-lowmem.dpkg-dist @@ -0,0 +1,8 @@ +# configuration values for the armbian-lowmem extension +# intended for use by boards with <256MB RAM +# +# swapfile path +SWAPFILE_PATH=/swapfile +# +# size of swapfile to create in MiB +SWAPFILE_SIZE_MB=256 diff --git a/packages/bsp/armbian-lowmem/lowmem-mkswap.service b/packages/bsp/armbian-lowmem/lowmem-mkswap.service new file mode 100644 index 0000000000..58796bc6bb --- /dev/null +++ b/packages/bsp/armbian-lowmem/lowmem-mkswap.service @@ -0,0 +1,14 @@ +[Unit] +Description=Armbian lowmem: Create a swapfile +DefaultDependencies=no +Wants=armbian-resize-filesystem.service +After=armbian-resize-filesystem.service +Before=basic.target + +[Service] +Type=oneshot +ExecStart=/usr/bin/lowmem-mkswap.sh +RemainAfterExit=yes + +[Install] +WantedBy=basic.target diff --git a/packages/bsp/armbian-lowmem/lowmem-mkswap.sh b/packages/bsp/armbian-lowmem/lowmem-mkswap.sh new file mode 100755 index 0000000000..845a072b57 --- /dev/null +++ b/packages/bsp/armbian-lowmem/lowmem-mkswap.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +set -euo pipefail + +SWAPFILE_PATH="/swapfile" +SWAPFILE_SIZE_MB=256 + +[[ -f /etc/default/armbian-lowmem ]] && . /etc/default/armbian-lowmem + +echo "Creating swapfile of size ${SWAPFILE_SIZE_MB}MiB at ${SWAPFILE_PATH}" + +# Safety: do not overwrite existing swapfile +if [[ -f "${SWAPFILE_PATH}" ]]; then + echo "Swapfile ${SWAPFILE_PATH} already exists, not overwriting." >&2 + exit 0 +fi + +# Safety: ensure we have enough free space for the swapfile + headroom +SWAPFILE_BASE=$(dirname "${SWAPFILE_PATH}") +FREE_MB=$(df -Pm "${SWAPFILE_BASE}" | awk 'NR==2{print $4}') +NEEDED_MB=$(( SWAPFILE_SIZE_MB + 64 )) # 64MiB headroom +if (( FREE_MB < NEEDED_MB )); then + echo "Not enough free space in ${SWAPFILE_BASE} to create ${SWAPFILE_SIZE_MB}MiB swapfile." >&2 + exit 1 +fi + +# Create swapfile, set permissions, and enable it +fallocate -l "${SWAPFILE_SIZE_MB}M" "${SWAPFILE_PATH}" +chmod 600 "${SWAPFILE_PATH}" +mkswap "${SWAPFILE_PATH}" +# Add to fstab if not present +if ! grep -qE "^[[:space:]]+${SWAPFILE_PATH}[[:space:]]+swap[[:space:]]" /etc/fstab; then + echo "${SWAPFILE_PATH} swap swap defaults,nofail,discard=once,pri=0 0 0" >> /etc/fstab +fi + +swapon -p 0 "${SWAPFILE_PATH}"