From 9dc24840c3b719e8b1b341ccb042b9918dee89fc Mon Sep 17 00:00:00 2001 From: Ricardo Pardini Date: Fri, 27 Jan 2023 13:10:05 +0100 Subject: [PATCH] armbian-next: firmware-deb: reworked: Provides/Conflicts instead of Replaces; `cp` -> `git archive`; new firmware CLI; FULL version .deb out of tmpfs --- lib/functions/cli/cli-firmware.sh | 51 +++++++++++++++++++ lib/functions/cli/commands.sh | 3 +- .../compilation/packages/firmware-deb.sh | 51 ++++++++++++------- lib/library-functions.sh | 9 ++++ 4 files changed, 96 insertions(+), 18 deletions(-) create mode 100644 lib/functions/cli/cli-firmware.sh diff --git a/lib/functions/cli/cli-firmware.sh b/lib/functions/cli/cli-firmware.sh new file mode 100644 index 0000000000..1932c133e0 --- /dev/null +++ b/lib/functions/cli/cli-firmware.sh @@ -0,0 +1,51 @@ +function cli_firmware_pre_run() { + declare -g ARMBIAN_COMMAND_REQUIRE_BASIC_DEPS="yes" # Require prepare_host_basic to run before the command. + + # "gimme root on a Linux machine" + cli_standard_relaunch_docker_or_sudo +} + +function cli_firmware_run() { + + # configuration etc - it initializes the extension manager; handles its own logging sections. + prep_conf_main_only_firmware < /dev/null # no stdin for this, so it bombs if tries to be interactive. + + # Minimal config needed + declare -g -r BOARD_FIRMWARE_INSTALL="-full" # Build full firmware "too" + + # Fool the preparation step; firmware is arch agnostic. + declare -g -r ARCH=arm64 + + # default build, but only invoke specific rootfs functions needed. It has its own logging sections. + do_with_default_build cli_firmware_only_in_default_build < /dev/null # no stdin for this, so it bombs if tries to be interactive. + + #reset_uid_owner "${BUILT_ROOTFS_CACHE_FILE}" + + display_alert "Firmware build complete" "fake" "info" +} + +# This is run inside do_with_default_build(), above. +function cli_firmware_only_in_default_build() { + github_actions_add_output firmware_version "fake" + + compile_firmware_light_and_possibly_full +} + +# Lean version, for building rootfs, that doesn't need BOARD/BOARDFAMILY; never interactive. +function prep_conf_main_only_firmware() { + LOG_SECTION="config_early_init" do_with_conditional_logging config_early_init + + check_basic_host + + LOG_SECTION="config_pre_main" do_with_conditional_logging config_pre_main + + allow_no_family="yes" \ + LOG_SECTION="do_main_configuration" do_with_conditional_logging do_main_configuration # This initializes the extension manager among a lot of other things, and call extension_prepare_config() hook + + LOG_SECTION="do_extra_configuration" do_with_conditional_logging do_extra_configuration + + skip_kernel="yes" \ + LOG_SECTION="config_post_main" do_with_conditional_logging config_post_main + + display_alert "Configuration prepared for non-BOARD build" "prep_conf_main_only_rootfs" "info" +} diff --git a/lib/functions/cli/commands.sh b/lib/functions/cli/commands.sh index c0e6763d27..e6b9c879ac 100644 --- a/lib/functions/cli/commands.sh +++ b/lib/functions/cli/commands.sh @@ -22,7 +22,8 @@ function armbian_register_commands() { ["build"]="standard_build" # implemented in cli_standard_build_pre_run and cli_standard_build_run ["distccd"]="distccd" # implemented in cli_distccd_pre_run and cli_distccd_run - ["rootfs"]="rootfs" # implemented in cli_rootfs_pre_run and cli_rootfs_run + ["rootfs"]="rootfs" # implemented in cli_rootfs_pre_run and cli_rootfs_run + ["firmware"]="firmware" # yeah this is getting old. implemented in cli_firmware_pre_run and cli_firmware_run # shortcuts, see vars set below. the use legacy single build, and try to control it via variables ["kernel"]="standard_build" diff --git a/lib/functions/compilation/packages/firmware-deb.sh b/lib/functions/compilation/packages/firmware-deb.sh index 0ac6d7be80..8b060ecfb9 100644 --- a/lib/functions/compilation/packages/firmware-deb.sh +++ b/lib/functions/compilation/packages/firmware-deb.sh @@ -29,25 +29,36 @@ function compile_firmware() { local ARMBIAN_FIRMWARE_GIT_BRANCH="${ARMBIAN_FIRMWARE_GIT_BRANCH:-"master"}" # Fetch Armbian firmware from git. - fetch_from_repo "${ARMBIAN_FIRMWARE_GIT_SOURCE}" "armbian-firmware-git" "branch:${ARMBIAN_FIRMWARE_GIT_BRANCH}" + declare fetched_revision + do_checkout="no" fetch_from_repo "${ARMBIAN_FIRMWARE_GIT_SOURCE}" "armbian-firmware-git" "branch:${ARMBIAN_FIRMWARE_GIT_BRANCH}" + declare -r armbian_firmware_git_sha1="${fetched_revision}" + declare extra_conflicts_comma="" if [[ -n $FULL ]]; then - # Fetch kernel firmware from git. This is huge... - fetch_from_repo "$MAINLINE_FIRMWARE_SOURCE" "linux-firmware-git" "branch:main" + # Fetch kernel firmware from git. This is large, but we don't have two copies of it anymore. So more manageable. + declare fetched_revision + do_checkout="no" fetch_from_repo "$MAINLINE_FIRMWARE_SOURCE" "linux-firmware-git" "branch:main" + declare -r mainline_firmware_git_sha1="${fetched_revision}" - # @TODO: rpardini: what is this thing with hardlinks? why? - # cp : create hardlinks - run_host_command_logged cp -af --reflink=auto "${SRC}/cache/sources/linux-firmware-git/*" "${fw_temp_dir}/${fw_dir}/lib/firmware/" + # use git archive to export the ${mainline_firmware_git_sha1} revision into "${fw_temp_dir}/${fw_dir}/lib/firmware/" + run_host_command_logged git -C "${SRC}/cache/sources/linux-firmware-git" archive --format=tar "${mainline_firmware_git_sha1}" "|" tar -C "${fw_temp_dir}/${fw_dir}/lib/firmware/" -xf - + + # Full version conflicts with more stuff, of course. + extra_conflicts_comma=",amd64-microcode,intel-microcode" + + # @TODO: rpardini: disabled, this is not the place to do this; move to extension/bsp/whatever # cp : create hardlinks for ath11k WCN685x hw2.1 firmware since they are using the same firmware with hw2.0 - run_host_command_logged cp -af --reflink=auto "${fw_temp_dir}/${fw_dir}/lib/firmware/ath11k/WCN6855/hw2.0/" "${fw_temp_dir}/${fw_dir}/lib/firmware/ath11k/WCN6855/hw2.1/" - - rm -rf "${fw_temp_dir}/${fw_dir}"/lib/firmware/.git # @TODO: would have been better not to waste I/O putting in there to begin with. + # run_host_command_logged cp -af --reflink=auto "${fw_temp_dir}/${fw_dir}/lib/firmware/ath11k/WCN6855/hw2.0/" "${fw_temp_dir}/${fw_dir}/lib/firmware/ath11k/WCN6855/hw2.1/" fi - # overlay Armbian's firmware on top of the mainline firmware - run_host_command_logged cp -af --reflink=auto "${SRC}/cache/sources/armbian-firmware-git/*" "${fw_temp_dir}/${fw_dir}/lib/firmware/" + # Armbian firmware; this overwrites anything in the mainline firmware repo (if that was included, in the full version only) + run_host_command_logged git -C "${SRC}/cache/sources/armbian-firmware-git" archive --format=tar "${armbian_firmware_git_sha1}" "|" tar -C "${fw_temp_dir}/${fw_dir}/lib/firmware/" -xf - + + # Show the size of the firmware directory in a tree if debugging + if [[ "${SHOW_DEBUG}" == "yes" ]]; then + run_host_command_logged tree -C --du -h -L 1 "${fw_temp_dir}/${fw_dir}"/lib/firmware "|| true" # do not fail + fi - rm -rf "${fw_temp_dir}/${fw_dir}"/lib/firmware/.git # @TODO: would have been better not to waste I/O putting in there to begin with. cd "${fw_temp_dir}/${fw_dir}" || exit_with_error "can't change directory" # set up control file @@ -59,7 +70,8 @@ function compile_firmware() { Architecture: all Maintainer: $MAINTAINER <$MAINTAINERMAIL> Installed-Size: 1 - Replaces: linux-firmware, firmware-brcm80211, firmware-ralink, firmware-samsung, firmware-realtek, armbian-firmware${REPLACE} + Conflicts: linux-firmware, firmware-brcm80211, firmware-ralink, firmware-samsung, firmware-realtek, armbian-firmware${REPLACE}${extra_conflicts_comma} + Provides: linux-firmware, firmware-brcm80211, firmware-ralink, firmware-samsung, firmware-realtek, armbian-firmware${REPLACE}${extra_conflicts_comma} Section: kernel Priority: optional Description: Armbian - Linux firmware${FULL} @@ -70,10 +82,15 @@ function compile_firmware() { # package run_host_command_logged mv -v "armbian-firmware${FULL}" "armbian-firmware${FULL}_${REVISION}_all" display_alert "Building firmware package" "armbian-firmware${FULL}_${REVISION}_all" "info" - fakeroot_dpkg_deb_build "armbian-firmware${FULL}_${REVISION}_all" - run_host_command_logged mv -v "armbian-firmware${FULL}_${REVISION}_all" "armbian-firmware${FULL}" - run_host_command_logged rsync -rq "armbian-firmware${FULL}_${REVISION}_all.deb" "${DEB_STORAGE}/" + if [[ -n $FULL ]]; then + display_alert "Full firmware, very big, avoiding tmpfs" "armbian-firmware${FULL}_${REVISION}_all" "info" + fakeroot_dpkg_deb_build "armbian-firmware${FULL}_${REVISION}_all" "${DEB_STORAGE}" + else + fakeroot_dpkg_deb_build "armbian-firmware${FULL}_${REVISION}_all" + run_host_command_logged mv -v "armbian-firmware${FULL}_${REVISION}_all" "armbian-firmware${FULL}" + run_host_command_logged rsync -rq "armbian-firmware${FULL}_${REVISION}_all.deb" "${DEB_STORAGE}/" + fi - done_with_temp_dir "${cleanup_id}" # changes cwd to "${SRC}" and fires the cleanup function early + done_with_temp_dir "${cleanup_id}" # changes cwd to "${SRC}" and fires the cleanup function early } diff --git a/lib/library-functions.sh b/lib/library-functions.sh index e1e2ee61ff..5807ba9862 100644 --- a/lib/library-functions.sh +++ b/lib/library-functions.sh @@ -64,6 +64,15 @@ set -o errexit ## set -e : exit the script if any statement returns a non-true # shellcheck source=lib/functions/cli/cli-docker.sh source "${SRC}"/lib/functions/cli/cli-docker.sh +# no errors tolerated. invoked before each sourced file to make sure. +#set -o pipefail # trace ERR through pipes - will be enabled "soon" +#set -o nounset ## set -u : exit the script if you try to use an uninitialised variable - one day will be enabled +set -o errtrace # trace ERR through - enabled +set -o errexit ## set -e : exit the script if any statement returns a non-true return value - enabled +### lib/functions/cli/cli-firmware.sh +# shellcheck source=lib/functions/cli/cli-firmware.sh +source "${SRC}"/lib/functions/cli/cli-firmware.sh + # no errors tolerated. invoked before each sourced file to make sure. #set -o pipefail # trace ERR through pipes - will be enabled "soon" #set -o nounset ## set -u : exit the script if you try to use an uninitialised variable - one day will be enabled