mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
extensions framework + UEFI aarch64/x86 + rpi4b + core changes/fixes (#3300)
* extensions framework (née "fragments")
- this should actually change nothing at this point, just add capabilities
- the framework is implemented in lib/extensions.sh
- the "if function x exists then call x" replaced with call_extension_method()
- +inline documentation
- +compatibility names
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* extensions framework; meta-extensions: auto-docs and sample extension gen
- 2 extensions dealing with extensibility itself
- detect-unused-extensions: shows which extensions are enabled, but never called.
- gen-sample-extension-docs: generates a sample empty extension & Markdown documentation for extensions
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* new extension methods and features via config variables in core Armbian
- `SKIP_EXTERNAL_TOOLCHAINS=yes` - does not download or use any linaro toolchains, only build host-installed ones
- `SKIP_BOOTSPLASH=yes` - does not patch kernel for splash file
- `EXTRA_BSP_NAME=xyz` - allows for BSP variants, useful for when extensions modify the BSP
- `EXTRA_ROOTFS_MIB_SIZE=x` - add x mib's to rootfs size, for use with very small images
- `KERNEL_EXTRA_TARGETS` - what extra targets to make kernel for, default to "modules dtbs"
- `BOOTCONFIG=none` - does not build nor install u-boot; also doesn't handle bootscripts et al
- `unset KERNELSOURCE` - does not build nor install kernel, nor build initrd, nor build nor install firmware
- `ARMHF_ARCH=skip` - does not add armhf to apt/dpkg, thus pure arm64
- `SKIP_ARMBIAN_REPO=yes` - results in armbian.list.disabled in the final image
- define `APT_EXTRA_DIST_PARAMS` with apt-cacher-ng options and use it for `PACKAGE_LIST_INSTALL/REMOVE` et al
- initial support for targeting x86/amd64 UEFI and BIOS
- some do's/don'ts for x86/amd64, like a different `UBUNTU_MIRROR` default
- GPT/EFI(ESP) partitions (fat, `UEFISIZE=256` to enable, mount `UEFI_MOUNT_POINT=/boot/efi`, first on disk but ends
up at `$uefipart`=15)
- GPT/BIOS partitions (fat, `BIOSSIZE=1` to enable, second on disk but ends up at partition 14)
- `UEFI_FS_LABEL="armbiefi"` - to set the FAT label for the EFI partition, visible in Win/Mac
- hard-requires gdisk package host-side
- add add_host_dependencies() extension method; fill `EXTRA_BUILD_DEPS="pkg pkg2"` to install to host before toolchains
download
- add pre_prepare_partitions() extension method, for custom partition size calculations
- add create_partition_table() extension method, used to do full-custom partitioning if `USE_HOOK_FOR_PARTITION=yes`
- add post_create_partitions() extension method, mostly for easy debugging
- add post_write_sdcard() extension method, where you can also set `SKIP_VERIFY=yes` to skip sdcard verification
- add post_install_kernel_debs() extension method.
- multiple fixes to bsp to avoid spurious errors when files are not where it expects
- v4: detect `update-initramfs` failure and abort build with useful message if it does
- v4: show useful stacktrace in `exit_with_error`
- if `ERROR_DEBUG_SHELL=yes`, drop into a shell before unmounting/deleting everything, so we can inspect what went wrong
- v4: display a message before `apt-get remove PACKAGE_LIST_BOARD_REMOVE` packages, so any errors while removing are easy to understand
- v4: preserve kernel .config's dates when copying
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* extensions framework; refactor tool fetching/building into extensions
- a few examples of core refactoring using extensions
- sunxi-tools extension, enabled by 2 different sunxi family includes ("reuse" example)
- marvel-tools extension, enabled by 2 different mvebu family includes
- rkbin-tools extension, enabled by rockship64_common family include
- amlogic-fip/c2-blobs stuff refactored directly into meson64_common.inc ("single-use" example)
- removed the 'testings' fetch_from_repo completely since not used anywhere.
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* .wip's for UEFI arm64 and UEFI/BIOS x86 via new GRUB extension
- v3: added `growroot`-awareness to `armbian-resize-filesystem`
- the partition-growing part of `armbian-resize-filesystem` does not deal correctly with the UEFI layout
- `growroot` is installed on UEFI images by default, that handles growing partition during initramfs
- now `armbian-resize-filesystem` handles `resize2fs` only, and works.
- v4: reworked UEFI board/family/include structure:
- use Distro's `linux-generic` kernel only for `current`
- `edge` now builds it's own pure-mainline `5.15.y` kernel, for both x86 and arm64
- `.config` taken from Ubuntu, probably needs tuning for EXTRAWIFI=yes et al
- v4: introduce `SKIP_KERNEL_SYMLINK=yes`, tested in `builddeb`
- to avoid symlinking kernel; u-boot likes it, but grub and flash-kernel hates it
- v5: many fixes
- v7: more small fixes.
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* .wip for the RaspberryPi 4B via new flash-kernel extension
- this does not build it's own kernel "yet", but uses default linux-raspi kernel from Ubuntu
- flash-kernel is not really a bootloader
- it just prepares kernel et al a FAT partition for booting by the RPi4b bootloader
- flash-kernel is standard Debian package, but has only been tested on Ubuntu releases
- it is really only known-working since Hirsute release.
- Debian's rpi kernel is armhf only, so out of scope here, at least until we add source-built kernels.
- v3: fixed focal rootfs build. untested.
- v3: better variable names, preparing for source-built kernel.
- v5: new edge build with pure mainline kernel.
- v6: many fixes and some hacks for packaging and layout, also firmware (using Ubuntu's)
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* Added first patch to edge x86 related to wifi drivers
* extensions: leave hostapd alone; remove hackish ext; block reentrancy
- package-list-utils does not belong in this PR
- grub or bcm2711 is not the place to remove hostapd
- block recursive enable_extension() calls, for now.
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* gen-sample-extension-docs: fix: avoid counter in generated sample
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* extensions: dependencies: enable_extension() in extensions with a stack
- and better stacktraces, I hope
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* Remove code from package list since we don't have it in repository
Adjust kernel config to disable driver that needs further polishing.
* Allow amd64 to build the same desktops as aarch64. We only have this limit for armhf, where some desktops don't work
* amd64: allow building amd64 on aarch64 with system toolchain
- conditionally add gcc-x86-64-linux-gnu to hostdeps
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* add libelf-dev directly to hostdeps (and Dockerfile), remove extension
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* packaging: remove SKIP_KERNEL_SYMLINK hack, fix the root cause
- which was the missing $image_name for non-arm64 & non-arm, so: x86 for example
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* grub: really obliterate u-boot stuff from BSP
- for now. soon we'll refactor u-boot so not have to do this
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* flash-kernel: really obliterate u-boot stuff from BSP
- for now. soon we'll refactor u-boot so not have to do this
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* extensions: add host_dependencies_ready() hook
- this passes FINAL_HOST_DEPS containing all hostdeps for the run after they're installed
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* Add verification functions for correct selection.
* If UEFI Skip symlink creation
* Do not create dtb package for amd64
* Skip scripts folder cleaning if build process native.
Skip creating postinst prerm scripts for headers.
* Skip applying headers-debian-byteshift.patch if build native
* Fix architecture syntax as x86_64
* Revert "amd64: allow building amd64 on aarch64 with system toolchain"
This reverts commit 0c5ee20bb1.
* Compare architectures before starting compilation.
Signed-off-by: The-going <48602507+The-going@users.noreply.github.com>
* extensions: cleanups after fixes by the-Going
- packaging:
- there is _no need_ anymore for the symlink hack, CONFIG_EFI or no. But check is great, see below
- it's not `amd64` that has no DTB's, it's all UEFI, thus: `is_enabled CONFIG_EFI`, thanks!
- Explicitly disallow "reverse cross compile" in amd64.conf.
- whitespace-only-deletions: revert. we shall shellfmt the whole thing one day, but not today.
- fix a few syntax warnings in newly introduced code (floating `$ARCH` vs `"${ARCH}`) - blame shellcheck
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* packaging: fix: turns out a lot of boards have CONFIG_EFI=y, can't use that for dtb/no-dtb decision.
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* grub: remove debug
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* firmware: allow installing `armbian-firmware-full`; make it really full
- can now use `BOARD_FIRMWARE_INSTALL="-full"` to install full firmware for the board. enable for UEFI.
- don't rely on KERNELSOURCE for firmware-related decisions. introduce `INSTALL_ARMBIAN_FIRMWARE` which defaults to `yes`
- rpi4b/flash-kernel: disable Armbian firmware; we need linux-firmware-raspi2, which conflicts.
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* extensions: log to /${LOG_SUBPATH}/ instead of fixed /debug/
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* extensions: introduce cleanup_extension_manager() called by build-all-ng's unset_all()
- to reset/unset everything done by the the initializer, so build can run again
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* extensions: remove 'global' logging, for use with build_all_ng
- enable_extensions() will have to live on without logging to file. it's just too early.
- now init EXTENSION_MANAGER_TMP_DIR in initialize_extension_manager()
- now init EXTENSION_MANAGER_LOG_FILE in initialize_extension_manager()
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* extensions: build-all-ng.sh bugfix due to extension's debug to stdout
- extensions (among other things) can produce output to stdout when activated
- fix: check_hash() produced "idential" (sic, now changed to IDENTICAL) to stdout as a trigger
- debugging output got mixed with "idential", rendering hash cache void for families that used extensions
- eg: sunxi, others
- fix is to send stdout to the bitbucket when sourcing the board & arch config files
- proper fix would be stop using stdout in this case and use return code for check_hash()
- one day soon
Signed-off-by: Ricardo Pardini <ricardo@pardini.net>
* Add CI build targets
Co-authored-by: Igor Pecovnik <igor.pecovnik@gmail.com>
Co-authored-by: The-going <48602507+The-going@users.noreply.github.com>
This commit is contained in:
@@ -269,6 +269,11 @@ fi
|
||||
|
||||
CONFIG_PATH=$(dirname "${CONFIG_FILE}")
|
||||
|
||||
# Source the extensions manager library at this point, before sourcing the config.
|
||||
# This allows early calls to enable_extension(), but initialization proper is done later.
|
||||
# shellcheck source=lib/extensions.sh
|
||||
source "${SRC}"/lib/extensions.sh
|
||||
|
||||
display_alert "Using config file" "${CONFIG_FILE}" "info"
|
||||
pushd "${CONFIG_PATH}" > /dev/null || exit
|
||||
# shellcheck source=/dev/null
|
||||
|
||||
38
config/boards/rpi4b.wip
Normal file
38
config/boards/rpi4b.wip
Normal file
@@ -0,0 +1,38 @@
|
||||
# Broadcom BCM2711 quad core 1-8Gb RAM SoC USB3 GBE USB-C WiFi/BT
|
||||
export BOARD_NAME="Raspberry Pi 4"
|
||||
export BOARDFAMILY="bcm2711"
|
||||
export KERNEL_TARGET="current,edge"
|
||||
export FK__MACHINE_MODEL="Raspberry Pi 4 Model B" # flash kernel (FK) configuration
|
||||
|
||||
# configure stuff at the appropriate time in flash-kernel
|
||||
pre_initramfs_flash_kernel__write_raspi_config() {
|
||||
# for serial console, there is also 'BOOT_UART=1' in 'rpi-eeprom-config' but that is for an earlier stage.
|
||||
# look at with it rpi-eeprom-config, change with 'EDITOR=nano rpi-eeprom-config --edit'
|
||||
cat <<-EOD >"${FIRMWARE_DIR}/config.txt"
|
||||
[pi4]
|
||||
max_framebuffers=2
|
||||
|
||||
[all]
|
||||
kernel=vmlinuz
|
||||
cmdline=cmdline.txt
|
||||
initramfs initrd.img followkernel
|
||||
disable_overscan=1
|
||||
hdmi_drive=2
|
||||
arm_64bit=1
|
||||
|
||||
# bootloader logs to serial, second stage
|
||||
# enable_uart=1
|
||||
|
||||
# overclock. requires decent thermals. COMMENT OUT IF DON'T USE A GREAT COOLER OR HEATSINK.
|
||||
over_voltage=6
|
||||
arm_freq=2000
|
||||
|
||||
# uncomment to disable wifi or bt.
|
||||
#dtoverlay=disable-wifi
|
||||
#dtoverlay=disable-bt
|
||||
|
||||
# gpu and 3d stuff.
|
||||
gpu_mem=256
|
||||
dtoverlay=vc4-fkms-v3d
|
||||
EOD
|
||||
}
|
||||
4
config/boards/uefi-arm64.wip
Normal file
4
config/boards/uefi-arm64.wip
Normal file
@@ -0,0 +1,4 @@
|
||||
# aarch64 via UEFI for all UEFI-enabled boards
|
||||
export BOARD_NAME="uefi-arm64"
|
||||
export BOARDFAMILY="uefi-arm64"
|
||||
export KERNEL_TARGET="current,edge"
|
||||
4
config/boards/uefi-x86.wip
Normal file
4
config/boards/uefi-x86.wip
Normal file
@@ -0,0 +1,4 @@
|
||||
# x86_64 via UEFI/BIOS for all boards
|
||||
export BOARD_NAME="uefi-x86"
|
||||
export BOARDFAMILY="uefi-x86"
|
||||
export KERNEL_TARGET="current,edge"
|
||||
@@ -1,4 +1,3 @@
|
||||
code
|
||||
emacs
|
||||
geany
|
||||
vim
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
@@ -1 +1 @@
|
||||
arm64
|
||||
arm64, amd64
|
||||
|
||||
10123
config/kernel/linux-bcm2711-edge.config
Normal file
10123
config/kernel/linux-bcm2711-edge.config
Normal file
File diff suppressed because it is too large
Load Diff
12598
config/kernel/linux-uefi-arm64-edge.config
Normal file
12598
config/kernel/linux-uefi-arm64-edge.config
Normal file
File diff suppressed because it is too large
Load Diff
10952
config/kernel/linux-uefi-x86-edge.config
Normal file
10952
config/kernel/linux-uefi-x86-edge.config
Normal file
File diff suppressed because it is too large
Load Diff
19
config/sources/amd64.conf
Normal file
19
config/sources/amd64.conf
Normal file
@@ -0,0 +1,19 @@
|
||||
export ARCH=amd64 # Debian name $(dpkg-architecture -qDEB_HOST_ARCH)
|
||||
export ARCHITECTURE=x86_64 # "kernel" arch
|
||||
export QEMU_BINARY="qemu-x86_64-static" # Hopefully you have this installed.
|
||||
export KERNEL_COMPILER=' ' # hack: use single space for host gcc. won't work on arm64 hosts
|
||||
export KERNEL_USE_GCC=' ' # more hacks.
|
||||
export KERNEL_IMAGE_TYPE="bzImage" # Ubuntu Standard
|
||||
export KERNEL_EXTRA_TARGETS="modules" # default is "modules dtb" but x86_64 has no DTB
|
||||
#export INITRD_ARCH=amd64 # Used by u-boot for mkimage in initramfs. No u-boot for x86 yet.
|
||||
|
||||
export UBOOT_USE_GCC="none" # required by configuration.sh
|
||||
|
||||
# Default to mainline
|
||||
[[ -z $KERNELSOURCE ]] && KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
|
||||
|
||||
if [[ "$(uname -m)" == "aarch64" ]]; then
|
||||
# Explicitly disallow "reverse cross-compile". Go ask @the-Going why ;-)
|
||||
display_error "Unsupported cross-compile" "aarch64 -> x86_64" "err"
|
||||
exit 39
|
||||
fi
|
||||
@@ -46,3 +46,7 @@ fi
|
||||
[[ -z $KERNELDIR ]] && KERNELDIR=$MAINLINE_KERNEL_DIR
|
||||
[[ -z $KERNELSOURCE ]] && KERNELSOURCE=$MAINLINE_KERNEL_SOURCE
|
||||
[[ -z $KERNELBRANCH ]] && KERNELBRANCH='branch:linux-5.4.y'
|
||||
|
||||
## System toolchains don't have the -none- variant, remove it
|
||||
[[ "${SKIP_EXTERNAL_TOOLCHAINS}" == "yes" ]] && [[ "${UBOOT_COMPILER}" = *none* ]] && UBOOT_COMPILER="${UBOOT_COMPILER//-none-/-}"
|
||||
[[ "${SKIP_EXTERNAL_TOOLCHAINS}" == "yes" ]] && [[ "${ATF_COMPILER}" = *none* ]] && ATF_COMPILER="${ATF_COMPILER//-none-/-}"
|
||||
|
||||
88
config/sources/families/bcm2711.conf
Normal file
88
config/sources/families/bcm2711.conf
Normal file
@@ -0,0 +1,88 @@
|
||||
enable_extension "flash-kernel"
|
||||
export LINUXFAMILY=bcm2711
|
||||
export ARCH=arm64
|
||||
export UEFI_FS_LABEL="rpicfg" # Windows/Mac users will see this if they mount the SD card. Configurable
|
||||
export SKIP_BOOTSPLASH="yes" # video is init-ed before us
|
||||
export KERNELDIR='linux-rpi' # Avoid sharing a source tree with others, until we know it's safe.
|
||||
export FK__PUBLISHED_KERNEL_VERSION="raspi" # flash kernel (FK) configuration
|
||||
export FK__KERNEL_PACKAGES=""
|
||||
export RASPI_ROOT_FS_LABEL="armbian"
|
||||
|
||||
case "${BRANCH}" in
|
||||
|
||||
current)
|
||||
export RASPI_DISTRO_KERNEL=yes # This will cause board to include distro's prebuilt kernel, not from source
|
||||
;;
|
||||
|
||||
edge)
|
||||
export RASPI_DISTRO_KERNEL=no
|
||||
export KERNELBRANCH="branch:linux-5.15.y"
|
||||
export KERNELPATCHDIR="${LINUXFAMILY}-${BRANCH}"
|
||||
export LINUXCONFIG="linux-${LINUXFAMILY}-${BRANCH}"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Add a label to the root partition - this is common, should refactor into a separate segment
|
||||
prepare_partitions_custom__add_rootfs_raspi_label_to_mkfs() {
|
||||
display_alert "raspi rootfs label ${RASPI_ROOT_FS_LABEL}" "boot with root=LABEL=${RASPI_ROOT_FS_LABEL}" "info"
|
||||
mkopts[ext4]="-L ${RASPI_ROOT_FS_LABEL} ${mkopts[ext4]}"
|
||||
}
|
||||
|
||||
pre_initramfs_flash_kernel__write_raspi_cmdline() {
|
||||
cat <<-EOD >"${FIRMWARE_DIR}/cmdline.txt"
|
||||
root=LABEL=${RASPI_ROOT_FS_LABEL} rootfstype=ext4 elevator=deadline rootwait fixrtc cgroup_enable=memory cgroup_memory=1 console=tty1
|
||||
EOD
|
||||
}
|
||||
|
||||
pre_flash_kernel__symlink_dtb_and_kernel() {
|
||||
if [[ "${RASPI_DISTRO_KERNEL}" != "yes" ]]; then # and firmware.
|
||||
display_alert "Preparing DTBs and Kernel..." "bcm2711" "info"
|
||||
mkdir -p "${MOUNT}"/etc/flash-kernel/dtbs
|
||||
|
||||
cat <<-EOD >>"${MOUNT}"/etc/flash-kernel/db
|
||||
# Armbian kernels have a different flavour than expected.
|
||||
Machine: ${FK__MACHINE_MODEL}
|
||||
Kernel-Flavors: any
|
||||
EOD
|
||||
|
||||
## @TODO: rpardini: a horrible hack. I'll sort this out together with overlays, later.
|
||||
local oneDTB dtbBase
|
||||
for oneDTB in "${MOUNT}"/boot/dtb/broadcom/*.dtb; do
|
||||
dtbBase=$(basename "${oneDTB}")
|
||||
cp "${MOUNT}"/boot/dtb/broadcom/"${dtbBase}" "${MOUNT}"/etc/flash-kernel/dtbs/"${dtbBase}"
|
||||
done
|
||||
|
||||
rm -rf "${MOUNT}"/boot/dtb* || true
|
||||
|
||||
# @TODO: rpardini: packaging could maybe already use the correct names? I can't figure out how.
|
||||
ln -s ./Image "${MOUNT}"/boot/vmlinuz
|
||||
ln -s ./Image "${MOUNT}"/boot/vmlinuz-
|
||||
fi
|
||||
}
|
||||
|
||||
extension_prepare_config__prepare_rpi_flash_kernel() {
|
||||
display_alert "Preparing bcm2711" "${RELEASE}, distro kernel?: ${RASPI_DISTRO_KERNEL}" "info"
|
||||
export RASPI_DISTRO_KERNEL="${RASPI_DISTRO_KERNEL:-no}" # Include a distro-built kernel?
|
||||
export SERIALCON="${RASPI_SERIALCON:-tty1}" # HDMI etc, not serial. most people don't have UART on rpi
|
||||
local usable_releases="focal|hirsute|impish|jammy"
|
||||
|
||||
if [[ "$RELEASE" =~ ^(${usable_releases})$ ]]; then
|
||||
export FK__EXTRA_PACKAGES="rpi-eeprom linux-firmware linux-firmware-raspi2 libraspberrypi-bin cloud-initramfs-growroot"
|
||||
|
||||
if [[ "$RELEASE" =~ ^(hirsute|impish|jammy)$ ]]; then # Add raspi-config for those releases that have it; it might be useful.
|
||||
export FK__EXTRA_PACKAGES="${FK__EXTRA_PACKAGES} raspi-config"
|
||||
fi
|
||||
|
||||
if [[ "${RASPI_DISTRO_KERNEL}" == "yes" ]]; then # and firmware.
|
||||
unset KERNELSOURCE # Make sure Armbian will not try to compile from source.
|
||||
export FK__KERNEL_PACKAGES="${FK__KERNEL_PACKAGES} linux-tools-raspi linux-raspi linux-image-raspi "
|
||||
# Ubuntu Impish+ split the kernel modules, add the extra ones too.
|
||||
if [[ "$RELEASE" =~ ^(impish|jammy)$ ]]; then
|
||||
export FK__KERNEL_PACKAGES="${FK__KERNEL_PACKAGES} linux-modules-extra-raspi"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
display_alert "Can't use release for ${BOARD}. Try: ${usable_releases}" "${RELEASE}" "err"
|
||||
exit 27
|
||||
fi
|
||||
}
|
||||
@@ -311,3 +311,11 @@ family_tweaks_bsp()
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# This is an extension method, put directly in meson64_common. A "built-in" extension if you will.
|
||||
# If used in more than one place, it could be moved to an extension: enable_extension "amlogic-fip-tools"
|
||||
function fetch_sources_tools__amlogic_fip() {
|
||||
fetch_from_repo "https://github.com/armbian/odroidc2-blobs" "odroidc2-blobs" "branch:master"
|
||||
fetch_from_repo "https://github.com/LibreELEC/amlogic-boot-fip" "amlogic-boot-fip" "branch:master"
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
enable_extension "rkbin-tools"
|
||||
ARCH=arm64
|
||||
KERNEL_IMAGE_TYPE=Image
|
||||
OFFSET=16
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
enable_extension "sunxi-tools"
|
||||
ARCH=arm64
|
||||
ATF_TARGET_MAP="PLAT=$ATF_PLAT DEBUG=1 bl31;;build/$ATF_PLAT/debug/bl31.bin"
|
||||
BOOTDELAY=1
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
enable_extension "sunxi-tools"
|
||||
ARCH=armhf
|
||||
BOOTDELAY=1
|
||||
BOOTPATCHDIR='u-boot-sunxi'
|
||||
|
||||
21
config/sources/families/include/uefi_common.inc
Normal file
21
config/sources/families/include/uefi_common.inc
Normal file
@@ -0,0 +1,21 @@
|
||||
enable_extension "grub"
|
||||
export SERIALCON="tty1" # Cant reasonably expect UEFI stuff to have a serial console. Customize if otherwise.
|
||||
export SKIP_BOOTSPLASH="yes" # No splash.
|
||||
export UEFI_GRUB_TIMEOUT=${UEFI_GRUB_TIMEOUT:-1} # Default 1-second timeout for GRUB menu.
|
||||
export BOARD_FIRMWARE_INSTALL="-full" # Install full firmware for UEFI boards
|
||||
case "${BRANCH}" in
|
||||
|
||||
current)
|
||||
# This will force `unset KERNELSOURCE` later; no kernel will be built.
|
||||
# Instead, the distro's default linux-generic kernel will be installed.
|
||||
export DISTRO_GENERIC_KERNEL=yes
|
||||
;;
|
||||
|
||||
edge)
|
||||
export DISTRO_GENERIC_KERNEL=no
|
||||
export LINUXCONFIG="linux-uefi-${LINUXFAMILY}-${BRANCH}"
|
||||
export KERNELBRANCH="branch:linux-5.15.y"
|
||||
export KERNELPATCHDIR="uefi-${LINUXFAMILY}-${BRANCH}" # Might be empty.
|
||||
export KERNELDIR="linux-uefi-${LINUXFAMILY}" # Avoid sharing a source tree with others, until we know it's safe.
|
||||
;;
|
||||
esac
|
||||
@@ -1,3 +1,4 @@
|
||||
enable_extension "marvell-tools"
|
||||
ARCH=armhf
|
||||
if [[ $BOARD == helios4 ]]; then
|
||||
source "${BASH_SOURCE%/*}/include/mvebu-helios4.inc"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
enable_extension "marvell-tools"
|
||||
ARCH=arm64
|
||||
BOOTBRANCH='branch:v2021.01'
|
||||
BOOTENV_FILE='mvebu64.txt'
|
||||
|
||||
4
config/sources/families/uefi-arm64.conf
Normal file
4
config/sources/families/uefi-arm64.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
# Important: LINUXFAMILY and ARCH are defined _before_ including the common family include
|
||||
export LINUXFAMILY="arm64"
|
||||
export ARCH="arm64"
|
||||
source "${BASH_SOURCE%/*}/include/uefi_common.inc"
|
||||
4
config/sources/families/uefi-x86.conf
Normal file
4
config/sources/families/uefi-x86.conf
Normal file
@@ -0,0 +1,4 @@
|
||||
# Important: LINUXFAMILY and ARCH are defined _before_ including the common family include
|
||||
export LINUXFAMILY="x86"
|
||||
export ARCH="amd64"
|
||||
source "${BASH_SOURCE%/*}/include/uefi_common.inc"
|
||||
@@ -66,5 +66,17 @@ rk322x-box edge jammy cli
|
||||
rock-3a legacy jammy cli beta yes
|
||||
|
||||
|
||||
# Raspberry Pi4
|
||||
rpi4b edge jammy cli beta yes
|
||||
|
||||
|
||||
# uefi-x86
|
||||
uefi-x86 edge jammy cli beta yes
|
||||
|
||||
|
||||
# uefi-arm64
|
||||
uefi-arm64 edge jammy cli beta yes
|
||||
|
||||
|
||||
# Virtual qemu
|
||||
virtual-qemu current jammy cli beta yes
|
||||
|
||||
@@ -25,7 +25,21 @@ orangepi3 edge jammy desktop beta
|
||||
orangepi4 edge jammy desktop beta yes xfce config_base 3dsupport,browsers
|
||||
|
||||
|
||||
# Raspberry Pi4
|
||||
rpi4b edge jammy desktop beta yes xfce config_base 3dsupport,browsers,chat,desktop_tools,editors,email,internet,multimedia,office,programming,remote_desktop
|
||||
rpi4b edge jammy desktop beta yes cinnamon config_base 3dsupport,browsers,chat,desktop_tools,editors,email,internet,multimedia,office,programming,remote_desktop
|
||||
|
||||
|
||||
# uefi-x86
|
||||
uefi-x86 edge jammy desktop beta yes xfce config_base 3dsupport,browsers,chat,desktop_tools,editors,email,internet,multimedia,office,programming,remote_desktop
|
||||
uefi-x86 edge jammy desktop beta yes cinnamon config_base 3dsupport,browsers,chat,desktop_tools,editors,email,internet,multimedia,office,programming,remote_desktop
|
||||
|
||||
|
||||
# uefi-arm64
|
||||
uefi-arm64 edge jammy desktop beta yes xfce config_base 3dsupport,browsers,chat,desktop_tools,editors,email,internet,multimedia,office,programming,remote_desktop
|
||||
uefi-arm64 edge jammy desktop beta yes cinnamon config_base 3dsupport,browsers,chat,desktop_tools,editors,email,internet,multimedia,office,programming,remote_desktop
|
||||
|
||||
|
||||
# qemu virtual images
|
||||
virtual-qemu current focal desktop beta yes budgie config_base 3dsupport,browsers,chat,desktop_tools,editors,email,internet,multimedia,office,programming,remote_desktop
|
||||
virtual-qemu current focal desktop beta yes cinnamon config_base 3dsupport,browsers,chat,desktop_tools,editors,email,internet,multimedia,office,programming,remote_desktop
|
||||
virtual-qemu current focal desktop beta yes xfce config_base 3dsupport,browsers,chat,desktop_tools,editors,email,internet,multimedia,office,programming,remote_desktop
|
||||
|
||||
@@ -1084,5 +1084,17 @@ jetson-nano current focal desktop s
|
||||
jetson-nano edge jammy cli stable yes
|
||||
|
||||
|
||||
# Raspberry Pi4
|
||||
rpi4b edge jammy cli stable no
|
||||
|
||||
|
||||
# uefi-x86
|
||||
uefi-x86 edge jammy cli stable no
|
||||
|
||||
|
||||
# uefi-arm64
|
||||
uefi-arm64 edge jammy cli stable no
|
||||
|
||||
|
||||
# Virtual qemu
|
||||
virtual-qemu current jammy cli stable no
|
||||
|
||||
@@ -64,7 +64,7 @@ RUN apt-get update \
|
||||
libbison-dev \
|
||||
libc6-amd64-cross \
|
||||
libc6-dev-armhf-cross \
|
||||
libfdt-dev \
|
||||
libfdt-dev libelf-dev \
|
||||
libfile-fcntllock-perl \
|
||||
libfl-dev \
|
||||
liblz4-tool \
|
||||
|
||||
50
extensions/detect-unused-extensions.sh
Normal file
50
extensions/detect-unused-extensions.sh
Normal file
@@ -0,0 +1,50 @@
|
||||
## Configuration
|
||||
export LOG_ALL_HOOK_TRACES=no # Should we log all hook function traces to stdout? (no, or level: wrn info)
|
||||
|
||||
## Hooks
|
||||
|
||||
# A honeypot wishful hooking. To make sure the whole thing works.
|
||||
# This is exactly the kind of hooking this extension is meant to detect.
|
||||
# This will never run, and should be detected below, but is handled specially and ignored.
|
||||
# Note: this will never run, since we (hopefully) don't have a hook_point called 'wishful_hooking_example'.
|
||||
function wishful_hooking_example__this_will_never_run() {
|
||||
echo "WISHFUL HOOKING -- this will never run. I promise."
|
||||
}
|
||||
|
||||
# Run super late, hopefully at the last possible moment.
|
||||
function extension_metadata_ready__999_detect_wishful_hooking() {
|
||||
display_alert "Checking extensions and hooks for uncalled hook points"
|
||||
declare -i found_honeypot_function=0
|
||||
|
||||
# Loop over the defined functions' keys. Find the info about the call. If not found, warn the user.
|
||||
# shellcheck disable=SC2154 # hook-exported variable
|
||||
for one_defined_function in ${!defined_hook_point_functions[*]}; do
|
||||
local source_info defined_info line_info
|
||||
defined_info="${defined_hook_point_functions["${one_defined_function}"]}"
|
||||
source_info="${hook_point_function_trace_sources["${one_defined_function}"]}"
|
||||
line_info="${hook_point_function_trace_lines["${one_defined_function}"]}"
|
||||
stack="$(get_extension_hook_stracktrace "${source_info}" "${line_info}")"
|
||||
if [[ "$source_info" != "" ]]; then
|
||||
# log to debug log. it's reassuring.
|
||||
echo "\$\$\$ Hook function stacktrace for '${one_defined_function}': '${stack}' (${defined_info})" >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
if [[ "${LOG_ALL_HOOK_TRACES}" != "no" ]]; then
|
||||
display_alert "Hook function stacktrace for '${one_defined_function}'" "${stack}" "${LOG_ALL_HOOK_TRACES}"
|
||||
fi
|
||||
continue # found a caller, move on.
|
||||
fi
|
||||
|
||||
# special handling for the honeypot function. it is supposed to be always detected as uncalled.
|
||||
if [[ "${one_defined_function}" == "wishful_hooking_example__this_will_never_run" ]]; then
|
||||
# we expect this wishful hooking, it is done on purpose below, to make sure this code works.
|
||||
found_honeypot_function=1
|
||||
else
|
||||
# unexpected wishful hooking. Log and wrn the user.
|
||||
echo "\$\$\$ Wishful hooking detected" "Function '${one_defined_function}' is defined (${defined_info}) but never called by the build." >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
display_alert "Wishful hooking detected" "Function '${one_defined_function}' is defined (${defined_info}) but never called by the build." "wrn"
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $found_honeypot_function -lt 1 ]]; then
|
||||
display_alert "Wishful hook DETECTION FAILED" "detect-wishful-hooking is not working. Good chance the environment vars are corrupted. Avoid child shells. Sorry." "wrn" | tee -a "${EXTENSION_MANAGER_LOG_FILE}"
|
||||
fi
|
||||
}
|
||||
119
extensions/flash-kernel.sh
Normal file
119
extensions/flash-kernel.sh
Normal file
@@ -0,0 +1,119 @@
|
||||
# This runs *after* user_config. Don't change anything not coming from other variables or meant to be configured by the user.
|
||||
function extension_prepare_config__prepare_flash_kernel() {
|
||||
# Configuration defaults, or lack thereof.
|
||||
export FK__TOOL_PACKAGE="${FK__TOOL_PACKAGE:-flash-kernel}"
|
||||
export FK__PUBLISHED_KERNEL_VERSION="${FK__PUBLISHED_KERNEL_VERSION:-undefined-flash-kernel-version}"
|
||||
export FK__EXTRA_PACKAGES="${FK__EXTRA_PACKAGES:-undefined-flash-kernel-kernel-package}"
|
||||
export FK__KERNEL_PACKAGES="${FK__KERNEL_PACKAGES:-}"
|
||||
export FK__MACHINE_MODEL="${FK__MACHINE_MODEL:-Undefined Flash-Kernel Machine}"
|
||||
|
||||
# Override certain variables. A case of "this extension knows better and modifies user configurable stuff".
|
||||
export BOOTCONFIG="none" # To try and convince lib/ to not build or install u-boot.
|
||||
unset BOOTSOURCE # To try and convince lib/ to not build or install u-boot.
|
||||
export UEFISIZE=256 # in MiB. Not really UEFI, but partition layout is the same.
|
||||
export BOOTSIZE=0 # No separate /boot, flash-kernel will "flash" the kernel+initrd to the firmware part.
|
||||
export UEFI_MOUNT_POINT="/boot/firmware" # mount uefi partition at /boot/firmware
|
||||
export CLOUD_INIT_CONFIG_LOCATION="/boot/firmware" # use /boot/firmware for cloud-init as well
|
||||
export VER="${FK__PUBLISHED_KERNEL_VERSION}" # For the VERSION
|
||||
export EXTRA_BSP_NAME="${EXTRA_BSP_NAME}-fk${FK__PUBLISHED_KERNEL_VERSION}" # Unique bsp name.
|
||||
echo "-- starting" >"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log # Zero out the log for this extension.
|
||||
}
|
||||
|
||||
function post_install_kernel_debs__install_kernel_and_flash_packages() {
|
||||
export INSTALL_ARMBIAN_FIRMWARE="no" # Disable Armbian-firmware install, which would happen after this method.
|
||||
|
||||
if [[ "${FK__EXTRA_PACKAGES}" != "" ]]; then
|
||||
display_alert "Installing flash-kernel extra packages" "${FK__EXTRA_PACKAGES}"
|
||||
echo "-- install extra pkgs" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq --no-install-recommends install ${FK__EXTRA_PACKAGES}" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log || {
|
||||
display_alert "Failed to install flash-kernel's extra packages." "${EXTENSION}" "err"
|
||||
exit 28
|
||||
}
|
||||
fi
|
||||
|
||||
if [[ "${FK__KERNEL_PACKAGES}" != "" ]]; then
|
||||
display_alert "Installing flash-kernel kernel packages" "${FK__KERNEL_PACKAGES}"
|
||||
echo "-- install kernel pkgs" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq --no-install-recommends install ${FK__KERNEL_PACKAGES}" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log || {
|
||||
display_alert "Failed to install flash-kernel's kernel packages." "${EXTENSION}" "err"
|
||||
exit 28
|
||||
}
|
||||
fi
|
||||
|
||||
display_alert "Installing flash-kernel package" "${FK__TOOL_PACKAGE}"
|
||||
# Create a fake /sys/firmware/efi directory so that flash-kernel does not try to do anything when installed
|
||||
# @TODO: this might or not work after flash-kernel 3.104 or later
|
||||
umount "${SDCARD}"/sys
|
||||
mkdir -p "${SDCARD}"/sys/firmware/efi
|
||||
|
||||
echo "-- install flash-kernel package" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq --no-install-recommends install ${FK__TOOL_PACKAGE}" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log || {
|
||||
display_alert "Failed to install flash-kernel package." "${EXTENSION}" "err"
|
||||
exit 28
|
||||
}
|
||||
|
||||
# Remove fake /sys/firmware (/efi) directory
|
||||
rm -rf "${SDCARD}"/sys/firmware
|
||||
}
|
||||
|
||||
# @TODO: extract u-boot into an extension, so that core bsps don't have this stuff in there to begin with.
|
||||
# @TODO: this code is duplicated in grub.sh extension, so another reason to refactor the root of the evil
|
||||
post_family_tweaks_bsp__remove_uboot_flash_kernel() {
|
||||
display_alert "Removing uboot from BSP" "${EXTENSION}" "info"
|
||||
# Simply remove everything with 'uboot' or 'u-boot' in their filenames from the BSP package.
|
||||
# shellcheck disable=SC2154 # $destination is the target dir of the bsp building function
|
||||
find "$destination" -type f | grep -e "uboot" -e "u-boot" | xargs rm
|
||||
}
|
||||
|
||||
pre_umount_final_image__remove_uboot_initramfs_hook_flash_kernel() {
|
||||
# even if BSP still contained this (cached .deb), make sure by removing from ${MOUNT}
|
||||
[[ -f "$MOUNT"/etc/initramfs/post-update.d/99-uboot ]] && rm -v "$MOUNT"/etc/initramfs/post-update.d/99-uboot
|
||||
}
|
||||
|
||||
function pre_update_initramfs__setup_flash_kernel() {
|
||||
local chroot_target=$MOUNT
|
||||
cp /usr/bin/"$QEMU_BINARY" "$chroot_target"/usr/bin/
|
||||
mount_chroot "$chroot_target/" # this already handles /boot/firmware which is required for it to work.
|
||||
# hack, umount the chroot's /sys, otherwise flash-kernel tries to EFI flash due to the build host (!) being EFI
|
||||
umount "$chroot_target/sys"
|
||||
|
||||
echo "-- flash-kernel disabling hooks" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log
|
||||
chroot "$chroot_target" /bin/bash -c "chmod -v -x /etc/kernel/postinst.d/initramfs-tools" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log 2>&1
|
||||
chroot "$chroot_target" /bin/bash -c "chmod -v -x /etc/initramfs/post-update.d/flash-kernel" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log 2>&1
|
||||
|
||||
export FIRMWARE_DIR="${MOUNT}"/boot/firmware
|
||||
call_extension_method "pre_initramfs_flash_kernel" <<-'PRE_INITRAMFS_FLASH_KERNEL'
|
||||
*prepare to update-initramfs before flashing kernel via flash_kernel*
|
||||
A good spot to write firmware config to ${FIRMWARE_DIR} (/boot/firmware) before flash-kernel actually runs.
|
||||
PRE_INITRAMFS_FLASH_KERNEL
|
||||
|
||||
local update_initramfs_cmd="update-initramfs -c -k all"
|
||||
display_alert "Updating flash-kernel initramfs..." "$update_initramfs_cmd" ""
|
||||
echo "-- flash-kernel initramfs" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log
|
||||
chroot "$chroot_target" /bin/bash -c "$update_initramfs_cmd" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log 2>&1 || {
|
||||
display_alert "Failed to run '$update_initramfs_cmd'" "Check ${DEST}/"${LOG_SUBPATH}"/flash-kernel.log" "err"
|
||||
exit 29
|
||||
}
|
||||
|
||||
call_extension_method "pre_flash_kernel" <<-'PRE_FLASH_KERNEL'
|
||||
*run before running flash-kernel*
|
||||
Each board might need different stuff for flash-kernel to work. Implement it here.
|
||||
Write to `${MOUNT}`, eg: `"${MOUNT}"/etc/flash-kernel`
|
||||
PRE_FLASH_KERNEL
|
||||
|
||||
local flash_kernel_cmd="flash-kernel --machine '${FK__MACHINE_MODEL}'"
|
||||
display_alert "flash-kernel" "${FK__MACHINE_MODEL}" "info"
|
||||
echo "-- flash-kernel itself" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log
|
||||
chroot "$chroot_target" /bin/bash -c "${flash_kernel_cmd}" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log 2>&1 || {
|
||||
display_alert "Failed to run '${flash_kernel_cmd}'" "Check ${DEST}/"${LOG_SUBPATH}"/flash-kernel.log" "err"
|
||||
exit 29
|
||||
}
|
||||
|
||||
display_alert "Re-enabling" "initramfs-tools/flash-kernel hook for kernel"
|
||||
echo "-- flash-kernel re-enabling hooks" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log
|
||||
chroot "$chroot_target" /bin/bash -c "chmod -v +x /etc/kernel/postinst.d/initramfs-tools" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log 2>&1
|
||||
chroot "$chroot_target" /bin/bash -c "chmod -v +x /etc/initramfs/post-update.d/flash-kernel" >>"${DEST}"/"${LOG_SUBPATH}"/flash-kernel.log 2>&1
|
||||
|
||||
umount_chroot "$chroot_target/"
|
||||
rm "$chroot_target"/usr/bin/"$QEMU_BINARY"
|
||||
}
|
||||
126
extensions/gen-sample-extension-docs.sh
Normal file
126
extensions/gen-sample-extension-docs.sh
Normal file
@@ -0,0 +1,126 @@
|
||||
## Hooks
|
||||
function extension_metadata_ready__499_display_docs_generation_start_info() {
|
||||
display_alert "Generating hook documentation and sample extension"
|
||||
}
|
||||
|
||||
function extension_metadata_ready__docs_markdown() {
|
||||
generate_markdown_docs_to_stdout >"${DEST}/"${LOG_SUBPATH}"/hooks.auto.docs.md"
|
||||
}
|
||||
|
||||
function extension_metadata_ready__docs_sample_extension() {
|
||||
mkdir -p "${SRC}/userpatches/extensions"
|
||||
generate_sample_extension_to_stdout >"${SRC}/userpatches/extensions/sample-extension.sh"
|
||||
}
|
||||
|
||||
## Internal functions
|
||||
|
||||
### Common stuff
|
||||
function read_common_data() {
|
||||
export HOOK_POINT_CALLS_COUNT=$(wc -l <"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt")
|
||||
export HOOK_POINT_CALLS_UNIQUE_COUNT=$(sort <"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt" | uniq | wc -l)
|
||||
export HOOK_POINTS_WITH_MULTIPLE_CALLS=""
|
||||
|
||||
# Read the hook_points (main, official names) from the hook point ordering file.
|
||||
export ALL_HOOK_POINT_CALLS=$(xargs echo -n <"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt")
|
||||
}
|
||||
|
||||
function loop_over_hook_points_and_call() {
|
||||
local callback="$1"
|
||||
HOOK_POINT_COUNTER=0
|
||||
for one_hook_point in ${ALL_HOOK_POINT_CALLS}; do
|
||||
export HOOK_POINT_COUNTER=$((HOOK_POINT_COUNTER + 1))
|
||||
export HOOK_POINT="${one_hook_point}"
|
||||
export MARKDOWN_HEAD="$(head -1 "${EXTENSION_MANAGER_TMP_DIR}/${one_hook_point}.orig.md")"
|
||||
export MARKDOWN_BODY="$(tail -n +2 "${EXTENSION_MANAGER_TMP_DIR}/${one_hook_point}.orig.md")"
|
||||
export COMPATIBILITY_NAMES="$(xargs echo -n <"${EXTENSION_MANAGER_TMP_DIR}/${one_hook_point}.compat")"
|
||||
${callback}
|
||||
done
|
||||
}
|
||||
|
||||
## Markdown stuff
|
||||
function generate_markdown_docs_to_stdout() {
|
||||
read_common_data
|
||||
cat <<MASTER_HEADER
|
||||
# Armbian build system extensibility documentation
|
||||
- This documentation is auto-generated.
|
||||
MASTER_HEADER
|
||||
|
||||
[[ $HOOK_POINT_CALLS_COUNT -gt $HOOK_POINT_CALLS_UNIQUE_COUNT ]] && {
|
||||
# Some hook points were called multiple times, determine which.
|
||||
HOOK_POINTS_WITH_MULTIPLE_CALLS=$(comm -13 <(sort <"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt" | uniq) <(sort <"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt") | sort | uniq | xargs echo -n)
|
||||
|
||||
cat <<MULTIPLE_CALLS_WARNING
|
||||
- *Important:* The following hook points where called multiple times during the documentation generation. This can be indicative of a bug in the build system. Please check the sources for the invocation of the following hooks: \`${HOOK_POINTS_WITH_MULTIPLE_CALLS}\`.
|
||||
MULTIPLE_CALLS_WARNING
|
||||
|
||||
}
|
||||
|
||||
cat <<PRE_HOOKS_HEADER
|
||||
## Hooks
|
||||
- Hooks are listed in the order they are called.
|
||||
PRE_HOOKS_HEADER
|
||||
|
||||
loop_over_hook_points_and_call "generate_markdown_one_hook_point_to_stdout"
|
||||
|
||||
cat <<MASTER_FOOTER
|
||||
------------------------------------------------------------------------------------------
|
||||
MASTER_FOOTER
|
||||
|
||||
}
|
||||
|
||||
function generate_markdown_one_hook_point_to_stdout() {
|
||||
# Hook name in 3rd level title, first line of description in a blockquote.
|
||||
# The rest in a normal block.
|
||||
cat <<HOOK_DOCS
|
||||
### \`${one_hook_point}\`
|
||||
> ${MARKDOWN_HEAD}
|
||||
|
||||
${MARKDOWN_BODY}
|
||||
|
||||
HOOK_DOCS
|
||||
|
||||
[[ "${COMPATIBILITY_NAMES}" != "" ]] && {
|
||||
echo -e "\n\nAlso known as (for backwards compatibility only):"
|
||||
for old_name in ${COMPATIBILITY_NAMES}; do
|
||||
echo "- \`${old_name}\`"
|
||||
done
|
||||
}
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
## Bash sample extension stuff
|
||||
generate_sample_extension_to_stdout() {
|
||||
read_common_data
|
||||
cat <<HEADER
|
||||
# Sample Armbian build system extension with all extension methods.
|
||||
# This file is auto-generated from and by the build system itself.
|
||||
# Please, always use the latest version of this file as a starting point for your own extensions.
|
||||
# Generation date: $(date)
|
||||
# Read more about the build system at https://docs.armbian.com/Developer-Guide_Build-Preparation/
|
||||
|
||||
HEADER
|
||||
|
||||
loop_over_hook_points_and_call "generate_bash_sample_for_hook_point"
|
||||
}
|
||||
|
||||
generate_bash_sample_for_hook_point() {
|
||||
# Include the markdown documentation as a comment.
|
||||
# Right now clean it up naively (remove backticks, mostly) but we could pipe through stuff to get better plaintext. (pandoc is a 155mb binary FYI)
|
||||
local COMMENT_HEAD="#### $(echo "${MARKDOWN_HEAD}" | tr '`' '"')"
|
||||
# shellcheck disable=SC2001
|
||||
local COMMENT_BODY="$(echo "${MARKDOWN_BODY}" | tr '`' '"' | sed -e 's/^/### /')"
|
||||
|
||||
local bonus=""
|
||||
[[ "${HOOK_POINT_COUNTER}" == "1" ]] && bonus="$(echo -e "\n\texport PROGRESS_DISPLAY=verysilent # Example: export a variable. This one silences the built.")"
|
||||
|
||||
cat <<SAMPLE_BASH_CODE
|
||||
${COMMENT_HEAD}
|
||||
${COMMENT_BODY}
|
||||
function ${HOOK_POINT}__be_more_awesome() {
|
||||
# @TODO: Please rename this function to reflect what it does, but preserve the "${HOOK_POINT}__" prefix.
|
||||
display_alert "Being awesome at \${HOOK_POINT}" "\${EXTENSION}" "info"${bonus}
|
||||
}
|
||||
|
||||
SAMPLE_BASH_CODE
|
||||
}
|
||||
163
extensions/grub.sh
Normal file
163
extensions/grub.sh
Normal file
@@ -0,0 +1,163 @@
|
||||
# This runs *after* user_config. Don't change anything not coming from other variables or meant to be configured by the user.
|
||||
function extension_prepare_config__prepare_flash_kernel() {
|
||||
# Extension configuration defaults.
|
||||
export DISTRO_GENERIC_KERNEL=${DISTRO_GENERIC_KERNEL:-no} # if yes, does not build our own kernel, instead, uses generic one from distro
|
||||
export UEFI_GRUB_TERMINAL="${UEFI_GRUB_TERMINAL:-serial console}" # 'serial' forces grub menu on serial console. empty to not include
|
||||
export UEFI_GRUB_DISABLE_OS_PROBER="${UEFI_GRUB_DISABLE_OS_PROBER:-}" # 'true' will disable os-probing, useful for SD cards.
|
||||
export UEFI_GRUB_DISTRO_NAME="${UEFI_GRUB_DISTRO_NAME:-Armbian}" # Will be used on grub menu display
|
||||
export UEFI_GRUB_TIMEOUT=${UEFI_GRUB_TIMEOUT:-0} # Small timeout by default
|
||||
export UEFI_ENABLE_BIOS_AMD64="${UEFI_ENABLE_BIOS_AMD64:-yes}" # Enable BIOS too if target is amd64
|
||||
export UEFI_EXPORT_KERNEL_INITRD="${UEFI_EXPORT_KERNEL_INITRD:-no}" # Export kernel and initrd for direct kernel boot "kexec"
|
||||
# User config overrides.
|
||||
export BOOTCONFIG="none" # To try and convince lib/ to not build or install u-boot.
|
||||
unset BOOTSOURCE # To try and convince lib/ to not build or install u-boot.
|
||||
export IMAGE_PARTITION_TABLE="gpt" # GPT partition table is essential for many UEFI-like implementations, eg Apple+Intel stuff.
|
||||
export UEFISIZE=256 # in MiB - grub EFI is tiny - but some EFI BIOSes ignore small too small EFI partitions
|
||||
export BOOTSIZE=0 # No separate /boot when using UEFI.
|
||||
export CLOUD_INIT_CONFIG_LOCATION="${CLOUD_INIT_CONFIG_LOCATION:-/boot/efi}" # use /boot/efi for cloud-init as default when using Grub.
|
||||
export EXTRA_BSP_NAME="${EXTRA_BSP_NAME}-grub" # Unique bsp name.
|
||||
export UEFI_GRUB_TARGET_BIOS="" # Target for BIOS GRUB install, set to i386-pc when UEFI_ENABLE_BIOS_AMD64=yes and target is amd64
|
||||
local uefi_packages="efibootmgr efivar cloud-initramfs-growroot" # Use growroot, add some efi-related packages
|
||||
uefi_packages="os-prober grub-efi-${ARCH}-bin ${uefi_packages}" # This works for Ubuntu and Debian, by sheer luck; common for EFI and BIOS
|
||||
|
||||
# BIOS-compatibility for amd64
|
||||
if [[ "${ARCH}" == "amd64" ]]; then
|
||||
export UEFI_GRUB_TARGET="x86_64-efi" # Default for x86_64
|
||||
if [[ "${UEFI_ENABLE_BIOS_AMD64}" == "yes" ]]; then
|
||||
export uefi_packages="${uefi_packages} grub-pc-bin grub-pc"
|
||||
export UEFI_GRUB_TARGET_BIOS="i386-pc"
|
||||
export BIOSSIZE=4 # 4 MiB BIOS partition
|
||||
else
|
||||
export uefi_packages="${uefi_packages} grub-efi-${ARCH}"
|
||||
fi
|
||||
fi
|
||||
|
||||
[[ "${ARCH}" == "arm64" ]] && export uefi_packages="${uefi_packages} grub-efi-${ARCH}"
|
||||
[[ "${ARCH}" == "arm64" ]] && export UEFI_GRUB_TARGET="arm64-efi" # Default for arm64-efi
|
||||
|
||||
if [[ "${DISTRIBUTION}" == "Ubuntu" ]]; then
|
||||
DISTRO_KERNEL_PACKAGES="linux-image-generic"
|
||||
DISTRO_FIRMWARE_PACKAGES="linux-firmware"
|
||||
elif [[ "${DISTRIBUTION}" == "Debian" ]]; then
|
||||
DISTRO_KERNEL_PACKAGES="linux-image-${ARCH}"
|
||||
DISTRO_FIRMWARE_PACKAGES="firmware-linux-free"
|
||||
# Debian's prebuilt kernels dont support hvc0, hack.
|
||||
if [[ "${SERIALCON}" == "hvc0" ]]; then
|
||||
display_alert "Debian's kernels don't support hvc0, changing to ttyS0" "${DISTRIBUTION}" "wrn"
|
||||
export SERIALCON="ttyS0"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${DISTRO_GENERIC_KERNEL}" == "yes" ]]; then
|
||||
export VER="generic"
|
||||
unset KERNELSOURCE # This should make Armbian skip most stuff. At least, I hacked it to.
|
||||
export INSTALL_ARMBIAN_FIRMWARE=no # Should skip build and install of Armbian-firmware.
|
||||
else
|
||||
export KERNELDIR="linux-uefi-${LINUXFAMILY}" # Avoid sharing a source tree with others, until we know it's safe.
|
||||
# Don't install anything. Armbian handles everything.
|
||||
DISTRO_KERNEL_PACKAGES=""
|
||||
DISTRO_FIRMWARE_PACKAGES=""
|
||||
fi
|
||||
|
||||
export PACKAGE_LIST_BOARD="${PACKAGE_LIST_BOARD} ${DISTRO_FIRMWARE_PACKAGES} ${DISTRO_KERNEL_PACKAGES} ${uefi_packages}"
|
||||
|
||||
display_alert "Activating" "GRUB with SERIALCON=${SERIALCON}; timeout ${UEFI_GRUB_TIMEOUT}; BIOS=${UEFI_GRUB_TARGET_BIOS}" ""
|
||||
}
|
||||
|
||||
# @TODO: extract u-boot into an extension, so that core bsps don't have this stuff in there to begin with.
|
||||
# @TODO: this code is duplicated in flash-kernel.sh extension, so another reason to refactor the root of the evil
|
||||
post_family_tweaks_bsp__remove_uboot_grub() {
|
||||
display_alert "Removing uboot from BSP" "${EXTENSION}" "info"
|
||||
# Simply remove everything with 'uboot' or 'u-boot' in their filenames from the BSP package.
|
||||
# shellcheck disable=SC2154 # $destination is the target dir of the bsp building function
|
||||
find "$destination" -type f | grep -e "uboot" -e "u-boot" | xargs rm
|
||||
}
|
||||
|
||||
pre_umount_final_image__remove_uboot_initramfs_hook_grub() {
|
||||
# even if BSP still contained this (cached .deb), make sure by removing from ${MOUNT}
|
||||
[[ -f "$MOUNT"/etc/initramfs/post-update.d/99-uboot ]] && rm -v "$MOUNT"/etc/initramfs/post-update.d/99-uboot
|
||||
}
|
||||
|
||||
pre_umount_final_image__install_grub() {
|
||||
configure_grub
|
||||
local chroot_target=$MOUNT
|
||||
display_alert "Installing bootloader" "GRUB" "info"
|
||||
|
||||
# getting rid of the dtb package, if installed, is hard. for now just zap it, otherwise update-grub goes bananas
|
||||
rm -rf "$MOUNT"/boot/dtb* || true
|
||||
|
||||
# add config to disable os-prober, otherwise image will have the host's other OSes boot entries.
|
||||
cat <<-grubCfgFragHostSide >>"${MOUNT}"/etc/default/grub.d/99-armbian-host-side.cfg
|
||||
GRUB_DISABLE_OS_PROBER=true
|
||||
grubCfgFragHostSide
|
||||
|
||||
# Mount the chroot...
|
||||
mount_chroot "$chroot_target/" # this already handles /boot/efi which is required for it to work.
|
||||
|
||||
if [[ "${UEFI_GRUB_TARGET_BIOS}" != "" ]]; then
|
||||
display_alert "Installing GRUB BIOS..." "${UEFI_GRUB_TARGET_BIOS} device ${LOOP}" ""
|
||||
chroot "$chroot_target" /bin/bash -c "grub-install --verbose --target=${UEFI_GRUB_TARGET_BIOS} ${LOOP}" >>"$DEST"/"${LOG_SUBPATH}"/install.log 2>&1 || {
|
||||
exit_with_error "${install_grub_cmdline} failed!"
|
||||
}
|
||||
fi
|
||||
|
||||
local install_grub_cmdline="update-initramfs -c -k all && update-grub && grub-install --verbose --target=${UEFI_GRUB_TARGET} --no-nvram --removable" # nvram is global to the host, even across chroot. take care.
|
||||
display_alert "Installing GRUB EFI..." "${UEFI_GRUB_TARGET}" ""
|
||||
chroot "$chroot_target" /bin/bash -c "$install_grub_cmdline" >>"$DEST"/"${LOG_SUBPATH}"/install.log 2>&1 || {
|
||||
exit_with_error "${install_grub_cmdline} failed!"
|
||||
}
|
||||
|
||||
# Remove host-side config.
|
||||
rm -f "${MOUNT}"/etc/default/grub.d/99-armbian-host-side.cfg
|
||||
|
||||
local root_uuid
|
||||
root_uuid=$(blkid -s UUID -o value "${LOOP}p1") # get the uuid of the root partition, this has been transposed
|
||||
|
||||
# Create /boot/efi/EFI/BOOT/grub.cfg (EFI/ESP) which will load /boot/grub/grub.cfg (in the rootfs, generated by update-grub)
|
||||
cat <<-grubEfiCfg >"${MOUNT}"/boot/efi/EFI/BOOT/grub.cfg
|
||||
search.fs_uuid ${root_uuid} root
|
||||
set prefix=(\$root)'/boot/grub'
|
||||
configfile \$prefix/grub.cfg
|
||||
grubEfiCfg
|
||||
|
||||
umount_chroot "$chroot_target/"
|
||||
|
||||
}
|
||||
|
||||
pre_umount_final_image__900_export_kernel_and_initramfs() {
|
||||
if [[ "${UEFI_EXPORT_KERNEL_INITRD}" == "yes" ]]; then
|
||||
display_alert "Exporting Kernel and Initrd for" "kexec" "info"
|
||||
# this writes to ${DESTIMG} directly, since debootstrap.sh will move them later.
|
||||
# capture the $MOUNT/boot/vmlinuz and initrd and send it out ${DESTIMG}
|
||||
cp "$MOUNT"/boot/vmlinuz-* "${DESTIMG}/${version}.kernel"
|
||||
cp "$MOUNT"/boot/initrd.img-* "${DESTIMG}/${version}.initrd"
|
||||
fi
|
||||
}
|
||||
|
||||
configure_grub() {
|
||||
display_alert "GRUB EFI kernel cmdline" "console=${SERIALCON} distro=${UEFI_GRUB_DISTRO_NAME} timeout=${UEFI_GRUB_TIMEOUT}" ""
|
||||
|
||||
if [[ "_${SERIALCON}_" != "__" ]]; then
|
||||
cat <<-grubCfgFrag >>"${MOUNT}"/etc/default/grub.d/98-armbian.cfg
|
||||
GRUB_CMDLINE_LINUX_DEFAULT="console=${SERIALCON}" # extra Kernel cmdline is configured here
|
||||
grubCfgFrag
|
||||
fi
|
||||
|
||||
cat <<-grubCfgFrag >>"${MOUNT}"/etc/default/grub.d/98-armbian.cfg
|
||||
GRUB_TIMEOUT_STYLE=menu # Show the menu with Kernel options (Armbian or -generic)...
|
||||
GRUB_TIMEOUT=${UEFI_GRUB_TIMEOUT} # ... for ${UEFI_GRUB_TIMEOUT} seconds, then boot the Armbian default.
|
||||
GRUB_DISTRIBUTOR="${UEFI_GRUB_DISTRO_NAME}" # On GRUB menu will show up as "Armbian GNU/Linux" (will show up in some UEFI BIOS boot menu (F8?) as "armbian", not on others)
|
||||
grubCfgFrag
|
||||
|
||||
if [[ "a${UEFI_GRUB_DISABLE_OS_PROBER}" != "a" ]]; then
|
||||
cat <<-grubCfgFragHostSide >>"${MOUNT}"/etc/default/grub.d/98-armbian.cfg
|
||||
GRUB_DISABLE_OS_PROBER=${UEFI_GRUB_DISABLE_OS_PROBER}
|
||||
grubCfgFragHostSide
|
||||
fi
|
||||
|
||||
if [[ "a${UEFI_GRUB_TERMINAL}" != "a" ]]; then
|
||||
cat <<-grubCfgFragTerminal >>"${MOUNT}"/etc/default/grub.d/98-armbian.cfg
|
||||
GRUB_TERMINAL="${UEFI_GRUB_TERMINAL}"
|
||||
grubCfgFragTerminal
|
||||
fi
|
||||
}
|
||||
5
extensions/marvell-tools.sh
Normal file
5
extensions/marvell-tools.sh
Normal file
@@ -0,0 +1,5 @@
|
||||
function fetch_sources_tools__marvell_tools() {
|
||||
fetch_from_repo "https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell" "marvell-tools" "branch:A3700_utils-armada-18.12"
|
||||
fetch_from_repo "https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git" "marvell-ddr" "branch:mv_ddr-armada-18.12"
|
||||
fetch_from_repo "https://github.com/MarvellEmbeddedProcessors/binaries-marvell" "marvell-binaries" "branch:binaries-marvell-armada-18.12"
|
||||
}
|
||||
16
extensions/rkbin-tools.sh
Normal file
16
extensions/rkbin-tools.sh
Normal file
@@ -0,0 +1,16 @@
|
||||
function fetch_sources_tools__rkbin_tools() {
|
||||
fetch_from_repo "https://github.com/armbian/rkbin" "rkbin-tools" "branch:master"
|
||||
}
|
||||
|
||||
function build_host_tools__install_rkbin_tools() {
|
||||
# install only if git commit hash changed
|
||||
cd "${SRC}"/cache/sources/rkbin-tools || exit
|
||||
# need to check if /usr/local/bin/loaderimage to detect new Docker containers with old cached sources
|
||||
if [[ ! -f .commit_id || $(improved_git rev-parse @ 2>/dev/null) != $(<.commit_id) || ! -f /usr/local/bin/loaderimage ]]; then
|
||||
display_alert "Installing" "rkbin-tools" "info"
|
||||
mkdir -p /usr/local/bin/
|
||||
install -m 755 tools/loaderimage /usr/local/bin/
|
||||
install -m 755 tools/trust_merger /usr/local/bin/
|
||||
improved_git rev-parse @ 2>/dev/null >.commit_id
|
||||
fi
|
||||
}
|
||||
17
extensions/sunxi-tools.sh
Normal file
17
extensions/sunxi-tools.sh
Normal file
@@ -0,0 +1,17 @@
|
||||
function fetch_sources_tools__sunxi_tools() {
|
||||
fetch_from_repo "https://github.com/linux-sunxi/sunxi-tools" "sunxi-tools" "branch:master"
|
||||
}
|
||||
|
||||
function build_host_tools__compile_sunxi_tools() {
|
||||
# Compile and install only if git commit hash changed
|
||||
cd "${SRC}"/cache/sources/sunxi-tools || exit
|
||||
# need to check if /usr/local/bin/sunxi-fexc to detect new Docker containers with old cached sources
|
||||
if [[ ! -f .commit_id || $(improved_git rev-parse @ 2>/dev/null) != $(<.commit_id) || ! -f /usr/local/bin/sunxi-fexc ]]; then
|
||||
display_alert "Compiling" "sunxi-tools" "info"
|
||||
make -s clean >/dev/null
|
||||
make -s tools >/dev/null
|
||||
mkdir -p /usr/local/bin/
|
||||
make install-tools >/dev/null 2>&1
|
||||
improved_git rev-parse @ 2>/dev/null >.commit_id
|
||||
fi
|
||||
}
|
||||
@@ -49,6 +49,7 @@ fi
|
||||
|
||||
unset_all ()
|
||||
{
|
||||
cleanup_extension_manager
|
||||
unset LINUXFAMILY LINUXCONFIG KERNELDIR KERNELSOURCE KERNELBRANCH BOOTDIR BOOTSOURCE BOOTBRANCH ARCH UBOOT_USE_GCC KERNEL_USE_GCC CPUMIN CPUMAX \
|
||||
UBOOT_VER KERNEL_VER GOVERNOR BOOTSIZE BOOTFS_TYPE UBOOT_TOOLCHAIN KERNEL_TOOLCHAIN DEBOOTSTRAP_LIST PACKAGE_LIST_EXCLUDE KERNEL_IMAGE_TYPE \
|
||||
write_uboot_platform family_tweaks family_tweaks_bsp setup_write_uboot_platform uboot_custom_postprocess atf_custom_postprocess family_tweaks_s \
|
||||
@@ -202,9 +203,9 @@ function check_hash()
|
||||
|
||||
BOARDFAMILY=$(grep BOARDFAMILY "${SRC}/config/boards/${BOARD}".* | cut -d \" -f2)
|
||||
# shellcheck source=/dev/null
|
||||
source "${SRC}/config/sources/families/${BOARDFAMILY}.conf"
|
||||
source "${SRC}/config/sources/families/${BOARDFAMILY}.conf" &> /dev/null
|
||||
# shellcheck source=/dev/null
|
||||
source "${SRC}/config/sources/${ARCH}.conf"
|
||||
source "${SRC}/config/sources/${ARCH}.conf" &> /dev/null
|
||||
ref_type=${KERNELBRANCH%%:*}
|
||||
if [[ $ref_type == head ]]; then
|
||||
ref_name=HEAD
|
||||
@@ -227,7 +228,7 @@ function check_hash()
|
||||
# ignore diff checking in case of network errrors
|
||||
local kernel_hash="${SRC}/cache/hash"$([[ ${BETA} == yes ]] && echo "-beta")"/linux-image-${BRANCH}-${LINUXFAMILY}.githash"
|
||||
if [[ -f ${kernel_hash} ]]; then
|
||||
[[ "$hash" == "$(head -1 "${kernel_hash}")" && "$patch_hash" == "$(tail -1 "${kernel_hash}")" || -z $hash ]] && echo "idential"
|
||||
[[ "$hash" == "$(head -1 "${kernel_hash}")" && "$patch_hash" == "$(tail -1 "${kernel_hash}")" || -z $hash ]] && echo "IDENTICAL"
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -333,7 +334,7 @@ function build_all()
|
||||
local store_hash
|
||||
store_hash=$(check_hash)
|
||||
fi
|
||||
if [[ "$store_hash" != idential ]]; then
|
||||
if [[ "$store_hash" != IDENTICAL ]]; then
|
||||
|
||||
if [[ $1 != "dryrun" ]] && [[ $n -ge $START ]]; then
|
||||
((n+=1))
|
||||
|
||||
@@ -101,7 +101,7 @@ compilation_prepare()
|
||||
# Linux splash file
|
||||
#
|
||||
|
||||
if linux-version compare "${version}" ge 5.8.10; then
|
||||
if linux-version compare "${version}" ge 5.8.10 && [ $SKIP_BOOTSPLASH != yes ]; then
|
||||
|
||||
display_alert "Adding" "Kernel splash file" "info"
|
||||
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
# compile_kernel
|
||||
# compile_firmware
|
||||
# compile_armbian-config
|
||||
# compile_sunxi_tools
|
||||
# install_rkbin_tools
|
||||
# compile_xilinx_bootgen
|
||||
# grab_version
|
||||
# find_toolchain
|
||||
@@ -413,32 +411,42 @@ compile_kernel()
|
||||
|
||||
display_alert "Compiling $BRANCH kernel" "$version" "info"
|
||||
|
||||
# build aarch64
|
||||
if [[ $(dpkg --print-architecture) == amd64 ]]; then
|
||||
|
||||
local toolchain
|
||||
toolchain=$(find_toolchain "$KERNEL_COMPILER" "$KERNEL_USE_GCC")
|
||||
[[ -z $toolchain ]] && exit_with_error "Could not find required toolchain" "${KERNEL_COMPILER}gcc $KERNEL_USE_GCC"
|
||||
|
||||
# build aarch64
|
||||
fi
|
||||
# compare with the architecture of the current Debian node
|
||||
# if it matches we use the system compiler
|
||||
if $(dpkg-architecture -e "${ARCH}"); then
|
||||
display_alert "Native compilation"
|
||||
elif [[ $(dpkg --print-architecture) == amd64 ]]; then
|
||||
local toolchain
|
||||
toolchain=$(find_toolchain "$KERNEL_COMPILER" "$KERNEL_USE_GCC")
|
||||
[[ -z $toolchain ]] && exit_with_error "Could not find required toolchain" "${KERNEL_COMPILER}gcc $KERNEL_USE_GCC"
|
||||
else
|
||||
exit_with_error "Architecture [$ARCH] is not supported"
|
||||
fi
|
||||
|
||||
display_alert "Compiler version" "${KERNEL_COMPILER}gcc $(eval env PATH="${toolchain}:${PATH}" "${KERNEL_COMPILER}gcc" -dumpversion)" "info"
|
||||
|
||||
# copy kernel config
|
||||
if [[ $KERNEL_KEEP_CONFIG == yes && -f "${DEST}"/config/$LINUXCONFIG.config ]]; then
|
||||
display_alert "Using previous kernel config" "${DEST}/config/$LINUXCONFIG.config" "info"
|
||||
cp "${DEST}/config/${LINUXCONFIG}.config" .config
|
||||
cp -p "${DEST}/config/${LINUXCONFIG}.config" .config
|
||||
else
|
||||
if [[ -f $USERPATCHES_PATH/$LINUXCONFIG.config ]]; then
|
||||
display_alert "Using kernel config provided by user" "userpatches/$LINUXCONFIG.config" "info"
|
||||
cp "${USERPATCHES_PATH}/${LINUXCONFIG}.config" .config
|
||||
cp -p "${USERPATCHES_PATH}/${LINUXCONFIG}.config" .config
|
||||
else
|
||||
display_alert "Using kernel config file" "config/kernel/$LINUXCONFIG.config" "info"
|
||||
cp "${SRC}/config/kernel/${LINUXCONFIG}.config" .config
|
||||
cp -p "${SRC}/config/kernel/${LINUXCONFIG}.config" .config
|
||||
fi
|
||||
fi
|
||||
|
||||
call_extension_method "custom_kernel_config" << 'CUSTOM_KERNEL_CONFIG'
|
||||
*Kernel .config is in place, still clean from git version*
|
||||
Called after ${LINUXCONFIG}.config is put in place (.config).
|
||||
Before any olddefconfig any Kconfig make is called.
|
||||
A good place to customize the .config directly.
|
||||
CUSTOM_KERNEL_CONFIG
|
||||
|
||||
|
||||
# hack for OdroidXU4. Copy firmare files
|
||||
if [[ $BOARD == odroidxu4 ]]; then
|
||||
mkdir -p "${kerneldir}/firmware/edid"
|
||||
@@ -488,7 +496,7 @@ compile_kernel()
|
||||
CROSS_COMPILE="$CCACHE $KERNEL_COMPILER" \
|
||||
$SRC_LOADADDR \
|
||||
LOCALVERSION="-$LINUXFAMILY" \
|
||||
$KERNEL_IMAGE_TYPE modules dtbs 2>>$DEST/${LOG_SUBPATH}/compilation.log' \
|
||||
$KERNEL_IMAGE_TYPE ${KERNEL_EXTRA_TARGETS:-modules dtbs} 2>>$DEST/${LOG_SUBPATH}/compilation.log' \
|
||||
${PROGRESS_LOG_TO_FILE:+' | tee -a $DEST/${LOG_SUBPATH}/compilation.log'} \
|
||||
${OUTPUT_DIALOG:+' | dialog --backtitle "$backtitle" \
|
||||
--progressbox "Compiling kernel..." $TTY_Y $TTY_X'} \
|
||||
@@ -590,8 +598,7 @@ compile_firmware()
|
||||
# cp : create hardlinks
|
||||
cp -af --reflink=auto "${SRC}"/cache/sources/armbian-firmware-git/* "${firmwaretempdir}/${plugin_dir}/lib/firmware/"
|
||||
|
||||
# cleanup what's not needed for sure
|
||||
rm -rf "${firmwaretempdir}/${plugin_dir}"/lib/firmware/{amdgpu,amd-ucode,radeon,nvidia,matrox,.git}
|
||||
rm -rf "${firmwaretempdir}/${plugin_dir}"/lib/firmware/.git
|
||||
cd "${firmwaretempdir}/${plugin_dir}" || exit
|
||||
|
||||
# set up control file
|
||||
@@ -758,34 +765,6 @@ compile_armbian-config()
|
||||
|
||||
|
||||
|
||||
compile_sunxi_tools()
|
||||
{
|
||||
# Compile and install only if git commit hash changed
|
||||
cd "${SRC}"/cache/sources/sunxi-tools || exit
|
||||
# need to check if /usr/local/bin/sunxi-fexc to detect new Docker containers with old cached sources
|
||||
if [[ ! -f .commit_id || $(improved_git rev-parse @ 2>/dev/null) != $(<.commit_id) || ! -f /usr/local/bin/sunxi-fexc ]]; then
|
||||
display_alert "Compiling" "sunxi-tools" "info"
|
||||
make -s clean >/dev/null
|
||||
make -s tools >/dev/null
|
||||
mkdir -p /usr/local/bin/
|
||||
make install-tools >/dev/null 2>&1
|
||||
improved_git rev-parse @ 2>/dev/null > .commit_id
|
||||
fi
|
||||
}
|
||||
|
||||
install_rkbin_tools()
|
||||
{
|
||||
# install only if git commit hash changed
|
||||
cd "${SRC}"/cache/sources/rkbin-tools || exit
|
||||
# need to check if /usr/local/bin/sunxi-fexc to detect new Docker containers with old cached sources
|
||||
if [[ ! -f .commit_id || $(improved_git rev-parse @ 2>/dev/null) != $(<.commit_id) || ! -f /usr/local/bin/loaderimage ]]; then
|
||||
display_alert "Installing" "rkbin-tools" "info"
|
||||
mkdir -p /usr/local/bin/
|
||||
install -m 755 tools/loaderimage /usr/local/bin/
|
||||
install -m 755 tools/trust_merger /usr/local/bin/
|
||||
improved_git rev-parse @ 2>/dev/null > .commit_id
|
||||
fi
|
||||
}
|
||||
|
||||
compile_xilinx_bootgen()
|
||||
{
|
||||
@@ -824,6 +803,7 @@ grab_version()
|
||||
#
|
||||
find_toolchain()
|
||||
{
|
||||
[[ "${SKIP_EXTERNAL_TOOLCHAINS}" == "yes" ]] && { echo "/usr/bin"; return; }
|
||||
local compiler=$1
|
||||
local expression=$2
|
||||
local dist=10
|
||||
|
||||
@@ -113,8 +113,11 @@ ATF_COMPILE=yes
|
||||
[[ -z $CRYPTROOT_PARAMETERS ]] && CRYPTROOT_PARAMETERS="--pbkdf pbkdf2"
|
||||
[[ -z $WIREGUARD ]] && WIREGUARD="yes"
|
||||
[[ -z $EXTRAWIFI ]] && EXTRAWIFI="yes"
|
||||
[[ -z $SKIP_BOOTSPLASH ]] && SKIP_BOOTSPLASH="no"
|
||||
[[ -z $AUFS ]] && AUFS="yes"
|
||||
[[ -z $IMAGE_PARTITION_TABLE ]] && IMAGE_PARTITION_TABLE="msdos"
|
||||
[[ -z $EXTRA_BSP_NAME ]] && EXTRA_BSP_NAME=""
|
||||
[[ -z $EXTRA_ROOTFS_MIB_SIZE ]] && EXTRA_ROOTFS_MIB_SIZE=0
|
||||
|
||||
# single ext4 partition is the default and preferred configuration
|
||||
#BOOTFS_TYPE=''
|
||||
@@ -131,6 +134,19 @@ fi
|
||||
# load architecture defaults
|
||||
source "${SRC}/config/sources/${ARCH}.conf"
|
||||
|
||||
## Extensions: at this point we've sourced all the config files that will be used,
|
||||
## and (hopefully) not yet invoked any extension methods. So this is the perfect
|
||||
## place to initialize the extension manager. It will create functions
|
||||
## like the 'post_family_config' that is invoked below.
|
||||
initialize_extension_manager
|
||||
|
||||
call_extension_method "post_family_config" "config_tweaks_post_family_config" << 'POST_FAMILY_CONFIG'
|
||||
*give the config a chance to override the family/arch defaults*
|
||||
This hook is called after the family configuration (`sources/families/xxx.conf`) is sourced.
|
||||
Since the family can override values from the user configuration and the board configuration,
|
||||
it is often used to in turn override those.
|
||||
POST_FAMILY_CONFIG
|
||||
|
||||
# Myy : Menu configuration for choosing desktop configurations
|
||||
|
||||
show_menu() {
|
||||
@@ -534,6 +550,10 @@ if [[ $DOWNLOAD_MIRROR == "bfsu" ]] ; then
|
||||
UBUNTU_MIRROR='mirrors.bfsu.edu.cn/ubuntu-ports/'
|
||||
fi
|
||||
|
||||
if [[ "${ARCH}" == "amd64" ]]; then
|
||||
UBUNTU_MIRROR='archive.ubuntu.com/ubuntu' # ports are only for non-amd64, of course.
|
||||
fi
|
||||
|
||||
# don't use mirrors that throws garbage on 404
|
||||
if [[ -z ${ARMBIAN_MIRROR} ]]; then
|
||||
while true; do
|
||||
@@ -544,16 +564,26 @@ if [[ -z ${ARMBIAN_MIRROR} ]]; then
|
||||
done
|
||||
fi
|
||||
|
||||
# For user override
|
||||
# For (late) user override.
|
||||
# Notice: it is too late to define hook functions or add extensions in lib.config, since the extension initialization already ran by now.
|
||||
# in case the user tries to use them in lib.config, hopefully they'll be detected as "wishful hooking" and the user will be wrn'ed.
|
||||
if [[ -f $USERPATCHES_PATH/lib.config ]]; then
|
||||
display_alert "Using user configuration override" "$USERPATCHES_PATH/lib.config" "info"
|
||||
source "$USERPATCHES_PATH"/lib.config
|
||||
fi
|
||||
|
||||
if [[ "$(type -t user_config)" == "function" ]]; then
|
||||
display_alert "Invoke function with user override" "user_config" "info"
|
||||
user_config
|
||||
fi
|
||||
call_extension_method "user_config" << 'USER_CONFIG'
|
||||
*Invoke function with user override*
|
||||
Allows for overriding configuration values set anywhere else.
|
||||
It is called after sourcing the `lib.config` file if it exists,
|
||||
but before assembling any package lists.
|
||||
USER_CONFIG
|
||||
|
||||
call_extension_method "extension_prepare_config" << 'EXTENSION_PREPARE_CONFIG'
|
||||
*allow extensions to prepare their own config, after user config is done*
|
||||
Implementors should preserve variable values pre-set, but can default values an/or validate them.
|
||||
This runs *after* user_config. Don't change anything not coming from other variables or meant to be configured by the user.
|
||||
EXTENSION_PREPARE_CONFIG
|
||||
|
||||
# apt-cacher-ng mirror configurarion
|
||||
if [[ $DISTRIBUTION == Ubuntu ]]; then
|
||||
@@ -619,6 +649,13 @@ unset LOG_OUTPUT_FILE
|
||||
# Give the option to configure DNS server used in the chroot during the build process
|
||||
[[ -z $NAMESERVER ]] && NAMESERVER="1.0.0.1" # default is cloudflare alternate
|
||||
|
||||
call_extension_method "post_aggregate_packages" "user_config_post_aggregate_packages" << 'POST_AGGREGATE_PACKAGES'
|
||||
*For final user override, using a function, after all aggregations are done*
|
||||
Called after aggregating all package lists, before the end of `compilation.sh`.
|
||||
Packages will still be installed after this is called, so it is the last chance
|
||||
to confirm or change any packages.
|
||||
POST_AGGREGATE_PACKAGES
|
||||
|
||||
# debug
|
||||
cat <<-EOF >> "${DEST}"/${LOG_SUBPATH}/output.log
|
||||
|
||||
|
||||
@@ -51,6 +51,11 @@ debootstrap_ng()
|
||||
# stage: prepare basic rootfs: unpack cache or create from scratch
|
||||
create_rootfs_cache
|
||||
|
||||
call_extension_method "pre_install_distribution_specific" "config_pre_install_distribution_specific" << 'PRE_INSTALL_DISTRIBUTION_SPECIFIC'
|
||||
*give config a chance to act before install_distribution_specific*
|
||||
Called after `create_rootfs_cache` (_prepare basic rootfs: unpack cache or create from scratch_) but before `install_distribution_specific` (_install distribution and board specific applications_).
|
||||
PRE_INSTALL_DISTRIBUTION_SPECIFIC
|
||||
|
||||
# stage: install kernel and u-boot packages
|
||||
# install distribution and board specific applications
|
||||
|
||||
@@ -248,8 +253,10 @@ create_rootfs_cache()
|
||||
# stage: create apt-get sources list
|
||||
create_sources_list "$RELEASE" "$SDCARD/"
|
||||
|
||||
# add armhf arhitecture to arm64
|
||||
[[ $ARCH == arm64 ]] && eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "dpkg --add-architecture armhf"'
|
||||
# add armhf arhitecture to arm64, unless configured not to do so.
|
||||
if [[ "a${ARMHF_ARCH}" != "askip" ]]; then
|
||||
[[ $ARCH == arm64 ]] && eval 'LC_ALL=C LANG=C chroot $SDCARD /bin/bash -c "dpkg --add-architecture armhf"'
|
||||
fi
|
||||
|
||||
# this should fix resolvconf installation failure in some cases
|
||||
chroot $SDCARD /bin/bash -c 'echo "resolvconf resolvconf/linkify-resolvconf boolean false" | debconf-set-selections'
|
||||
@@ -458,6 +465,16 @@ prepare_partitions()
|
||||
|
||||
# default BOOTSIZE to use if not specified
|
||||
DEFAULT_BOOTSIZE=256 # MiB
|
||||
# size of UEFI partition. 0 for no UEFI. Don't mix UEFISIZE>0 and BOOTSIZE>0
|
||||
UEFISIZE=${UEFISIZE:-0}
|
||||
BIOSSIZE=${BIOSSIZE:-0}
|
||||
UEFI_MOUNT_POINT=${UEFI_MOUNT_POINT:-/boot/efi}
|
||||
UEFI_FS_LABEL="${UEFI_FS_LABEL:-armbiefi}"
|
||||
|
||||
call_extension_method "pre_prepare_partitions" "prepare_partitions_custom" <<'PRE_PREPARE_PARTITIONS'
|
||||
*allow custom options for mkfs*
|
||||
Good time to change stuff like mkfs opts, types etc.
|
||||
PRE_PREPARE_PARTITIONS
|
||||
|
||||
# stage: determine partition configuration
|
||||
if [[ -n $BOOTFS_TYPE ]]; then
|
||||
@@ -483,6 +500,16 @@ prepare_partitions()
|
||||
local bootpart=1
|
||||
local rootpart=2
|
||||
[[ -z $BOOTSIZE || $BOOTSIZE -le 8 ]] && BOOTSIZE=${DEFAULT_BOOTSIZE}
|
||||
elif [[ $UEFISIZE -gt 0 ]]; then
|
||||
if [[ "${IMAGE_PARTITION_TABLE}" == "gpt" ]]; then
|
||||
# efi partition and ext4 root. some juggling is done by parted/sgdisk
|
||||
local uefipart=15
|
||||
local rootpart=1
|
||||
else
|
||||
# efi partition and ext4 root.
|
||||
local uefipart=1
|
||||
local rootpart=2
|
||||
fi
|
||||
else
|
||||
# single partition ext4 root
|
||||
local rootpart=1
|
||||
@@ -490,8 +517,17 @@ prepare_partitions()
|
||||
fi
|
||||
|
||||
# stage: calculate rootfs size
|
||||
local rootfs_size=$(du -sm $SDCARD/ | cut -f1) # MiB
|
||||
export rootfs_size=$(du -sm $SDCARD/ | cut -f1) # MiB
|
||||
display_alert "Current rootfs size" "$rootfs_size MiB" "info"
|
||||
|
||||
call_extension_method "prepare_image_size" "config_prepare_image_size" << 'PREPARE_IMAGE_SIZE'
|
||||
*allow dynamically determining the size based on the $rootfs_size*
|
||||
Called after `${rootfs_size}` is known, but before `${FIXED_IMAGE_SIZE}` is taken into account.
|
||||
A good spot to determine `FIXED_IMAGE_SIZE` based on `rootfs_size`.
|
||||
UEFISIZE can be set to 0 for no UEFI partition, or to a size in MiB to include one.
|
||||
Last chance to set `USE_HOOK_FOR_PARTITION`=yes and then implement create_partition_table hook_point.
|
||||
PREPARE_IMAGE_SIZE
|
||||
|
||||
if [[ -n $FIXED_IMAGE_SIZE && $FIXED_IMAGE_SIZE =~ ^[0-9]+$ ]]; then
|
||||
display_alert "Using user-defined image size" "$FIXED_IMAGE_SIZE MiB" "info"
|
||||
local sdsize=$FIXED_IMAGE_SIZE
|
||||
@@ -500,7 +536,7 @@ prepare_partitions()
|
||||
exit_with_error "User defined image size is too small" "$sdsize <= $rootfs_size"
|
||||
fi
|
||||
else
|
||||
local imagesize=$(( $rootfs_size + $OFFSET + $BOOTSIZE )) # MiB
|
||||
local imagesize=$(( $rootfs_size + $OFFSET + $BOOTSIZE + $UEFISIZE + $EXTRA_ROOTFS_MIB_SIZE)) # MiB
|
||||
case $ROOTFS_TYPE in
|
||||
btrfs)
|
||||
# Used for server images, currently no swap functionality, so disk space
|
||||
@@ -534,23 +570,69 @@ prepare_partitions()
|
||||
|
||||
# stage: calculate boot partition size
|
||||
local bootstart=$(($OFFSET * 2048))
|
||||
local rootstart=$(($bootstart + ($BOOTSIZE * 2048)))
|
||||
local rootstart=$(($bootstart + ($BOOTSIZE * 2048) + ($UEFISIZE * 2048)))
|
||||
local bootend=$(($rootstart - 1))
|
||||
|
||||
# stage: create partition table
|
||||
display_alert "Creating partitions" "${bootfs:+/boot: $bootfs }root: $ROOTFS_TYPE" "info"
|
||||
parted -s ${SDCARD}.raw -- mklabel ${IMAGE_PARTITION_TABLE}
|
||||
if [[ $ROOTFS_TYPE == nfs ]]; then
|
||||
if [[ "${USE_HOOK_FOR_PARTITION}" == "yes" ]]; then
|
||||
call_extension_method "create_partition_table" <<- 'CREATE_PARTITION_TABLE'
|
||||
*only called when USE_HOOK_FOR_PARTITION=yes to create the complete partition table*
|
||||
Finally, we can get our own partition table. You have to partition ${SDCARD}.raw
|
||||
yourself. Good luck.
|
||||
CREATE_PARTITION_TABLE
|
||||
elif [[ $ROOTFS_TYPE == nfs ]]; then
|
||||
# single /boot partition
|
||||
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$bootfs]} ${bootstart}s 100%
|
||||
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$bootfs]} ${bootstart}s "100%"
|
||||
elif [[ $UEFISIZE -gt 0 ]]; then
|
||||
# uefi partition + root partition
|
||||
if [[ "${IMAGE_PARTITION_TABLE}" == "gpt" ]]; then
|
||||
if [[ ${BIOSSIZE} -gt 0 ]]; then
|
||||
display_alert "Creating partitions" "BIOS+UEFI+rootfs" "info"
|
||||
# UEFI + GPT automatically get a BIOS partition at 14, EFI at 15
|
||||
local biosstart=$(($OFFSET * 2048))
|
||||
local uefistart=$(($OFFSET * 2048 + ($BIOSSIZE * 2048)))
|
||||
local rootstart=$(($uefistart + ($UEFISIZE * 2048) ))
|
||||
local biosend=$(($uefistart - 1))
|
||||
local uefiend=$(($rootstart - 1))
|
||||
parted -s ${SDCARD}.raw -- mkpart bios fat32 ${biosstart}s ${biosend}s
|
||||
parted -s ${SDCARD}.raw -- mkpart efi fat32 ${uefistart}s ${uefiend}s
|
||||
parted -s ${SDCARD}.raw -- mkpart rootfs ${parttype[$ROOTFS_TYPE]} ${rootstart}s "100%"
|
||||
# transpose so BIOS is in sda14; EFI is in sda15 and root in sda1; requires sgdisk, parted cant do numbers
|
||||
sgdisk --transpose 1:14 ${SDCARD}.raw &> /dev/null || echo "*** TRANSPOSE 1:14 FAILED"
|
||||
sgdisk --transpose 2:15 ${SDCARD}.raw &> /dev/null || echo "*** TRANSPOSE 2:15 FAILED"
|
||||
sgdisk --transpose 3:1 ${SDCARD}.raw &> /dev/null || echo "*** TRANSPOSE 3:1 FAILED"
|
||||
# set the ESP (efi) flag on 15
|
||||
parted -s ${SDCARD}.raw -- set 14 bios_grub on || echo "*** SETTING bios_grub ON 14 FAILED"
|
||||
parted -s ${SDCARD}.raw -- set 15 esp on || echo "*** SETTING ESP ON 15 FAILED"
|
||||
else
|
||||
display_alert "Creating partitions" "UEFI+rootfs (no BIOS)" "info"
|
||||
# Simple EFI + root partition on GPT, no BIOS.
|
||||
parted -s ${SDCARD}.raw -- mkpart efi fat32 ${bootstart}s ${bootend}s
|
||||
parted -s ${SDCARD}.raw -- mkpart rootfs ${parttype[$ROOTFS_TYPE]} ${rootstart}s "100%"
|
||||
# transpose so EFI is in sda15 and root in sda1; requires sgdisk, parted cant do numbers
|
||||
sgdisk --transpose 1:15 ${SDCARD}.raw &> /dev/null || echo "*** TRANSPOSE 1:15 FAILED"
|
||||
sgdisk --transpose 2:1 ${SDCARD}.raw &> /dev/null || echo "*** TRANSPOSE 2:1 FAILED"
|
||||
# set the ESP (efi) flag on 15
|
||||
parted -s ${SDCARD}.raw -- set 15 esp on || echo "*** SETTING ESP ON 15 FAILED"
|
||||
fi
|
||||
else
|
||||
parted -s ${SDCARD}.raw -- mkpart primary fat32 ${bootstart}s ${bootend}s
|
||||
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s "100%"
|
||||
fi
|
||||
elif [[ $BOOTSIZE == 0 ]]; then
|
||||
# single root partition
|
||||
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s 100%
|
||||
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s "100%"
|
||||
else
|
||||
# /boot partition + root partition
|
||||
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$bootfs]} ${bootstart}s ${bootend}s
|
||||
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s 100%
|
||||
parted -s ${SDCARD}.raw -- mkpart primary ${parttype[$ROOTFS_TYPE]} ${rootstart}s "100%"
|
||||
fi
|
||||
|
||||
call_extension_method "post_create_partitions" <<- 'POST_CREATE_PARTITIONS'
|
||||
*called after all partitions are created, but not yet formatted*
|
||||
POST_CREATE_PARTITIONS
|
||||
|
||||
# stage: mount image
|
||||
# lock access to loop devices
|
||||
@@ -609,9 +691,22 @@ prepare_partitions()
|
||||
mount ${LOOP}p${bootpart} $MOUNT/boot/
|
||||
echo "UUID=$(blkid -s UUID -o value ${LOOP}p${bootpart}) /boot ${mkfs[$bootfs]} defaults${mountopts[$bootfs]} 0 2" >> $SDCARD/etc/fstab
|
||||
fi
|
||||
if [[ -n $uefipart ]]; then
|
||||
display_alert "Creating EFI partition" "FAT32 ${UEFI_MOUNT_POINT} on ${LOOP}p${uefipart} label ${UEFI_FS_LABEL}"
|
||||
check_loop_device "${LOOP}p${uefipart}"
|
||||
mkfs.fat -F32 -n "${UEFI_FS_LABEL}" ${LOOP}p${uefipart} >>"${DEST}"/debug/install.log 2>&1
|
||||
mkdir -p "${MOUNT}${UEFI_MOUNT_POINT}"
|
||||
mount ${LOOP}p${uefipart} "${MOUNT}${UEFI_MOUNT_POINT}"
|
||||
echo "UUID=$(blkid -s UUID -o value ${LOOP}p${uefipart}) ${UEFI_MOUNT_POINT} vfat defaults 0 2" >>$SDCARD/etc/fstab
|
||||
fi
|
||||
[[ $ROOTFS_TYPE == nfs ]] && echo "/dev/nfs / nfs defaults 0 0" >> $SDCARD/etc/fstab
|
||||
echo "tmpfs /tmp tmpfs defaults,nosuid 0 0" >> $SDCARD/etc/fstab
|
||||
|
||||
call_extension_method "format_partitions" <<- 'FORMAT_PARTITIONS'
|
||||
*if you created your own partitions, this would be a good time to format them*
|
||||
The loop device is mounted, so ${LOOP}p1 is it's first partition etc.
|
||||
FORMAT_PARTITIONS
|
||||
|
||||
# stage: adjust boot script or boot environment
|
||||
if [[ -f $SDCARD/boot/armbianEnv.txt ]]; then
|
||||
if [[ $CRYPTROOT_ENABLE == yes ]]; then
|
||||
@@ -691,7 +786,10 @@ update_initramfs()
|
||||
cp /usr/bin/$QEMU_BINARY $chroot_target/usr/bin/
|
||||
mount_chroot "$chroot_target/"
|
||||
|
||||
chroot $chroot_target /bin/bash -c "$update_initramfs_cmd" >> $DEST/${LOG_SUBPATH}/install.log 2>&1
|
||||
chroot $chroot_target /bin/bash -c "$update_initramfs_cmd" >> $DEST/${LOG_SUBPATH}/install.log 2>&1 || {
|
||||
display_alert "Updating initramfs FAILED, see:" "$DEST/${LOG_SUBPATH}/install.log" "err"
|
||||
exit 23
|
||||
}
|
||||
display_alert "Updated initramfs." "for details see: $DEST/${LOG_SUBPATH}/install.log" "info"
|
||||
|
||||
display_alert "Re-enabling" "initramfs-tools hook for kernel"
|
||||
@@ -708,6 +806,9 @@ update_initramfs()
|
||||
#
|
||||
create_image()
|
||||
{
|
||||
# create DESTIMG, hooks might put stuff there early.
|
||||
mkdir -p $DESTIMG
|
||||
|
||||
# stage: create file name
|
||||
local version="${VENDOR}_${REVISION}_${BOARD^}_${RELEASE}_${BRANCH}_${VER/-$LINUXFAMILY/}${DESKTOP_ENVIRONMENT:+_$DESKTOP_ENVIRONMENT}"
|
||||
[[ $BUILD_DESKTOP == yes ]] && version=${version}_desktop
|
||||
@@ -734,8 +835,15 @@ create_image()
|
||||
rsync -aHWXh --info=progress2,stats1 $SDCARD/boot $MOUNT >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
|
||||
fi
|
||||
|
||||
call_extension_method "pre_update_initramfs" "config_pre_update_initramfs" << 'PRE_UPDATE_INITRAMFS'
|
||||
*allow config to hack into the initramfs create process*
|
||||
Called after rsync has synced both `/root` and `/root` on the target, but before calling `update_initramfs`.
|
||||
PRE_UPDATE_INITRAMFS
|
||||
|
||||
# stage: create final initramfs
|
||||
update_initramfs $MOUNT
|
||||
[[ -n $KERNELSOURCE ]] && {
|
||||
update_initramfs $MOUNT
|
||||
}
|
||||
|
||||
# DEBUG: print free space
|
||||
local freespace=$(LC_ALL=C df -h)
|
||||
@@ -743,27 +851,39 @@ create_image()
|
||||
display_alert "Free SD cache" "$(echo -e "$freespace" | grep $SDCARD | awk '{print $5}')" "info"
|
||||
display_alert "Mount point" "$(echo -e "$freespace" | grep $MOUNT | head -1 | awk '{print $5}')" "info"
|
||||
|
||||
# stage: write u-boot
|
||||
write_uboot $LOOP
|
||||
# stage: write u-boot, unless the deb is not there, which would happen if BOOTCONFIG=none
|
||||
[[ -f "${DEB_STORAGE}"/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb ]] && write_uboot $LOOP
|
||||
|
||||
# fix wrong / permissions
|
||||
chmod 755 $MOUNT
|
||||
|
||||
# unmount /boot first, rootfs second, image file last
|
||||
call_extension_method "pre_umount_final_image" "config_pre_umount_final_image" << 'PRE_UMOUNT_FINAL_IMAGE'
|
||||
*allow config to hack into the image before the unmount*
|
||||
Called before unmounting both `/root` and `/boot`.
|
||||
PRE_UMOUNT_FINAL_IMAGE
|
||||
|
||||
# unmount /boot/efi first, then /boot, rootfs third, image file last
|
||||
sync
|
||||
[[ $UEFISIZE != 0 ]] && umount -l "${MOUNT}${UEFI_MOUNT_POINT}"
|
||||
[[ $BOOTSIZE != 0 ]] && umount -l $MOUNT/boot
|
||||
[[ $ROOTFS_TYPE != nfs ]] && umount -l $MOUNT
|
||||
[[ $CRYPTROOT_ENABLE == yes ]] && cryptsetup luksClose $ROOT_MAPPER
|
||||
|
||||
call_extension_method "post_umount_final_image" "config_post_umount_final_image" << 'POST_UMOUNT_FINAL_IMAGE'
|
||||
*allow config to hack into the image after the unmount*
|
||||
Called after unmounting both `/root` and `/boot`.
|
||||
POST_UMOUNT_FINAL_IMAGE
|
||||
|
||||
# to make sure its unmounted
|
||||
while grep -Eq '(${MOUNT}|${DESTIMG})' /proc/mounts
|
||||
do
|
||||
display_alert "Unmounting" "${MOUNT}" "info"
|
||||
display_alert "Wait for unmount" "${MOUNT}" "info"
|
||||
sleep 5
|
||||
done
|
||||
|
||||
losetup -d $LOOP
|
||||
rm -rf --one-file-system $DESTIMG $MOUNT
|
||||
# Don't delete $DESTIMG here, extensions might have put nice things there already.
|
||||
rm -rf --one-file-system $MOUNT
|
||||
|
||||
mkdir -p $DESTIMG
|
||||
mv ${SDCARD}.raw $DESTIMG/${version}.img
|
||||
@@ -858,13 +978,20 @@ create_image()
|
||||
fi
|
||||
display_alert "Done building" "${DESTIMG}/${version}.img" "info"
|
||||
|
||||
# call custom post build hook
|
||||
[[ $(type -t post_build_image) == function ]] && post_build_image "${DESTIMG}/${version}.img"
|
||||
# Previously, post_build_image passed the .img path as an argument to the hook. Now its an ENV var.
|
||||
export FINAL_IMAGE_FILE="${DESTIMG}/${version}.img"
|
||||
call_extension_method "post_build_image" << 'POST_BUILD_IMAGE'
|
||||
*custom post build hook*
|
||||
Called after the final .img file is built, before it is (possibly) written to an SD writer.
|
||||
- *NOTE*: this hook used to take an argument ($1) for the final image produced.
|
||||
- Now it is passed as an environment variable `${FINAL_IMAGE_FILE}`
|
||||
It is the last possible chance to modify `$CARD_DEVICE`.
|
||||
POST_BUILD_IMAGE
|
||||
|
||||
# move artefacts from temporally directory to its final destination
|
||||
[[ -n $compression_type ]] && rm $DESTIMG/${version}.img
|
||||
rsync -a --no-owner --no-group --remove-source-files $DESTIMG/${version}* ${FINALDEST}
|
||||
rm -rf $DESTIMG
|
||||
rm -rf --one-file-system $DESTIMG
|
||||
|
||||
# write image to SD card
|
||||
if [[ $(lsblk "$CARD_DEVICE" 2>/dev/null) && -f ${FINALDEST}/${version}.img ]]; then
|
||||
@@ -881,13 +1008,21 @@ create_image()
|
||||
# write to SD card
|
||||
pv -p -b -r -c -N "[ .... ] dd" ${FINALDEST}/${version}.img | dd of=$CARD_DEVICE bs=1M iflag=fullblock oflag=direct status=none
|
||||
|
||||
# read and compare
|
||||
display_alert "Verifying. Please wait!"
|
||||
local ofsha=$(dd if=$CARD_DEVICE count=$(du -b ${FINALDEST}/${version}.img | cut -f1) status=none iflag=count_bytes oflag=direct | sha256sum | awk '{print $1}')
|
||||
if [[ $ifsha == $ofsha ]]; then
|
||||
display_alert "Writing verified" "${version}.img" "info"
|
||||
else
|
||||
display_alert "Writing failed" "${version}.img" "err"
|
||||
call_extension_method "post_write_sdcard" <<- 'POST_BUILD_IMAGE'
|
||||
*run after writing img to sdcard*
|
||||
After the image is written to `$CARD_DEVICE`, but before verifying it.
|
||||
You can still set SKIP_VERIFY=yes to skip verification.
|
||||
POST_BUILD_IMAGE
|
||||
|
||||
if [[ "${SKIP_VERIFY}" != "yes" ]]; then
|
||||
# read and compare
|
||||
display_alert "Verifying. Please wait!"
|
||||
local ofsha=$(dd if=$CARD_DEVICE count=$(du -b ${FINALDEST}/${version}.img | cut -f1) status=none iflag=count_bytes oflag=direct | sha256sum | awk '{print $1}')
|
||||
if [[ $ifsha == $ofsha ]]; then
|
||||
display_alert "Writing verified" "${version}.img" "info"
|
||||
else
|
||||
display_alert "Writing failed" "${version}.img" "err"
|
||||
fi
|
||||
fi
|
||||
elif [[ `systemd-detect-virt` == 'docker' && -n $CARD_DEVICE ]]; then
|
||||
# display warning when we want to write sd card under Docker
|
||||
|
||||
@@ -186,10 +186,12 @@ install_common()
|
||||
fi
|
||||
else
|
||||
|
||||
if [ -f "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" ]; then
|
||||
cp "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}"
|
||||
else
|
||||
cp "${SRC}/config/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}"
|
||||
if [[ "${BOOTCONFIG}" != "none" ]]; then
|
||||
if [ -f "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" ]; then
|
||||
cp "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}"
|
||||
else
|
||||
cp "${SRC}/config/bootscripts/${bootscript_src}" "${SDCARD}/boot/${bootscript_dst}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ -n $BOOTENV_FILE ]]; then
|
||||
@@ -240,60 +242,86 @@ install_common()
|
||||
|
||||
cd $SRC
|
||||
|
||||
# Prepare and export caching-related params common to all apt calls below, to maximize apt-cacher-ng usage
|
||||
export APT_EXTRA_DIST_PARAMS=""
|
||||
[[ $NO_APT_CACHER != yes ]] && APT_EXTRA_DIST_PARAMS="-o Acquire::http::Proxy=\"http://${APT_PROXY_ADDR:-localhost:3142}\" -o Acquire::http::Proxy::localhost=\"DIRECT\""
|
||||
|
||||
display_alert "Updating" "package lists"
|
||||
chroot "${SDCARD}" /bin/bash -c "apt-get update" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
|
||||
chroot "${SDCARD}" /bin/bash -c "apt-get ${APT_EXTRA_DIST_PARAMS} update" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
|
||||
|
||||
display_alert "Temporarily disabling" "initramfs-tools hook for kernel"
|
||||
chroot "${SDCARD}" /bin/bash -c "chmod -v -x /etc/kernel/postinst.d/initramfs-tools" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
|
||||
|
||||
# install family packages
|
||||
if [[ -n ${PACKAGE_LIST_FAMILY} ]]; then
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq --no-install-recommends install $PACKAGE_LIST_FAMILY" >> "${DEST}"/${LOG_SUBPATH}/install.log
|
||||
display_alert "Installing PACKAGE_LIST_FAMILY packages" "${PACKAGE_LIST_FAMILY}"
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq --no-install-recommends install $PACKAGE_LIST_FAMILY" >> "${DEST}"/${LOG_SUBPATH}/install.log
|
||||
fi
|
||||
|
||||
# install board packages
|
||||
if [[ -n ${PACKAGE_LIST_BOARD} ]]; then
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq --no-install-recommends install $PACKAGE_LIST_BOARD" >> "${DEST}"/${LOG_SUBPATH}/install.log
|
||||
display_alert "Installing PACKAGE_LIST_BOARD packages" "${PACKAGE_LIST_BOARD}"
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq --no-install-recommends install $PACKAGE_LIST_BOARD" >> "${DEST}"/${LOG_SUBPATH}/install.log || { display_alert "Failed to install PACKAGE_LIST_BOARD" "${PACKAGE_LIST_BOARD}" "err"; exit 2; }
|
||||
fi
|
||||
|
||||
# remove family packages
|
||||
if [[ -n ${PACKAGE_LIST_FAMILY_REMOVE} ]]; then
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq remove --auto-remove $PACKAGE_LIST_FAMILY_REMOVE" >> "${DEST}"/${LOG_SUBPATH}/install.log
|
||||
display_alert "Removing PACKAGE_LIST_FAMILY_REMOVE packages" "${PACKAGE_LIST_FAMILY_REMOVE}"
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq remove --auto-remove $PACKAGE_LIST_FAMILY_REMOVE" >> "${DEST}"/${LOG_SUBPATH}/install.log
|
||||
fi
|
||||
|
||||
# remove board packages
|
||||
if [[ -n ${PACKAGE_LIST_BOARD_REMOVE} ]]; then
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get -yqq remove --auto-remove $PACKAGE_LIST_BOARD_REMOVE" >> "${DEST}"/${LOG_SUBPATH}/install.log
|
||||
display_alert "Removing PACKAGE_LIST_BOARD_REMOVE packages" "${PACKAGE_LIST_BOARD_REMOVE}"
|
||||
for PKG_REMOVE in ${PACKAGE_LIST_BOARD_REMOVE}; do
|
||||
chroot "${SDCARD}" /bin/bash -c "DEBIAN_FRONTEND=noninteractive apt-get ${APT_EXTRA_DIST_PARAMS} -yqq remove --auto-remove ${PKG_REMOVE}" >> "${DEST}"/${LOG_SUBPATH}/install.log
|
||||
done
|
||||
fi
|
||||
|
||||
# install u-boot
|
||||
if [[ "${REPOSITORY_INSTALL}" != *u-boot* ]]; then
|
||||
UBOOT_VER=$(dpkg --info "${DEB_STORAGE}/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
|
||||
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb"
|
||||
else
|
||||
install_deb_chroot "linux-u-boot-${BOARD}-${BRANCH}" "remote" "yes"
|
||||
UPSTREM_VER=$(dpkg-deb -f "${SDCARD}"/var/cache/apt/archives/linux-u-boot-${BOARD}-${BRANCH}*_${ARCH}.deb Version)
|
||||
fi
|
||||
|
||||
# @TODO: add install_bootloader() extension method, refactor into u-boot extension
|
||||
[[ "${BOOTCONFIG}" != "none" ]] && {
|
||||
if [[ "${REPOSITORY_INSTALL}" != *u-boot* ]]; then
|
||||
UBOOT_VER=$(dpkg --info "${DEB_STORAGE}/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb" | grep Descr | awk '{print $(NF)}')
|
||||
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb"
|
||||
else
|
||||
install_deb_chroot "linux-u-boot-${BOARD}-${BRANCH}" "remote" "yes"
|
||||
UPSTREM_VER=$(dpkg-deb -f "${SDCARD}"/var/cache/apt/archives/linux-u-boot-${BOARD}-${BRANCH}*_${ARCH}.deb Version)
|
||||
fi
|
||||
}
|
||||
|
||||
call_extension_method "pre_install_kernel_debs" << 'PRE_INSTALL_KERNEL_DEBS'
|
||||
*called before installing the Armbian-built kernel deb packages*
|
||||
It is not too late to `unset KERNELSOURCE` here and avoid kernel install.
|
||||
PRE_INSTALL_KERNEL_DEBS
|
||||
|
||||
# install kernel
|
||||
if [[ "${REPOSITORY_INSTALL}" != *kernel* ]]; then
|
||||
VER=$(dpkg --info "${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" | awk -F"-" '/Source:/{print $2}')
|
||||
[[ -n $KERNELSOURCE ]] && {
|
||||
if [[ "${REPOSITORY_INSTALL}" != *kernel* ]]; then
|
||||
VER=$(dpkg --info "${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb" | awk -F"-" '/Source:/{print $2}')
|
||||
|
||||
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb"
|
||||
if [[ -f ${DEB_STORAGE}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb ]]; then
|
||||
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb"
|
||||
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb"
|
||||
if [[ -f ${DEB_STORAGE}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb ]]; then
|
||||
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL/image/dtb}_${REVISION}_${ARCH}.deb"
|
||||
fi
|
||||
if [[ $INSTALL_HEADERS == yes ]]; then
|
||||
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL/image/headers}_${REVISION}_${ARCH}.deb"
|
||||
fi
|
||||
else
|
||||
install_deb_chroot "linux-image-${BRANCH}-${LINUXFAMILY}" "remote"
|
||||
VER=$(dpkg-deb -f "${SDCARD}"/var/cache/apt/archives/linux-image-${BRANCH}-${LINUXFAMILY}*_${ARCH}.deb Source)
|
||||
VER="${VER/-$LINUXFAMILY/}"
|
||||
VER="${VER/linux-/}"
|
||||
install_deb_chroot "linux-dtb-${BRANCH}-${LINUXFAMILY}" "remote"
|
||||
[[ $INSTALL_HEADERS == yes ]] && install_deb_chroot "linux-headers-${BRANCH}-${LINUXFAMILY}" "remote"
|
||||
fi
|
||||
if [[ $INSTALL_HEADERS == yes ]]; then
|
||||
install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KERNEL/image/headers}_${REVISION}_${ARCH}.deb"
|
||||
fi
|
||||
else
|
||||
install_deb_chroot "linux-image-${BRANCH}-${LINUXFAMILY}" "remote"
|
||||
VER=$(dpkg-deb -f "${SDCARD}"/var/cache/apt/archives/linux-image-${BRANCH}-${LINUXFAMILY}*_${ARCH}.deb Source)
|
||||
VER="${VER/-$LINUXFAMILY/}"
|
||||
VER="${VER/linux-/}"
|
||||
install_deb_chroot "linux-dtb-${BRANCH}-${LINUXFAMILY}" "remote"
|
||||
[[ $INSTALL_HEADERS == yes ]] && install_deb_chroot "linux-headers-${BRANCH}-${LINUXFAMILY}" "remote"
|
||||
fi
|
||||
}
|
||||
|
||||
call_extension_method "post_install_kernel_debs" << 'POST_INSTALL_KERNEL_DEBS'
|
||||
*allow config to do more with the installed kernel/headers*
|
||||
Called after packages, u-boot, kernel and headers installed in the chroot, but before the BSP is installed.
|
||||
If `KERNELSOURCE` is (still?) unset after this, Armbian-built firmware will not be installed.
|
||||
POST_INSTALL_KERNEL_DEBS
|
||||
|
||||
# install board support packages
|
||||
if [[ "${REPOSITORY_INSTALL}" != *bsp* ]]; then
|
||||
@@ -318,14 +346,16 @@ install_common()
|
||||
fi
|
||||
fi
|
||||
|
||||
# install armbian-firmware
|
||||
if [[ "${REPOSITORY_INSTALL}" != *armbian-firmware* ]]; then
|
||||
if [[ -f ${DEB_STORAGE}/armbian-firmware_${REVISION}_all.deb ]]; then
|
||||
install_deb_chroot "${DEB_STORAGE}/armbian-firmware_${REVISION}_all.deb"
|
||||
# install armbian-firmware by default. Set BOARD_FIRMWARE_INSTALL="-full" to install full firmware variant
|
||||
[[ "${INSTALL_ARMBIAN_FIRMWARE:-yes}" == "yes" ]] && {
|
||||
if [[ "${REPOSITORY_INSTALL}" != *armbian-firmware* ]]; then
|
||||
if [[ -f ${DEB_STORAGE}/armbian-firmware_${REVISION}_all.deb ]]; then
|
||||
install_deb_chroot "${DEB_STORAGE}/armbian-firmware${BOARD_FIRMWARE_INSTALL:-""}_${REVISION}_all.deb"
|
||||
fi
|
||||
else
|
||||
install_deb_chroot "armbian-firmware${BOARD_FIRMWARE_INSTALL:-""}" "remote"
|
||||
fi
|
||||
else
|
||||
install_deb_chroot "armbian-firmware" "remote"
|
||||
fi
|
||||
}
|
||||
|
||||
# install armbian-config
|
||||
if [[ "${PACKAGE_LIST_RM}" != *armbian-config* ]]; then
|
||||
@@ -379,6 +409,12 @@ install_common()
|
||||
# execute $LINUXFAMILY-specific tweaks
|
||||
[[ $(type -t family_tweaks) == function ]] && family_tweaks
|
||||
|
||||
call_extension_method "post_family_tweaks" << 'FAMILY_TWEAKS'
|
||||
*customize the tweaks made by $LINUXFAMILY-specific family_tweaks*
|
||||
It is run after packages are installed in the rootfs, but before enabling additional services.
|
||||
It allows implementors access to the rootfs (`${SDCARD}`) in its pristine state after packages are installed.
|
||||
FAMILY_TWEAKS
|
||||
|
||||
# enable additional services
|
||||
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable armbian-firstrun.service >/dev/null 2>&1"
|
||||
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable armbian-firstrun-config.service >/dev/null 2>&1"
|
||||
@@ -429,6 +465,8 @@ install_common()
|
||||
for i in $(echo "${SERIALCON:-'ttyS0'}" | sed "s/,/ /g")
|
||||
do
|
||||
IFS=':' read -r -a array <<< "$i"
|
||||
[[ "${array[0]}" == "tty1" ]] && continue # Don't enable tty1 as serial console.
|
||||
display_alert "Enabling serial console" "${array[0]}" "info"
|
||||
# add serial console to secure tty list
|
||||
[ -z "$(grep -w '^${array[0]}' "${SDCARD}"/etc/securetty 2> /dev/null)" ] && \
|
||||
echo "${array[0]}" >> "${SDCARD}"/etc/securetty
|
||||
@@ -439,7 +477,6 @@ install_common()
|
||||
sed -i "s/--keep-baud 115200/--keep-baud ${array[1]},115200/" \
|
||||
"${SDCARD}/lib/systemd/system/serial-getty@${array[0]}.service"
|
||||
fi
|
||||
display_alert "Enabling serial console" "${array[0]}" "info"
|
||||
chroot "${SDCARD}" /bin/bash -c "systemctl daemon-reload" >> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
|
||||
chroot "${SDCARD}" /bin/bash -c "systemctl --no-reload enable serial-getty@${array[0]}.service" \
|
||||
>> "${DEST}"/${LOG_SUBPATH}/install.log 2>&1
|
||||
@@ -670,4 +707,10 @@ post_debootstrap_tweaks()
|
||||
chroot "${SDCARD}" /bin/bash -c "dpkg-divert --quiet --local --rename --remove /sbin/start-stop-daemon"
|
||||
rm -f "${SDCARD}"/usr/sbin/policy-rc.d "${SDCARD}/usr/bin/${QEMU_BINARY}"
|
||||
|
||||
call_extension_method "post_post_debootstrap_tweaks" "config_post_debootstrap_tweaks" << 'POST_POST_DEBOOTSTRAP_TWEAKS'
|
||||
*run after removing diversions and qemu with chroot unmounted*
|
||||
Last chance to touch the `${SDCARD}` filesystem before it is copied to the final media.
|
||||
It is too late to run any chrooted commands, since the supporting filesystems are already unmounted.
|
||||
POST_POST_DEBOOTSTRAP_TWEAKS
|
||||
|
||||
}
|
||||
|
||||
447
lib/extensions.sh
Normal file
447
lib/extensions.sh
Normal file
@@ -0,0 +1,447 @@
|
||||
# global variables managing the state of the extension manager. treat as private.
|
||||
declare -A extension_function_info # maps a function name to a string with KEY=VALUEs information about the defining extension
|
||||
declare -i initialize_extension_manager_counter=0 # how many times has the extension manager initialized?
|
||||
declare -A defined_hook_point_functions # keeps a map of hook point functions that were defined and their extension info
|
||||
declare -A hook_point_function_trace_sources # keeps a map of hook point functions that were actually called and their source
|
||||
declare -A hook_point_function_trace_lines # keeps a map of hook point functions that were actually called and their source
|
||||
declare fragment_manager_cleanup_file # this is a file used to cleanup the manager's produced functions, for build_all_ng
|
||||
# configuration.
|
||||
export DEBUG_EXTENSION_CALLS=no # set to yes to log every hook function called to the main build log
|
||||
export LOG_ENABLE_EXTENSION=yes # colorful logs with stacktrace when enable_extension is called.
|
||||
|
||||
# This is a helper function for calling hooks.
|
||||
# It follows the pattern long used in the codebase for hook-like behaviour:
|
||||
# [[ $(type -t name_of_hook_function) == function ]] && name_of_hook_function
|
||||
# but with the following added behaviors:
|
||||
# 1) it allows for many arguments, and will treat each as a hook point.
|
||||
# this allows for easily kept backwards compatibility when renaming hooks, for example.
|
||||
# 2) it will read the stdin and assume it's (Markdown) documentation for the hook point.
|
||||
# combined with heredoc in the call site, it allows for "inline" documentation about the hook
|
||||
# notice: this is not involved in how the hook functions came to be. read below for that.
|
||||
call_extension_method() {
|
||||
# First, consume the stdin and write metadata about the call.
|
||||
write_hook_point_metadata "$@" || true
|
||||
|
||||
# @TODO: hack to handle stdin again, possibly with '< /dev/tty'
|
||||
|
||||
# Then a sanity check, hook points should only be invoked after the manager has initialized.
|
||||
if [[ ${initialize_extension_manager_counter} -lt 1 ]]; then
|
||||
display_alert "Extension problem" "Call to call_extension_method() (in ${BASH_SOURCE[1]- $(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")}) before extension manager is initialized." "err"
|
||||
fi
|
||||
|
||||
# With DEBUG_EXTENSION_CALLS, log the hook call. Users might be wondering what/when is a good hook point to use, and this is visual aid.
|
||||
[[ "${DEBUG_EXTENSION_CALLS}" == "yes" ]] &&
|
||||
display_alert "--> Extension Method '${1}' being called from" "$(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")" ""
|
||||
|
||||
# Then call the hooks, if they are defined.
|
||||
for hook_name in "$@"; do
|
||||
echo "-- Extension Method being called: ${hook_name}" >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
# shellcheck disable=SC2086
|
||||
[[ $(type -t ${hook_name}) == function ]] && { ${hook_name}; }
|
||||
done
|
||||
}
|
||||
|
||||
# what this does is a lot of bash mumbo-jumbo to find all board-,family-,config- or user-defined hook points.
|
||||
# the meat of this is 'compgen -A function', which is bash builtin that lists all defined functions.
|
||||
# it will then compose a full hook point (function) that calls all the implementing hooks.
|
||||
# this centralized function will then be called by the regular Armbian build system, which is oblivious to how
|
||||
# it came to be. (although it is encouraged to call hook points via call_extension_method() above)
|
||||
# to avoid hard coding the list of hook-points (eg: user_config, image_tweaks_pre_customize, etc) we use
|
||||
# a marker in the function names, namely "__" (two underscores) to determine the hook point.
|
||||
initialize_extension_manager() {
|
||||
# before starting, auto-add extensions specified (eg, on the command-line) via the ENABLE_EXTENSIONS env var. Do it only once.
|
||||
[[ ${initialize_extension_manager_counter} -lt 1 ]] && [[ "${ENABLE_EXTENSIONS}" != "" ]] && {
|
||||
local auto_extension
|
||||
for auto_extension in $(echo "${ENABLE_EXTENSIONS}" | tr "," " "); do
|
||||
ENABLE_EXTENSION_TRACE_HINT="ENABLE_EXTENSIONS -> " enable_extension "${auto_extension}"
|
||||
done
|
||||
}
|
||||
|
||||
# This marks the manager as initialized, no more extensions are allowed to load after this.
|
||||
export initialize_extension_manager_counter=$((initialize_extension_manager_counter + 1))
|
||||
|
||||
# Have a unique temporary dir, even if being built concurrently by build_all_ng.
|
||||
export EXTENSION_MANAGER_TMP_DIR="${SRC}/.tmp/.extensions/${LOG_SUBPATH}"
|
||||
mkdir -p "${EXTENSION_MANAGER_TMP_DIR}"
|
||||
|
||||
# Log destination.
|
||||
export EXTENSION_MANAGER_LOG_FILE="${EXTENSION_MANAGER_TMP_DIR}/extensions.log"
|
||||
echo -n "" >"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt"
|
||||
|
||||
# globally initialize the extensions log.
|
||||
echo "-- lib/extensions.sh included. logs will be below, followed by the debug generated by the initialize_extension_manager() function." >"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
|
||||
# log whats happening.
|
||||
echo "-- initialize_extension_manager() called." >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
|
||||
# this is the all-important separator.
|
||||
local hook_extension_delimiter="__"
|
||||
|
||||
# list all defined functions. filter only the ones that have the delimiter. get only the part before the delimiter.
|
||||
# sort them, and make them unique. the sorting is required for uniq to work, and does not affect the ordering of execution.
|
||||
# get them on a single line, space separated.
|
||||
local all_hook_points
|
||||
all_hook_points="$(compgen -A function | grep "${hook_extension_delimiter}" | awk -F "${hook_extension_delimiter}" '{print $1}' | sort | uniq | xargs echo -n)"
|
||||
|
||||
declare -i hook_points_counter=0 hook_functions_counter=0 hook_point_functions_counter=0
|
||||
|
||||
# initialize the cleanups file.
|
||||
fragment_manager_cleanup_file="${SRC}"/.tmp/extension_function_cleanup.sh
|
||||
echo "# cleanups: " >"${fragment_manager_cleanup_file}"
|
||||
|
||||
local FUNCTION_SORT_OPTIONS="--general-numeric-sort --ignore-case" # --random-sort could be used to introduce chaos
|
||||
local hook_point=""
|
||||
# now loop over the hook_points.
|
||||
for hook_point in ${all_hook_points}; do
|
||||
echo "-- hook_point ${hook_point}" >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
|
||||
# check if the hook point is already defined as a function.
|
||||
# that can happen for example with user_config(), that can be implemented itself directly by a userpatches config.
|
||||
# for now, just warn, but we could devise a way to actually integrate it in the call list.
|
||||
# or: advise the user to rename their user_config() function to something like user_config__make_it_awesome()
|
||||
local existing_hook_point_function
|
||||
existing_hook_point_function="$(compgen -A function | grep "^${hook_point}\$")"
|
||||
if [[ "${existing_hook_point_function}" == "${hook_point}" ]]; then
|
||||
echo "--- hook_point_functions (final sorted realnames): ${hook_point_functions}" >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
display_alert "Extension conflict" "function ${hook_point} already defined! ignoring functions: $(compgen -A function | grep "^${hook_point}${hook_extension_delimiter}")" "wrn"
|
||||
continue
|
||||
fi
|
||||
|
||||
# for each hook_point, obtain the list of implementing functions.
|
||||
# the sort order here is (very) relevant, since it determines final execution order.
|
||||
# so the name of the functions actually determine the ordering.
|
||||
local hook_point_functions hook_point_functions_pre_sort hook_point_functions_sorted_by_sort_id
|
||||
|
||||
# Sorting. Multiple extensions (or even the same extension twice) can implement the same hook point
|
||||
# as long as they have different function names (the part after the double underscore __).
|
||||
# the order those will be called depends on the name; eg:
|
||||
# 'hook_point__033_be_awesome()' would be caller sooner than 'hook_point__799_be_even_more_awesome()'
|
||||
# independent from where they were defined or in which order the extensions containing them were added.
|
||||
# since requiring specific ordering could hamper portability, we reward extension authors who
|
||||
# don't mind ordering for writing just: 'hook_point__be_just_awesome()' which is automatically rewritten
|
||||
# as 'hook_point__500_be_just_awesome()'.
|
||||
# extension authors who care about ordering can use the 3-digit number, and use the context variables
|
||||
# HOOK_ORDER and HOOK_POINT_TOTAL_FUNCS to confirm in which order they're being run.
|
||||
|
||||
# gather the real names of the functions (after the delimiter).
|
||||
hook_point_functions_pre_sort="$(compgen -A function | grep "^${hook_point}${hook_extension_delimiter}" | awk -F "${hook_extension_delimiter}" '{print $2}' | xargs echo -n)"
|
||||
echo "--- hook_point_functions_pre_sort: ${hook_point_functions_pre_sort}" >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
|
||||
# add "500_" to the names of function that do NOT start with a number.
|
||||
# keep a reference from the new names to the old names (we'll sort on the new, but invoke the old)
|
||||
declare -A hook_point_functions_sortname_to_realname
|
||||
declare -A hook_point_functions_realname_to_sortname
|
||||
for hook_point_function_realname in ${hook_point_functions_pre_sort}; do
|
||||
local sort_id="${hook_point_function_realname}"
|
||||
[[ ! $sort_id =~ ^[0-9] ]] && sort_id="500_${sort_id}"
|
||||
hook_point_functions_sortname_to_realname[${sort_id}]="${hook_point_function_realname}"
|
||||
hook_point_functions_realname_to_sortname[${hook_point_function_realname}]="${sort_id}"
|
||||
done
|
||||
|
||||
# actually sort the sort_id's...
|
||||
# shellcheck disable=SC2086
|
||||
hook_point_functions_sorted_by_sort_id="$(echo "${hook_point_functions_realname_to_sortname[*]}" | tr " " "\n" | LC_ALL=C sort ${FUNCTION_SORT_OPTIONS} | xargs echo -n)"
|
||||
echo "--- hook_point_functions_sorted_by_sort_id: ${hook_point_functions_sorted_by_sort_id}" >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
|
||||
# then map back to the real names, keeping the order..
|
||||
hook_point_functions=""
|
||||
for hook_point_function_sortname in ${hook_point_functions_sorted_by_sort_id}; do
|
||||
hook_point_functions="${hook_point_functions} ${hook_point_functions_sortname_to_realname[${hook_point_function_sortname}]}"
|
||||
done
|
||||
# shellcheck disable=SC2086
|
||||
hook_point_functions="$(echo -n ${hook_point_functions})"
|
||||
echo "--- hook_point_functions (final sorted realnames): ${hook_point_functions}" >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
|
||||
hook_point_functions_counter=0
|
||||
hook_points_counter=$((hook_points_counter + 1))
|
||||
|
||||
# determine the variables we'll pass to the hook function during execution.
|
||||
# this helps the extension author create extensions that are portable between userpatches and official Armbian.
|
||||
# shellcheck disable=SC2089
|
||||
local common_function_vars="HOOK_POINT=\"${hook_point}\""
|
||||
|
||||
# loop over the functions for this hook_point (keep a total for the hook point and a grand running total)
|
||||
for hook_point_function in ${hook_point_functions}; do
|
||||
hook_point_functions_counter=$((hook_point_functions_counter + 1))
|
||||
hook_functions_counter=$((hook_functions_counter + 1))
|
||||
done
|
||||
common_function_vars="${common_function_vars} HOOK_POINT_TOTAL_FUNCS=\"${hook_point_functions_counter}\""
|
||||
|
||||
echo "-- hook_point: ${hook_point} will run ${hook_point_functions_counter} functions: ${hook_point_functions}" >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
local temp_source_file_for_hook_point="${EXTENSION_MANAGER_TMP_DIR}/extension_function_definition.sh"
|
||||
|
||||
hook_point_functions_loop_counter=0
|
||||
|
||||
# prepare the cleanup for the function, so we can remove our mess at the end of the build.
|
||||
cat <<-FUNCTION_CLEANUP_FOR_HOOK_POINT >>"${fragment_manager_cleanup_file}"
|
||||
unset ${hook_point}
|
||||
FUNCTION_CLEANUP_FOR_HOOK_POINT
|
||||
|
||||
# now compose a function definition. notice the heredoc. it will be written to tmp file, logged, then sourced.
|
||||
# theres a lot of opportunities here, but for now I keep it simple:
|
||||
# - execute functions in the order defined by ${hook_point_functions} above
|
||||
# - define call-specific environment variables, to help extension authors to write portable extensions (eg: EXTENSION_DIR)
|
||||
cat <<-FUNCTION_DEFINITION_HEADER >"${temp_source_file_for_hook_point}"
|
||||
${hook_point}() {
|
||||
echo "*** Extension-managed hook starting '${hook_point}': will run ${hook_point_functions_counter} functions: '${hook_point_functions}'" >>"\${EXTENSION_MANAGER_LOG_FILE}"
|
||||
FUNCTION_DEFINITION_HEADER
|
||||
|
||||
for hook_point_function in ${hook_point_functions}; do
|
||||
hook_point_functions_loop_counter=$((hook_point_functions_loop_counter + 1))
|
||||
|
||||
# store the full name in a hash, so we can track which were actually called later.
|
||||
defined_hook_point_functions["${hook_point}${hook_extension_delimiter}${hook_point_function}"]="DEFINED=yes ${extension_function_info["${hook_point}${hook_extension_delimiter}${hook_point_function}"]}"
|
||||
|
||||
# prepare the call context
|
||||
local hook_point_function_variables="${common_function_vars}" # start with common vars... (eg: HOOK_POINT_TOTAL_FUNCS)
|
||||
# add the contextual extension info for the function (eg, EXTENSION_DIR)
|
||||
hook_point_function_variables="${hook_point_function_variables} ${extension_function_info["${hook_point}${hook_extension_delimiter}${hook_point_function}"]}"
|
||||
# add the current execution counter, so the extension author can know in which order it is being actually called
|
||||
hook_point_function_variables="${hook_point_function_variables} HOOK_ORDER=\"${hook_point_functions_loop_counter}\""
|
||||
|
||||
# add it to our (not the call site!) environment. if we export those in the call site, the stack is corrupted.
|
||||
eval "${hook_point_function_variables}"
|
||||
|
||||
# output the call, passing arguments, and also logging the output to the extensions log.
|
||||
# attention: don't pipe here (eg, capture output), otherwise hook function cant modify the environment (which is mostly the point)
|
||||
# @TODO: better error handling. we have a good opportunity to 'set -e' here, and 'set +e' after, so that extension authors are encouraged to write error-free handling code
|
||||
cat <<-FUNCTION_DEFINITION_CALLSITE >>"${temp_source_file_for_hook_point}"
|
||||
hook_point_function_trace_sources["${hook_point}${hook_extension_delimiter}${hook_point_function}"]="\${BASH_SOURCE[*]}"
|
||||
hook_point_function_trace_lines["${hook_point}${hook_extension_delimiter}${hook_point_function}"]="\${BASH_LINENO[*]}"
|
||||
[[ "\${DEBUG_EXTENSION_CALLS}" == "yes" ]] && display_alert "---> Extension Method ${hook_point}" "${hook_point_functions_loop_counter}/${hook_point_functions_counter} (ext:${EXTENSION:-built-in}) ${hook_point_function}" ""
|
||||
echo "*** *** Extension-managed hook starting ${hook_point_functions_loop_counter}/${hook_point_functions_counter} '${hook_point}${hook_extension_delimiter}${hook_point_function}':" >>"\${EXTENSION_MANAGER_LOG_FILE}"
|
||||
${hook_point_function_variables} ${hook_point}${hook_extension_delimiter}${hook_point_function} "\$@"
|
||||
echo "*** *** Extension-managed hook finished ${hook_point_functions_loop_counter}/${hook_point_functions_counter} '${hook_point}${hook_extension_delimiter}${hook_point_function}':" >>"\${EXTENSION_MANAGER_LOG_FILE}"
|
||||
FUNCTION_DEFINITION_CALLSITE
|
||||
|
||||
# output the cleanup for the implementation as well.
|
||||
cat <<-FUNCTION_CLEANUP_FOR_HOOK_POINT_IMPLEMENTATION >>"${fragment_manager_cleanup_file}"
|
||||
unset ${hook_point}${hook_extension_delimiter}${hook_point_function}
|
||||
FUNCTION_CLEANUP_FOR_HOOK_POINT_IMPLEMENTATION
|
||||
|
||||
# unset extension vars for the next loop.
|
||||
unset EXTENSION EXTENSION_DIR EXTENSION_FILE EXTENSION_ADDED_BY
|
||||
done
|
||||
|
||||
cat <<-FUNCTION_DEFINITION_FOOTER >>"${temp_source_file_for_hook_point}"
|
||||
echo "*** Extension-managed hook ending '${hook_point}': completed." >>"\${EXTENSION_MANAGER_LOG_FILE}"
|
||||
} # end ${hook_point}() function
|
||||
FUNCTION_DEFINITION_FOOTER
|
||||
|
||||
# unsets, lest the next loop inherits them
|
||||
unset hook_point_functions hook_point_functions_sortname_to_realname hook_point_functions_realname_to_sortname
|
||||
|
||||
# log what was produced in our own debug logfile
|
||||
cat "${temp_source_file_for_hook_point}" >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
cat "${fragment_manager_cleanup_file}" >>"${EXTENSION_MANAGER_LOG_FILE}"
|
||||
|
||||
# source the generated function.
|
||||
# shellcheck disable=SC1090
|
||||
source "${temp_source_file_for_hook_point}"
|
||||
|
||||
rm -f "${temp_source_file_for_hook_point}"
|
||||
done
|
||||
|
||||
# Dont show any output until we have more than 1 hook function (we implement one already, below)
|
||||
[[ ${hook_functions_counter} -gt 0 ]] &&
|
||||
display_alert "Extension manager" "processed ${hook_points_counter} Extension Methods calls and ${hook_functions_counter} Extension Method implementations" "info" | tee -a "${EXTENSION_MANAGER_LOG_FILE}"
|
||||
}
|
||||
|
||||
cleanup_extension_manager() {
|
||||
if [[ -f "${fragment_manager_cleanup_file}" ]]; then
|
||||
display_alert "Cleaning up" "extension manager" "info"
|
||||
# this will unset all the functions.
|
||||
# shellcheck disable=SC1090 # dynamic source, thanks, shellcheck
|
||||
source "${fragment_manager_cleanup_file}"
|
||||
fi
|
||||
# reset/unset the variables used
|
||||
initialize_extension_manager_counter=0
|
||||
unset extension_function_info defined_hook_point_functions hook_point_function_trace_sources hook_point_function_trace_lines fragment_manager_cleanup_file
|
||||
}
|
||||
|
||||
# why not eat our own dog food?
|
||||
# process everything that happened during extension related activities
|
||||
# and write it to the log. also, move the log from the .tmp dir to its
|
||||
# final location. this will make run_after_build() "hot" (eg, emit warnings)
|
||||
run_after_build__999_finish_extension_manager() {
|
||||
# export these maps, so the hook can access them and produce useful stuff.
|
||||
export defined_hook_point_functions hook_point_function_trace_sources
|
||||
|
||||
# eat our own dog food, pt2.
|
||||
call_extension_method "extension_metadata_ready" <<'EXTENSION_METADATA_READY'
|
||||
*meta-Meta time!*
|
||||
Implement this hook to work with/on the meta-data made available by the extension manager.
|
||||
Interesting stuff to process:
|
||||
- `"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt"` contains a list of all hook points called, in order.
|
||||
- For each hook_point in the list, more files will have metadata about that hook point.
|
||||
- `${EXTENSION_MANAGER_TMP_DIR}/hook_point.orig.md` contains the hook documentation at the call site (inline docs), hopefully in Markdown format.
|
||||
- `${EXTENSION_MANAGER_TMP_DIR}/hook_point.compat` contains the compatibility names for the hooks.
|
||||
- `${EXTENSION_MANAGER_TMP_DIR}/hook_point.exports` contains _exported_ environment variables.
|
||||
- `${EXTENSION_MANAGER_TMP_DIR}/hook_point.vars` contains _all_ environment variables.
|
||||
- `${defined_hook_point_functions}` is a map of _all_ the defined hook point functions and their extension information.
|
||||
- `${hook_point_function_trace_sources}` is a map of all the hook point functions _that were really called during the build_ and their BASH_SOURCE information.
|
||||
- `${hook_point_function_trace_lines}` is the same, but BASH_LINENO info.
|
||||
After this hook is done, the `${EXTENSION_MANAGER_TMP_DIR}` will be removed.
|
||||
EXTENSION_METADATA_READY
|
||||
|
||||
# Move temporary log file over to final destination, and start writing to it instead (although 999 is pretty late in the game)
|
||||
mv "${EXTENSION_MANAGER_LOG_FILE}" "${DEST}/${LOG_SUBPATH:-debug}/extensions.log"
|
||||
export EXTENSION_MANAGER_LOG_FILE="${DEST}/${LOG_SUBPATH:-debug}/extensions.log"
|
||||
|
||||
# Cleanup. Leave no trace...
|
||||
[[ -d "${EXTENSION_MANAGER_TMP_DIR}" ]] && rm -rf "${EXTENSION_MANAGER_TMP_DIR}"
|
||||
}
|
||||
|
||||
# This is called by call_extension_method(). To say the truth, this should be in an extension. But then it gets too meta for anyone's head.
|
||||
write_hook_point_metadata() {
|
||||
local main_hook_point_name="$1"
|
||||
|
||||
[[ ! -d "${EXTENSION_MANAGER_TMP_DIR}" ]] && mkdir -p "${EXTENSION_MANAGER_TMP_DIR}"
|
||||
cat - >"${EXTENSION_MANAGER_TMP_DIR}/${main_hook_point_name}.orig.md" # Write the hook point documentation received via stdin to a tmp file for later processing.
|
||||
shift
|
||||
echo -n "$@" >"${EXTENSION_MANAGER_TMP_DIR}/${main_hook_point_name}.compat" # log the 2nd+ arguments too (those are the alternative/compatibility names), separate file.
|
||||
compgen -A export >"${EXTENSION_MANAGER_TMP_DIR}/${main_hook_point_name}.exports" # capture the exported env vars.
|
||||
compgen -A variable >"${EXTENSION_MANAGER_TMP_DIR}/${main_hook_point_name}.vars" # capture all env vars.
|
||||
|
||||
# add to the list of hook points called, in order.
|
||||
echo "${main_hook_point_name}" >>"${EXTENSION_MANAGER_TMP_DIR}/hook_point_calls.txt"
|
||||
}
|
||||
|
||||
# Helper function, to get clean "stack traces" that do not include the hook/extension infrastructure code.
|
||||
get_extension_hook_stracktrace() {
|
||||
local sources_str="$1" # Give this ${BASH_SOURCE[*]} - expanded
|
||||
local lines_str="$2" # And this # Give this ${BASH_LINENO[*]} - expanded
|
||||
local sources lines index final_stack=""
|
||||
IFS=' ' read -r -a sources <<<"${sources_str}"
|
||||
IFS=' ' read -r -a lines <<<"${lines_str}"
|
||||
for index in "${!sources[@]}"; do
|
||||
local source="${sources[index]}" line="${lines[((index - 1))]}"
|
||||
# skip extension infrastructure sources, these only pollute the trace and add no insight to users
|
||||
[[ ${source} == */.tmp/extension_function_definition.sh ]] && continue
|
||||
[[ ${source} == *lib/extensions.sh ]] && continue
|
||||
[[ ${source} == */compile.sh ]] && continue
|
||||
# relativize the source, otherwise too long to display
|
||||
source="${source#"${SRC}/"}"
|
||||
# remove 'lib/'. hope this is not too confusing.
|
||||
source="${source#"lib/"}"
|
||||
# add to the list
|
||||
arrow="$([[ "$final_stack" != "" ]] && echo "-> ")"
|
||||
final_stack="${source}:${line} ${arrow} ${final_stack} "
|
||||
done
|
||||
# output the result, no newline
|
||||
# shellcheck disable=SC2086 # I wanna suppress double spacing, thanks
|
||||
echo -n $final_stack
|
||||
}
|
||||
|
||||
show_caller_full() {
|
||||
local frame=0
|
||||
while caller $frame; do
|
||||
((frame++))
|
||||
done
|
||||
}
|
||||
# can be called by board, family, config or user to make sure an extension is included.
|
||||
# single argument is the extension name.
|
||||
# will look for it in /userpatches/extensions first.
|
||||
# if not found there will look in /extensions
|
||||
# if not found will exit 17
|
||||
declare -i enable_extension_recurse_counter=0
|
||||
declare -a enable_extension_recurse_stack
|
||||
enable_extension() {
|
||||
local extension_name="$1"
|
||||
local extension_dir extension_file extension_file_in_dir extension_floating_file
|
||||
local stacktrace
|
||||
|
||||
# capture the stack leading to this, possibly with a hint in front.
|
||||
stacktrace="${ENABLE_EXTENSION_TRACE_HINT}$(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")"
|
||||
|
||||
# if LOG_ENABLE_EXTENSION, output useful stack, so user can figure out which extensions are being added where
|
||||
[[ "${LOG_ENABLE_EXTENSION}" == "yes" ]] &&
|
||||
display_alert "Extension being added" "${extension_name} :: added by ${stacktrace}" ""
|
||||
|
||||
# first a check, has the extension manager already initialized? then it is too late to enable_extension(). bail.
|
||||
if [[ ${initialize_extension_manager_counter} -gt 0 ]]; then
|
||||
display_alert "Extension problem" "already initialized -- too late to add '${extension_name}' (trace: ${stacktrace})" "err"
|
||||
exit 2
|
||||
fi
|
||||
|
||||
# check the counter. if recurring, add to the stack and return success
|
||||
if [[ $enable_extension_recurse_counter -gt 1 ]]; then
|
||||
enable_extension_recurse_stack+=("${extension_name}")
|
||||
return 0
|
||||
fi
|
||||
|
||||
# increment the counter
|
||||
enable_extension_recurse_counter=$((enable_extension_recurse_counter + 1))
|
||||
|
||||
# there are many opportunities here. too many, actually. let userpatches override just some functions, etc.
|
||||
for extension_base_path in "${SRC}/userpatches/extensions" "${SRC}/extensions"; do
|
||||
extension_dir="${extension_base_path}/${extension_name}"
|
||||
extension_file_in_dir="${extension_dir}/${extension_name}.sh"
|
||||
extension_floating_file="${extension_base_path}/${extension_name}.sh"
|
||||
|
||||
if [[ -d "${extension_dir}" ]] && [[ -f "${extension_file_in_dir}" ]]; then
|
||||
extension_file="${extension_file_in_dir}"
|
||||
break
|
||||
elif [[ -f "${extension_floating_file}" ]]; then
|
||||
extension_dir="${extension_base_path}" # this is misleading. only directory-based extensions should have this.
|
||||
extension_file="${extension_floating_file}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
# After that, we should either have extension_file and extension_dir, or throw.
|
||||
if [[ ! -f "${extension_file}" ]]; then
|
||||
echo "ERR: Extension problem -- cant find extension '${extension_name}' anywhere - called by ${BASH_SOURCE[1]}"
|
||||
exit 17 # exit, forcibly. no way we can recover from this, and next extensions will get bogus errors as well.
|
||||
fi
|
||||
|
||||
local before_function_list after_function_list new_function_list
|
||||
|
||||
# store a list of existing functions at this point, before sourcing the extension.
|
||||
before_function_list="$(compgen -A function)"
|
||||
|
||||
# error handling during a 'source' call is quite insane in bash after 4.3.
|
||||
# to be able to catch errors in sourced scripts the only way is to trap
|
||||
declare -i extension_source_generated_error=0
|
||||
trap 'extension_source_generated_error=1;' ERR
|
||||
|
||||
# source the file. extensions are not supposed to do anything except export variables and define functions, so nothing should happen here.
|
||||
# there is no way to enforce it though, short of static analysis.
|
||||
# we could punish the extension authors who violate it by removing some essential variables temporarily from the environment during this source, and restore them later.
|
||||
# shellcheck disable=SC1090
|
||||
source "${extension_file}"
|
||||
|
||||
# remove the trap we set.
|
||||
trap - ERR
|
||||
|
||||
# decrement the recurse counter, so calls to this method are allowed again.
|
||||
enable_extension_recurse_counter=$((enable_extension_recurse_counter - 1))
|
||||
|
||||
# test if it fell into the trap, and abort immediately with an error.
|
||||
if [[ $extension_source_generated_error != 0 ]]; then
|
||||
display_alert "Extension failed to load" "${extension_file}" "err"
|
||||
exit 4
|
||||
fi
|
||||
|
||||
# get a new list of functions after sourcing the extension
|
||||
after_function_list="$(compgen -A function)"
|
||||
|
||||
# compare before and after, thus getting the functions defined by the extension.
|
||||
# comm is oldskool. we like it. go "man comm" to understand -13 below
|
||||
new_function_list="$(comm -13 <(echo "$before_function_list" | sort) <(echo "$after_function_list" | sort))"
|
||||
|
||||
# iterate over defined functions, store them in global associative array extension_function_info
|
||||
for newly_defined_function in ${new_function_list}; do
|
||||
extension_function_info["${newly_defined_function}"]="EXTENSION=\"${extension_name}\" EXTENSION_DIR=\"${extension_dir}\" EXTENSION_FILE=\"${extension_file}\" EXTENSION_ADDED_BY=\"${stacktrace}\""
|
||||
done
|
||||
|
||||
# snapshot, then clear, the stack
|
||||
local -a stack_snapshot=("${enable_extension_recurse_stack[@]}")
|
||||
enable_extension_recurse_stack=()
|
||||
|
||||
# process the stacked snapshot, finally enabling the extensions
|
||||
for stacked_extension in "${stack_snapshot[@]}"; do
|
||||
ENABLE_EXTENSION_TRACE_HINT="RECURSE ${stacktrace} ->" enable_extension "${stacked_extension}"
|
||||
done
|
||||
|
||||
}
|
||||
122
lib/general.sh
122
lib/general.sh
@@ -118,10 +118,19 @@ exit_with_error()
|
||||
local _description=$1
|
||||
local _highlight=$2
|
||||
_file=$(basename "${BASH_SOURCE[1]}")
|
||||
local stacktrace="$(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")"
|
||||
|
||||
display_alert "ERROR in function $_function" "$_file:$_line" "err"
|
||||
display_alert "ERROR in function $_function" "$stacktrace" "err"
|
||||
display_alert "$_description" "$_highlight" "err"
|
||||
display_alert "Process terminated" "" "info"
|
||||
|
||||
if [[ "${ERROR_DEBUG_SHELL}" == "yes" ]]; then
|
||||
display_alert "MOUNT" "${MOUNT}" "err"
|
||||
display_alert "SDCARD" "${SDCARD}" "err"
|
||||
display_alert "Here's a shell." "debug it" "err"
|
||||
bash < /dev/tty || true
|
||||
fi
|
||||
|
||||
# TODO: execute run_after_build here?
|
||||
overlayfs_wrapper "cleanup"
|
||||
# unlock loop device access in case of starvation
|
||||
@@ -225,6 +234,12 @@ create_sources_list()
|
||||
# replace local package server if defined. Suitable for development
|
||||
[[ -n $LOCAL_MIRROR ]] && echo "deb http://$LOCAL_MIRROR $RELEASE main ${RELEASE}-utils ${RELEASE}-desktop" > "${basedir}"/etc/apt/sources.list.d/armbian.list
|
||||
|
||||
# disable repo if amd64 or SKIP_ARMBIAN_REPO=yes
|
||||
if [[ "${ARCH}" == "amd64" ]] || [[ "${SKIP_ARMBIAN_REPO}" == "yes" ]]; then
|
||||
display_alert "Disabling armbian repo" "${ARCH}-${RELEASE}" "wrn"
|
||||
mv "${SDCARD}"/etc/apt/sources.list.d/armbian.list "${SDCARD}"/etc/apt/sources.list.d/armbian.list.disabled
|
||||
fi
|
||||
|
||||
display_alert "Adding Armbian repository and authentication key" "/etc/apt/sources.list.d/armbian.list" "info"
|
||||
cp "${SRC}"/config/armbian.key "${basedir}"
|
||||
chroot "${basedir}" /bin/bash -c "cat armbian.key | apt-key add - > /dev/null 2>&1"
|
||||
@@ -1187,7 +1202,7 @@ prepare_host()
|
||||
if [[ $(dpkg --print-architecture) != amd64 ]]; then
|
||||
display_alert "Please read documentation to set up proper compilation environment"
|
||||
display_alert "https://www.armbian.com/using-armbian-tools/"
|
||||
exit_with_error "Running this tool on non x86-x64 build host is not supported"
|
||||
exit_with_error "Running this tool on non x86_64 build host is not supported"
|
||||
fi
|
||||
|
||||
# build aarch64
|
||||
@@ -1215,8 +1230,8 @@ prepare_host()
|
||||
parted pkg-config libncurses5-dev whiptail debian-keyring debian-archive-keyring f2fs-tools libfile-fcntllock-perl rsync libssl-dev \
|
||||
nfs-kernel-server btrfs-progs ncurses-term p7zip-full kmod dosfstools libc6-dev-armhf-cross imagemagick \
|
||||
curl patchutils liblz4-tool libpython2.7-dev linux-base swig aptly acl python3-dev python3-distutils \
|
||||
locales ncurses-base pixz dialog systemd-container udev libfdt-dev lib32stdc++6 libc6-i386 lib32ncurses5 lib32tinfo5 \
|
||||
bison libbison-dev flex libfl-dev cryptsetup gpg gnupg1 cpio aria2 pigz dirmngr python3-distutils jq distcc"
|
||||
locales ncurses-base pixz dialog systemd-container udev libfdt-dev libelf-dev lib32stdc++6 libc6-i386 lib32ncurses5 lib32tinfo5 \
|
||||
bison libbison-dev flex libfl-dev cryptsetup gpg gnupg1 cpio aria2 pigz dirmngr python3-distutils jq distcc gdisk"
|
||||
|
||||
# build aarch64
|
||||
else
|
||||
@@ -1227,9 +1242,9 @@ prepare_host()
|
||||
parted pkg-config libncurses5-dev whiptail debian-keyring debian-archive-keyring f2fs-tools libfile-fcntllock-perl rsync libssl-dev \
|
||||
nfs-kernel-server btrfs-progs ncurses-term p7zip-full kmod dosfstools libc6-amd64-cross libc6-dev-armhf-cross imagemagick \
|
||||
curl patchutils liblz4-tool libpython2.7-dev linux-base swig aptly acl python3-dev \
|
||||
locales ncurses-base pixz dialog systemd-container udev libfdt-dev libc6 qemu \
|
||||
locales ncurses-base pixz dialog systemd-container udev libfdt-dev libelf-dev libc6 qemu \
|
||||
bison libbison-dev flex libfl-dev cryptsetup gpg gnupg1 cpio aria2 pigz \
|
||||
dirmngr python3-distutils jq "
|
||||
dirmngr python3-distutils jq gdisk"
|
||||
|
||||
# build aarch64
|
||||
fi
|
||||
@@ -1301,7 +1316,13 @@ prepare_host()
|
||||
local deps=()
|
||||
local installed=$(dpkg-query -W -f '${db:Status-Abbrev}|${binary:Package}\n' '*' 2>/dev/null | grep '^ii' | awk -F '|' '{print $2}' | cut -d ':' -f 1)
|
||||
|
||||
for packet in $hostdeps; do
|
||||
export EXTRA_BUILD_DEPS=""
|
||||
call_extension_method "add_host_dependencies" <<- 'ADD_HOST_DEPENDENCIES'
|
||||
*run before installing host dependencies*
|
||||
you can add packages to install, space separated, to ${EXTRA_BUILD_DEPS} here.
|
||||
ADD_HOST_DEPENDENCIES
|
||||
|
||||
for packet in $hostdeps ${EXTRA_BUILD_DEPS}; do
|
||||
if ! grep -q -x -e "$packet" <<< "$installed"; then deps+=("$packet"); fi
|
||||
done
|
||||
|
||||
@@ -1335,6 +1356,15 @@ prepare_host()
|
||||
update-ccache-symlinks
|
||||
fi
|
||||
|
||||
export FINAL_HOST_DEPS="$hostdeps ${EXTRA_BUILD_DEPS}"
|
||||
call_extension_method "host_dependencies_ready" <<- 'HOST_DEPENDENCIES_READY'
|
||||
*run after all host dependencies are installed*
|
||||
At this point we can read `${FINAL_HOST_DEPS}`, but changing won't have any effect.
|
||||
All the dependencies, including the default/core deps and the ones added via `${EXTRA_BUILD_DEPS}`
|
||||
are installed at this point. The system clock has not yet been synced.
|
||||
HOST_DEPENDENCIES_READY
|
||||
|
||||
|
||||
# sync clock
|
||||
if [[ $SYNC_CLOCK != no ]]; then
|
||||
display_alert "Syncing clock" "host" "info"
|
||||
@@ -1364,53 +1394,57 @@ prepare_host()
|
||||
mkdir -p "${DEST}"/debs-beta/extra "${DEST}"/debs/extra "${DEST}"/{config,debug,patch} "${USERPATCHES_PATH}"/overlay "${SRC}"/cache/{sources,hash,hash-beta,toolchain,utility,rootfs} "${SRC}"/.tmp
|
||||
|
||||
# build aarch64
|
||||
if [[ $(dpkg --print-architecture) == amd64 ]]; then
|
||||
if [[ $(dpkg --print-architecture) == amd64 ]]; then
|
||||
if [[ "${SKIP_EXTERNAL_TOOLCHAINS}" != "yes" ]]; then
|
||||
display_alert "Checking for external GCC compilers" "" "info"
|
||||
# download external Linaro compiler and missing special dependencies since they are needed for certain sources
|
||||
|
||||
display_alert "Checking for external GCC compilers" "" "info"
|
||||
# download external Linaro compiler and missing special dependencies since they are needed for certain sources
|
||||
local toolchains=(
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-linaro-arm-none-eabi-4.8-2014.04_linux.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchains/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz"
|
||||
)
|
||||
|
||||
local toolchains=(
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-linaro-aarch64-none-elf-4.8-2013.11_linux.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-linaro-arm-none-eabi-4.8-2014.04_linux.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-linaro-arm-linux-gnueabihf-4.8-2014.04_linux.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-linaro-7.4.1-2019.02-x86_64_arm-linux-gnueabi.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-linaro-7.4.1-2019.02-x86_64_aarch64-linux-gnu.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchains/gcc-arm-8.3-2019.03-x86_64-arm-linux-gnueabihf.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchains/gcc-arm-8.3-2019.03-x86_64-aarch64-linux-gnu.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-arm-9.2-2019.12-x86_64-arm-none-linux-gnueabihf.tar.xz"
|
||||
"${ARMBIAN_MIRROR}/_toolchain/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu.tar.xz"
|
||||
)
|
||||
USE_TORRENT_STATUS=${USE_TORRENT}
|
||||
USE_TORRENT="no"
|
||||
for toolchain in ${toolchains[@]}; do
|
||||
download_and_verify "_toolchain" "${toolchain##*/}"
|
||||
done
|
||||
USE_TORRENT=${USE_TORRENT_STATUS}
|
||||
|
||||
USE_TORRENT_STATUS=${USE_TORRENT}
|
||||
USE_TORRENT="no"
|
||||
for toolchain in ${toolchains[@]}; do
|
||||
download_and_verify "_toolchain" "${toolchain##*/}"
|
||||
done
|
||||
USE_TORRENT=${USE_TORRENT_STATUS}
|
||||
|
||||
rm -rf "${SRC}"/cache/toolchain/*.tar.xz*
|
||||
local existing_dirs=( $(ls -1 "${SRC}"/cache/toolchain) )
|
||||
for dir in ${existing_dirs[@]}; do
|
||||
local found=no
|
||||
for toolchain in ${toolchains[@]}; do
|
||||
local filename=${toolchain##*/}
|
||||
local dirname=${filename//.tar.xz}
|
||||
[[ $dir == $dirname ]] && found=yes
|
||||
done
|
||||
if [[ $found == no ]]; then
|
||||
display_alert "Removing obsolete toolchain" "$dir"
|
||||
rm -rf "${SRC}/cache/toolchain/${dir}"
|
||||
rm -rf "${SRC}"/cache/toolchain/*.tar.xz*
|
||||
local existing_dirs=( $(ls -1 "${SRC}"/cache/toolchain) )
|
||||
for dir in ${existing_dirs[@]}; do
|
||||
local found=no
|
||||
for toolchain in ${toolchains[@]}; do
|
||||
local filename=${toolchain##*/}
|
||||
local dirname=${filename//.tar.xz}
|
||||
[[ $dir == $dirname ]] && found=yes
|
||||
done
|
||||
if [[ $found == no ]]; then
|
||||
display_alert "Removing obsolete toolchain" "$dir"
|
||||
rm -rf "${SRC}/cache/toolchain/${dir}"
|
||||
fi
|
||||
done
|
||||
else
|
||||
display_alert "Ignoring toolchains" "SKIP_EXTERNAL_TOOLCHAINS: ${SKIP_EXTERNAL_TOOLCHAINS}" "info"
|
||||
fi
|
||||
done
|
||||
|
||||
fi # check offline
|
||||
|
||||
# enable arm binary format so that the cross-architecture chroot environment will work
|
||||
if [[ $KERNEL_ONLY != yes ]]; then
|
||||
modprobe -q binfmt_misc
|
||||
mountpoint -q /proc/sys/fs/binfmt_misc/ || mount binfmt_misc -t binfmt_misc /proc/sys/fs/binfmt_misc
|
||||
test -e /proc/sys/fs/binfmt_misc/qemu-arm || update-binfmts --enable qemu-arm
|
||||
test -e /proc/sys/fs/binfmt_misc/qemu-aarch64 || update-binfmts --enable qemu-aarch64
|
||||
if [[ "$(arch)" != "aarch64" ]]; then
|
||||
test -e /proc/sys/fs/binfmt_misc/qemu-arm || update-binfmts --enable qemu-arm
|
||||
test -e /proc/sys/fs/binfmt_misc/qemu-aarch64 || update-binfmts --enable qemu-aarch64
|
||||
fi
|
||||
fi
|
||||
|
||||
# build aarch64
|
||||
|
||||
@@ -71,6 +71,16 @@ unmount_on_exit()
|
||||
{
|
||||
|
||||
trap - INT TERM EXIT
|
||||
local stacktrace="$(get_extension_hook_stracktrace "${BASH_SOURCE[*]}" "${BASH_LINENO[*]}")"
|
||||
display_alert "unmount_on_exit() called!" "$stacktrace" "err"
|
||||
if [[ "${ERROR_DEBUG_SHELL}" == "yes" ]]; then
|
||||
ERROR_DEBUG_SHELL=no # dont do it twice
|
||||
display_alert "MOUNT" "${MOUNT}" "err"
|
||||
display_alert "SDCARD" "${SDCARD}" "err"
|
||||
display_alert "ERROR_DEBUG_SHELL=yes, starting a shell." "ERROR_DEBUG_SHELL" "err"
|
||||
bash < /dev/tty || true
|
||||
fi
|
||||
|
||||
umount_chroot "${SDCARD}/"
|
||||
umount -l "${SDCARD}"/tmp >/dev/null 2>&1
|
||||
umount -l "${SDCARD}" >/dev/null 2>&1
|
||||
@@ -79,7 +89,7 @@ unmount_on_exit()
|
||||
[[ $CRYPTROOT_ENABLE == yes ]] && cryptsetup luksClose "${ROOT_MAPPER}"
|
||||
losetup -d "${LOOP}" >/dev/null 2>&1
|
||||
rm -rf --one-file-system "${SDCARD}"
|
||||
exit_with_error "debootstrap-ng was interrupted"
|
||||
exit_with_error "debootstrap-ng was interrupted" || true # don't trigger again
|
||||
|
||||
}
|
||||
|
||||
@@ -158,6 +168,13 @@ customize_image()
|
||||
|
||||
# for users that need to prepare files at host
|
||||
[[ -f $USERPATCHES_PATH/customize-image-host.sh ]] && source "$USERPATCHES_PATH"/customize-image-host.sh
|
||||
|
||||
call_extension_method "pre_customize_image" "image_tweaks_pre_customize" << 'PRE_CUSTOMIZE_IMAGE'
|
||||
*run before customize-image.sh*
|
||||
This hook is called after `customize-image-host.sh` is called, but before the overlay is mounted.
|
||||
It thus can be used for the same purposes as `customize-image-host.sh`.
|
||||
PRE_CUSTOMIZE_IMAGE
|
||||
|
||||
cp "$USERPATCHES_PATH"/customize-image.sh "${SDCARD}"/tmp/customize-image.sh
|
||||
chmod +x "${SDCARD}"/tmp/customize-image.sh
|
||||
mkdir -p "${SDCARD}"/tmp/overlay
|
||||
@@ -172,6 +189,10 @@ customize_image()
|
||||
exit_with_error "customize-image.sh exited with error (rc: $CUSTOMIZE_IMAGE_RC)"
|
||||
fi
|
||||
|
||||
call_extension_method "post_customize_image" "image_tweaks_post_customize" << 'POST_CUSTOMIZE_IMAGE'
|
||||
*post customize-image.sh hook*
|
||||
Run after the customize-image.sh script is run, and the overlay is unmounted.
|
||||
POST_CUSTOMIZE_IMAGE
|
||||
}
|
||||
|
||||
|
||||
|
||||
91
lib/main.sh
91
lib/main.sh
@@ -393,6 +393,11 @@ else
|
||||
|
||||
fi
|
||||
|
||||
call_extension_method "post_determine_cthreads" "config_post_determine_cthreads" << 'POST_DETERMINE_CTHREADS'
|
||||
*give config a chance modify CTHREADS programatically. A build server may work better with hyperthreads-1 for example.*
|
||||
Called early, before any compilation work starts.
|
||||
POST_DETERMINE_CTHREADS
|
||||
|
||||
if [[ $BETA == yes ]]; then
|
||||
IMAGE_TYPE=nightly
|
||||
elif [[ $BETA != "yes" && $BUILD_ALL == yes && -n $GPG_PASS ]]; then
|
||||
@@ -409,9 +414,9 @@ BOOTSOURCEDIR="${BOOTDIR}/$(branch2dir "${BOOTBRANCH}")"
|
||||
LINUXSOURCEDIR="${KERNELDIR}/$(branch2dir "${KERNELBRANCH}")"
|
||||
[[ -n $ATFSOURCE ]] && ATFSOURCEDIR="${ATFDIR}/$(branch2dir "${ATFBRANCH}")"
|
||||
|
||||
BSP_CLI_PACKAGE_NAME="armbian-bsp-cli-${BOARD}"
|
||||
BSP_CLI_PACKAGE_NAME="armbian-bsp-cli-${BOARD}${EXTRA_BSP_NAME}"
|
||||
BSP_CLI_PACKAGE_FULLNAME="${BSP_CLI_PACKAGE_NAME}_${REVISION}_${ARCH}"
|
||||
BSP_DESKTOP_PACKAGE_NAME="armbian-bsp-desktop-${BOARD}"
|
||||
BSP_DESKTOP_PACKAGE_NAME="armbian-bsp-desktop-${BOARD}${EXTRA_BSP_NAME}"
|
||||
BSP_DESKTOP_PACKAGE_FULLNAME="${BSP_DESKTOP_PACKAGE_NAME}_${REVISION}_${ARCH}"
|
||||
|
||||
CHOSEN_UBOOT=linux-u-boot-${BRANCH}-${BOARD}
|
||||
@@ -436,46 +441,42 @@ prepare_host
|
||||
|
||||
# ignore updates help on building all images - for internal purposes
|
||||
if [[ $IGNORE_UPDATES != yes ]]; then
|
||||
display_alert "Downloading sources" "" "info"
|
||||
|
||||
fetch_from_repo "$BOOTSOURCE" "$BOOTDIR" "$BOOTBRANCH" "yes"
|
||||
fetch_from_repo "$KERNELSOURCE" "$KERNELDIR" "$KERNELBRANCH" "yes"
|
||||
if [[ -n $ATFSOURCE ]]; then
|
||||
fetch_from_repo "$ATFSOURCE" "$ATFDIR" "$ATFBRANCH" "yes"
|
||||
fi
|
||||
fetch_from_repo "https://github.com/linux-sunxi/sunxi-tools" "sunxi-tools" "branch:master"
|
||||
fetch_from_repo "https://github.com/armbian/rkbin" "rkbin-tools" "branch:master"
|
||||
fetch_from_repo "https://github.com/MarvellEmbeddedProcessors/A3700-utils-marvell" "marvell-tools" "branch:A3700_utils-armada-18.12"
|
||||
fetch_from_repo "https://github.com/MarvellEmbeddedProcessors/mv-ddr-marvell.git" "marvell-ddr" "branch:mv_ddr-armada-18.12"
|
||||
fetch_from_repo "https://github.com/MarvellEmbeddedProcessors/binaries-marvell" "marvell-binaries" "branch:binaries-marvell-armada-18.12"
|
||||
fetch_from_repo "https://github.com/armbian/odroidc2-blobs" "odroidc2-blobs" "branch:master"
|
||||
fetch_from_repo "https://github.com/armbian/testings" "testing-reports" "branch:master"
|
||||
fetch_from_repo "https://github.com/LibreELEC/amlogic-boot-fip" "amlogic-boot-fip" "branch:master"
|
||||
|
||||
compile_sunxi_tools
|
||||
install_rkbin_tools
|
||||
|
||||
for option in $(tr ',' ' ' <<< "$CLEAN_LEVEL"); do
|
||||
[[ $option != sources ]] && cleaning "$option"
|
||||
done
|
||||
display_alert "Downloading sources" "" "info"
|
||||
[[ -n $BOOTSOURCE ]] && fetch_from_repo "$BOOTSOURCE" "$BOOTDIR" "$BOOTBRANCH" "yes"
|
||||
[[ -n $KERNELSOURCE ]] && fetch_from_repo "$KERNELSOURCE" "$KERNELDIR" "$KERNELBRANCH" "yes"
|
||||
[[ -n $ATFSOURCE ]] && fetch_from_repo "$ATFSOURCE" "$ATFDIR" "$ATFBRANCH" "yes"
|
||||
|
||||
call_extension_method "fetch_sources_tools" <<- 'FETCH_SOURCES_TOOLS'
|
||||
*fetch host-side sources needed for tools and build*
|
||||
Run early to fetch_from_repo or otherwise obtain sources for needed tools.
|
||||
FETCH_SOURCES_TOOLS
|
||||
|
||||
call_extension_method "build_host_tools" <<- 'BUILD_HOST_TOOLS'
|
||||
*build needed tools for the build, host-side*
|
||||
After sources are fetched, build host-side tools needed for the build.
|
||||
BUILD_HOST_TOOLS
|
||||
|
||||
for option in $(tr ',' ' ' <<< "$CLEAN_LEVEL"); do
|
||||
[[ $option != sources ]] && cleaning "$option"
|
||||
done
|
||||
fi
|
||||
|
||||
# Compile u-boot if packed .deb does not exist or use the one from repository
|
||||
if [[ ! -f "${DEB_STORAGE}"/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb ]]; then
|
||||
|
||||
if [[ -n "${ATFSOURCE}" && "${REPOSITORY_INSTALL}" != *u-boot* ]]; then
|
||||
compile_atf
|
||||
# Don't build at all if the BOOTCONFIG is 'none'.
|
||||
[[ "${BOOTCONFIG}" != "none" ]] && {
|
||||
# Compile u-boot if packed .deb does not exist or use the one from repository
|
||||
if [[ ! -f "${DEB_STORAGE}"/${CHOSEN_UBOOT}_${REVISION}_${ARCH}.deb ]]; then
|
||||
if [[ -n "${ATFSOURCE}" && "${REPOSITORY_INSTALL}" != *u-boot* ]]; then
|
||||
compile_atf
|
||||
fi
|
||||
[[ "${REPOSITORY_INSTALL}" != *u-boot* ]] && compile_uboot
|
||||
fi
|
||||
[[ "${REPOSITORY_INSTALL}" != *u-boot* ]] && compile_uboot
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
# Compile kernel if packed .deb does not exist or use the one from repository
|
||||
if [[ ! -f ${DEB_STORAGE}/${CHOSEN_KERNEL}_${REVISION}_${ARCH}.deb ]]; then
|
||||
|
||||
KDEB_CHANGELOG_DIST=$RELEASE
|
||||
[[ "${REPOSITORY_INSTALL}" != *kernel* ]] && compile_kernel
|
||||
[[ -n $KERNELSOURCE ]] && [[ "${REPOSITORY_INSTALL}" != *kernel* ]] && compile_kernel
|
||||
|
||||
fi
|
||||
|
||||
@@ -497,13 +498,14 @@ fi
|
||||
if ! ls "${DEB_STORAGE}/armbian-firmware_${REVISION}_all.deb" 1> /dev/null 2>&1 || ! ls "${DEB_STORAGE}/armbian-firmware-full_${REVISION}_all.deb" 1> /dev/null 2>&1; then
|
||||
|
||||
if [[ "${REPOSITORY_INSTALL}" != *armbian-firmware* ]]; then
|
||||
|
||||
FULL=""
|
||||
REPLACE="-full"
|
||||
compile_firmware
|
||||
FULL="-full"
|
||||
REPLACE=""
|
||||
compile_firmware
|
||||
[[ "${INSTALL_ARMBIAN_FIRMWARE:-yes}" == "yes" ]] && { # Build firmware by default.
|
||||
FULL=""
|
||||
REPLACE="-full"
|
||||
compile_firmware
|
||||
FULL="-full"
|
||||
REPLACE=""
|
||||
compile_firmware
|
||||
}
|
||||
|
||||
fi
|
||||
|
||||
@@ -540,9 +542,12 @@ else
|
||||
|
||||
fi
|
||||
|
||||
# hook for function to run after build, i.e. to change owner of $SRC
|
||||
# NOTE: this will run only if there were no errors during build process
|
||||
[[ $(type -t run_after_build) == function ]] && run_after_build || true
|
||||
call_extension_method "run_after_build" << 'RUN_AFTER_BUILD'
|
||||
*hook for function to run after build, i.e. to change owner of `$SRC`*
|
||||
Really one of the last hooks ever called. The build has ended. Congratulations.
|
||||
- *NOTE:* this will run only if there were no errors during build process.
|
||||
RUN_AFTER_BUILD
|
||||
|
||||
|
||||
end=$(date +%s)
|
||||
runtime=$(((end-start)/60))
|
||||
|
||||
@@ -31,27 +31,30 @@ create_board_package()
|
||||
copy_all_packages_files_for "bsp-cli"
|
||||
|
||||
# install copy of boot script & environment file
|
||||
local bootscript_src=${BOOTSCRIPT%%:*}
|
||||
local bootscript_dst=${BOOTSCRIPT##*:}
|
||||
mkdir -p "${destination}"/usr/share/armbian/
|
||||
|
||||
# create extlinux config file
|
||||
if [[ $SRC_EXTLINUX != yes ]]; then
|
||||
if [ -f "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" ]; then
|
||||
cp "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" "${destination}/usr/share/armbian/${bootscript_dst}"
|
||||
else
|
||||
cp "${SRC}/config/bootscripts/${bootscript_src}" "${destination}/usr/share/armbian/${bootscript_dst}"
|
||||
if [[ "${BOOTCONFIG}" != "none" ]]; then
|
||||
# @TODO: add extension method bsp_prepare_bootloader(), refactor into u-boot extension
|
||||
local bootscript_src=${BOOTSCRIPT%%:*}
|
||||
local bootscript_dst=${BOOTSCRIPT##*:}
|
||||
mkdir -p "${destination}"/usr/share/armbian/
|
||||
|
||||
# create extlinux config file
|
||||
if [[ $SRC_EXTLINUX != yes ]]; then
|
||||
if [ -f "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" ]; then
|
||||
cp "${USERPATCHES_PATH}/bootscripts/${bootscript_src}" "${destination}/usr/share/armbian/${bootscript_dst}"
|
||||
else
|
||||
cp "${SRC}/config/bootscripts/${bootscript_src}" "${destination}/usr/share/armbian/${bootscript_dst}"
|
||||
fi
|
||||
[[ -n $BOOTENV_FILE && -f $SRC/config/bootenv/$BOOTENV_FILE ]] && \
|
||||
cp "${SRC}/config/bootenv/${BOOTENV_FILE}" "${destination}"/usr/share/armbian/armbianEnv.txt
|
||||
fi
|
||||
|
||||
# add configuration for setting uboot environment from userspace with: fw_setenv fw_printenv
|
||||
if [[ -n $UBOOT_FW_ENV ]]; then
|
||||
UBOOT_FW_ENV=($(tr ',' ' ' <<< "$UBOOT_FW_ENV"))
|
||||
mkdir -p "${destination}"/etc
|
||||
echo "# Device to access offset env size" > "${destination}"/etc/fw_env.config
|
||||
echo "/dev/mmcblk0 ${UBOOT_FW_ENV[0]} ${UBOOT_FW_ENV[1]}" >> "${destination}"/etc/fw_env.config
|
||||
fi
|
||||
[[ -n $BOOTENV_FILE && -f $SRC/config/bootenv/$BOOTENV_FILE ]] && \
|
||||
cp "${SRC}/config/bootenv/${BOOTENV_FILE}" "${destination}"/usr/share/armbian/armbianEnv.txt
|
||||
fi
|
||||
|
||||
# add configuration for setting uboot environment from userspace with: fw_setenv fw_printenv
|
||||
if [[ -n $UBOOT_FW_ENV ]]; then
|
||||
UBOOT_FW_ENV=($(tr ',' ' ' <<< "$UBOOT_FW_ENV"))
|
||||
mkdir -p "${destination}"/etc
|
||||
echo "# Device to access offset env size" > "${destination}"/etc/fw_env.config
|
||||
echo "/dev/mmcblk0 ${UBOOT_FW_ENV[0]} ${UBOOT_FW_ENV[1]}" >> "${destination}"/etc/fw_env.config
|
||||
fi
|
||||
|
||||
# Replaces: base-files is needed to replace /etc/update-motd.d/ files on Xenial
|
||||
@@ -160,7 +163,7 @@ create_board_package()
|
||||
# ${BOARD} BSP post installation script
|
||||
#
|
||||
|
||||
systemctl --no-reload enable armbian-ramlog.service
|
||||
[ -f /etc/lib/systemd/system/armbian-ramlog.service ] && systemctl --no-reload enable armbian-ramlog.service
|
||||
|
||||
# check if it was disabled in config and disable in new service
|
||||
if [ -n "\$(grep -w '^ENABLED=false' /etc/default/log2ram 2> /dev/null)" ]; then
|
||||
@@ -225,17 +228,17 @@ create_board_package()
|
||||
|
||||
fi
|
||||
|
||||
[ ! -f "/etc/network/interfaces" ] && cp /etc/network/interfaces.default /etc/network/interfaces
|
||||
[ ! -f "/etc/network/interfaces" ] && [ -f "/etc/network/interfaces.default" ] && cp /etc/network/interfaces.default /etc/network/interfaces
|
||||
ln -sf /var/run/motd /etc/motd
|
||||
rm -f /etc/update-motd.d/00-header /etc/update-motd.d/10-help-text
|
||||
|
||||
if [ ! -f "/etc/default/armbian-motd" ]; then
|
||||
mv /etc/default/armbian-motd.dpkg-dist /etc/default/armbian-motd
|
||||
fi
|
||||
if [ ! -f "/etc/default/armbian-ramlog" ]; then
|
||||
if [ ! -f "/etc/default/armbian-ramlog" ] && [ -f /etc/default/armbian-ramlog.dpkg-dist ]; then
|
||||
mv /etc/default/armbian-ramlog.dpkg-dist /etc/default/armbian-ramlog
|
||||
fi
|
||||
if [ ! -f "/etc/default/armbian-zram-config" ]; then
|
||||
if [ ! -f "/etc/default/armbian-zram-config" ] && [ -f /etc/default/armbian-zram-config.dpkg-dist ]; then
|
||||
mv /etc/default/armbian-zram-config.dpkg-dist /etc/default/armbian-zram-config
|
||||
fi
|
||||
|
||||
@@ -301,6 +304,11 @@ fi
|
||||
# execute $LINUXFAMILY-specific tweaks
|
||||
[[ $(type -t family_tweaks_bsp) == function ]] && family_tweaks_bsp
|
||||
|
||||
call_extension_method "post_family_tweaks_bsp" << 'POST_FAMILY_TWEAKS_BSP'
|
||||
*family_tweaks_bsp overrrides what is in the config, so give it a chance to override the family tweaks*
|
||||
This should be implemented by the config to tweak the BSP, after the board or family has had the chance to.
|
||||
POST_FAMILY_TWEAKS_BSP
|
||||
|
||||
# add some summary to the image
|
||||
fingerprint_image "${destination}/etc/armbian.txt"
|
||||
|
||||
|
||||
@@ -9,6 +9,15 @@
|
||||
# /etc/kernel/{pre,post}{inst,rm}.d/ directories (or an alternative location
|
||||
# specified in KDEB_HOOKDIR) that will be called on package install and
|
||||
# removal.
|
||||
#
|
||||
# armbian/bulddeb 0.1
|
||||
# Copyright 2021 Leonid Gasheev (The-going <48602507+The-going@users.noreply.github.com>)
|
||||
#
|
||||
# In order to make a choice, it is enough for us to check the value
|
||||
# of the variable in the kernel configuration file and Debian's own variables.
|
||||
#
|
||||
# Uncomment the next line to see all the current values.
|
||||
# echo "$(dpkg-architecture -l)" >&2
|
||||
|
||||
set -e
|
||||
|
||||
@@ -24,6 +33,14 @@ if_enabled_echo() {
|
||||
fi
|
||||
}
|
||||
|
||||
is_native() {
|
||||
dpkg-architecture -qDEB_BUILD_ARCH | grep -q "$(dpkg-architecture -qDEB_HOST_ARCH)"
|
||||
}
|
||||
|
||||
is_build_on_amd64() {
|
||||
dpkg-architecture -qDEB_BUILD_ARCH | grep -q amd64
|
||||
}
|
||||
|
||||
create_package() {
|
||||
local pname="$1" pdir="$2"
|
||||
local dpkg_deb_opts
|
||||
@@ -67,7 +84,7 @@ EOT
|
||||
chmod 775 $pdir/DEBIAN/postinst
|
||||
fi
|
||||
|
||||
# Create postinstall prerm script for headers
|
||||
# Create postinst prerm script for headers
|
||||
if [ "$3" = "headers" ]; then
|
||||
|
||||
# Set the time for all files to the current time.
|
||||
@@ -131,10 +148,14 @@ deploy_kernel_headers () {
|
||||
fi
|
||||
} > debian/hdrobjfiles
|
||||
|
||||
(
|
||||
if is_native; then
|
||||
echo "info: Build native: Skip headers-debian-byteshift.patch" >&2
|
||||
elif is_build_on_amd64; then
|
||||
(
|
||||
cd $destdir
|
||||
patch -p1 < /tmp/headers-debian-byteshift.patch
|
||||
)
|
||||
)
|
||||
fi
|
||||
|
||||
tar -c -f - -C $srctree -T debian/hdrsrcfiles | tar -xf - -C $destdir
|
||||
tar -c -f - -T debian/hdrobjfiles | tar -xf - -C $destdir
|
||||
@@ -197,6 +218,7 @@ parisc|mips|powerpc)
|
||||
installed_image_path="boot/vmlinux-$version"
|
||||
;;
|
||||
*)
|
||||
image_name=vmlinuz
|
||||
installed_image_path="boot/vmlinuz-$version"
|
||||
esac
|
||||
|
||||
@@ -292,7 +314,7 @@ done
|
||||
## Create sym link to kernel image
|
||||
##
|
||||
sed -e "s/exit 0//g" -i $tmpdir/DEBIAN/postinst
|
||||
cat >> $tmpdir/DEBIAN/postinst <<EOT
|
||||
cat >> $tmpdir/DEBIAN/postinst << EOT
|
||||
ln -sf $(basename $installed_image_path) /boot/$image_name 2> /dev/null || mv /$installed_image_path /boot/$image_name
|
||||
touch /boot/.next
|
||||
exit 0
|
||||
@@ -329,17 +351,27 @@ EOT
|
||||
create_package "$packagename" "$tmpdir"
|
||||
|
||||
if [ "$ARCH" != "um" ]; then
|
||||
create_package "$dtb_packagename" "$dtb_dir" "dtb"
|
||||
|
||||
if [ "$(cat debian/arch)" != "amd64" ]; then # No DTB for amd64 target
|
||||
create_package "$dtb_packagename" "$dtb_dir" "dtb"
|
||||
fi
|
||||
|
||||
deploy_libc_headers $libc_headers_dir
|
||||
create_package $libc_headers_packagename $libc_headers_dir
|
||||
|
||||
if is_enabled CONFIG_MODULES; then
|
||||
# Clean up the executables that are left over from
|
||||
# cross-compilation for a different host architecture.
|
||||
(cd $srctree; make M=scripts clean;)
|
||||
deploy_kernel_headers $kernel_headers_dir
|
||||
create_package $kernel_headers_packagename $kernel_headers_dir "headers"
|
||||
if is_native ; then
|
||||
# echo "Skip scripts folder cleaning" >&2
|
||||
# echo "Skip creating postinst prerm scripts for headers" >&2
|
||||
deploy_kernel_headers $kernel_headers_dir
|
||||
create_package $kernel_headers_packagename $kernel_headers_dir
|
||||
else
|
||||
# Clean up the executables that are left over from
|
||||
# cross-compilation for a different host architecture.
|
||||
(cd $srctree; make M=scripts clean;)
|
||||
deploy_kernel_headers $kernel_headers_dir
|
||||
create_package $kernel_headers_packagename $kernel_headers_dir "headers"
|
||||
fi
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
@@ -23,7 +23,7 @@ done
|
||||
KERNELID=$(uname -r)
|
||||
|
||||
# Odroid N2 exception
|
||||
[[ -n $(cat /proc/device-tree/model | tr -d '\000' | grep ODROID | grep Plus) ]] && BOARD_NAME+="+"
|
||||
[[ -f /proc/device-tree/model ]] && [[ -n $(cat /proc/device-tree/model | tr -d '\000' | grep ODROID | grep Plus) ]] && BOARD_NAME+="+"
|
||||
|
||||
TERM=linux toilet -f standard -F metal $(echo $BOARD_NAME | sed 's/Orange Pi/OPi/' | sed 's/NanoPi/NPi/' | sed 's/Banana Pi/BPi/')
|
||||
echo -e "Welcome to \e[0;91mArmbian ${VERSION} ${DISTRIBUTION_CODENAME^}\x1B[0m with $([[ $BRANCH == edge ]] && echo -e "\e[0;91mbleeding\x1B[0m edge " )\e[0;91mLinux $KERNELID\x1B[0m\n"
|
||||
|
||||
@@ -13,6 +13,15 @@
|
||||
|
||||
do_expand_partition()
|
||||
{
|
||||
# check if growroot (from cloud-initramfs-growroot package) is installed.
|
||||
# despite it's name, that package does NOT require cloud-init.
|
||||
# if so, it means the partition with root filesystem was already resized during initramfs.
|
||||
# in this case do nothing here, but return 0 to allow resize2fs to run (growroot does not handle that).
|
||||
if [[ -f /usr/share/initramfs-tools/hooks/growroot ]] || [[ -f /usr/share/initramfs-tools/scripts/local-bottom/growroot ]]; then
|
||||
echo "partition resize skipped: growroot detected."
|
||||
return 0
|
||||
fi
|
||||
|
||||
# trim any btrfs subvolume identifier given in square brackets (e.g. /dev/mapper/armbian-root[/@])
|
||||
local rootsource=$(findmnt -n -o SOURCE / | sed 's~\[.*\]~~') # i.e. /dev/mmcblk0p1 or /dev/mapper/armbian-root
|
||||
|
||||
@@ -162,6 +171,7 @@ do_resize_crypt()
|
||||
do_expand_ext4()
|
||||
{
|
||||
echo -e "\n### [resize2fs] Start resizing ext4 partition $1 now\n" >> ${Log}
|
||||
echo "Running 'resize2fs ${rootpart}' now..."
|
||||
resize2fs ${rootpart} >> ${Log} 2>&1
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,287 @@
|
||||
From 3ec70749ae3cb072f19d886981a217121f776415 Mon Sep 17 00:00:00 2001
|
||||
From: Igor Pecovnik <igor.pecovnik@gmail.com>
|
||||
Date: Sat, 6 Nov 2021 19:15:23 +0100
|
||||
Subject: [PATCH] Revert "net: Remove net/ipx.h and uapi/linux/ipx.h header
|
||||
files"
|
||||
|
||||
This reverts commit 6c9b40844751ea30c72f7a2f92f4d704bc6b2927.
|
||||
---
|
||||
include/net/ipx.h | 171 +++++++++++++++++++++++++++++++++++++++
|
||||
include/uapi/linux/ipx.h | 87 ++++++++++++++++++++
|
||||
2 files changed, 258 insertions(+)
|
||||
create mode 100644 include/net/ipx.h
|
||||
create mode 100644 include/uapi/linux/ipx.h
|
||||
|
||||
diff --git a/include/net/ipx.h b/include/net/ipx.h
|
||||
new file mode 100644
|
||||
index 000000000000..9d1342807b59
|
||||
--- /dev/null
|
||||
+++ b/include/net/ipx.h
|
||||
@@ -0,0 +1,171 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 */
|
||||
+#ifndef _NET_INET_IPX_H_
|
||||
+#define _NET_INET_IPX_H_
|
||||
+/*
|
||||
+ * The following information is in its entirety obtained from:
|
||||
+ *
|
||||
+ * Novell 'IPX Router Specification' Version 1.10
|
||||
+ * Part No. 107-000029-001
|
||||
+ *
|
||||
+ * Which is available from ftp.novell.com
|
||||
+ */
|
||||
+
|
||||
+#include <linux/netdevice.h>
|
||||
+#include <net/datalink.h>
|
||||
+#include <linux/ipx.h>
|
||||
+#include <linux/list.h>
|
||||
+#include <linux/slab.h>
|
||||
+#include <linux/refcount.h>
|
||||
+
|
||||
+struct ipx_address {
|
||||
+ __be32 net;
|
||||
+ __u8 node[IPX_NODE_LEN];
|
||||
+ __be16 sock;
|
||||
+};
|
||||
+
|
||||
+#define ipx_broadcast_node "\377\377\377\377\377\377"
|
||||
+#define ipx_this_node "\0\0\0\0\0\0"
|
||||
+
|
||||
+#define IPX_MAX_PPROP_HOPS 8
|
||||
+
|
||||
+struct ipxhdr {
|
||||
+ __be16 ipx_checksum __packed;
|
||||
+#define IPX_NO_CHECKSUM cpu_to_be16(0xFFFF)
|
||||
+ __be16 ipx_pktsize __packed;
|
||||
+ __u8 ipx_tctrl;
|
||||
+ __u8 ipx_type;
|
||||
+#define IPX_TYPE_UNKNOWN 0x00
|
||||
+#define IPX_TYPE_RIP 0x01 /* may also be 0 */
|
||||
+#define IPX_TYPE_SAP 0x04 /* may also be 0 */
|
||||
+#define IPX_TYPE_SPX 0x05 /* SPX protocol */
|
||||
+#define IPX_TYPE_NCP 0x11 /* $lots for docs on this (SPIT) */
|
||||
+#define IPX_TYPE_PPROP 0x14 /* complicated flood fill brdcast */
|
||||
+ struct ipx_address ipx_dest __packed;
|
||||
+ struct ipx_address ipx_source __packed;
|
||||
+};
|
||||
+
|
||||
+/* From af_ipx.c */
|
||||
+extern int sysctl_ipx_pprop_broadcasting;
|
||||
+
|
||||
+struct ipx_interface {
|
||||
+ /* IPX address */
|
||||
+ __be32 if_netnum;
|
||||
+ unsigned char if_node[IPX_NODE_LEN];
|
||||
+ refcount_t refcnt;
|
||||
+
|
||||
+ /* physical device info */
|
||||
+ struct net_device *if_dev;
|
||||
+ struct datalink_proto *if_dlink;
|
||||
+ __be16 if_dlink_type;
|
||||
+
|
||||
+ /* socket support */
|
||||
+ unsigned short if_sknum;
|
||||
+ struct hlist_head if_sklist;
|
||||
+ spinlock_t if_sklist_lock;
|
||||
+
|
||||
+ /* administrative overhead */
|
||||
+ int if_ipx_offset;
|
||||
+ unsigned char if_internal;
|
||||
+ unsigned char if_primary;
|
||||
+
|
||||
+ struct list_head node; /* node in ipx_interfaces list */
|
||||
+};
|
||||
+
|
||||
+struct ipx_route {
|
||||
+ __be32 ir_net;
|
||||
+ struct ipx_interface *ir_intrfc;
|
||||
+ unsigned char ir_routed;
|
||||
+ unsigned char ir_router_node[IPX_NODE_LEN];
|
||||
+ struct list_head node; /* node in ipx_routes list */
|
||||
+ refcount_t refcnt;
|
||||
+};
|
||||
+
|
||||
+struct ipx_cb {
|
||||
+ u8 ipx_tctrl;
|
||||
+ __be32 ipx_dest_net;
|
||||
+ __be32 ipx_source_net;
|
||||
+ struct {
|
||||
+ __be32 netnum;
|
||||
+ int index;
|
||||
+ } last_hop;
|
||||
+};
|
||||
+
|
||||
+#include <net/sock.h>
|
||||
+
|
||||
+struct ipx_sock {
|
||||
+ /* struct sock has to be the first member of ipx_sock */
|
||||
+ struct sock sk;
|
||||
+ struct ipx_address dest_addr;
|
||||
+ struct ipx_interface *intrfc;
|
||||
+ __be16 port;
|
||||
+#ifdef CONFIG_IPX_INTERN
|
||||
+ unsigned char node[IPX_NODE_LEN];
|
||||
+#endif
|
||||
+ unsigned short type;
|
||||
+ /*
|
||||
+ * To handle special ncp connection-handling sockets for mars_nwe,
|
||||
+ * the connection number must be stored in the socket.
|
||||
+ */
|
||||
+ unsigned short ipx_ncp_conn;
|
||||
+};
|
||||
+
|
||||
+static inline struct ipx_sock *ipx_sk(struct sock *sk)
|
||||
+{
|
||||
+ return (struct ipx_sock *)sk;
|
||||
+}
|
||||
+
|
||||
+#define IPX_SKB_CB(__skb) ((struct ipx_cb *)&((__skb)->cb[0]))
|
||||
+
|
||||
+#define IPX_MIN_EPHEMERAL_SOCKET 0x4000
|
||||
+#define IPX_MAX_EPHEMERAL_SOCKET 0x7fff
|
||||
+
|
||||
+extern struct list_head ipx_routes;
|
||||
+extern rwlock_t ipx_routes_lock;
|
||||
+
|
||||
+extern struct list_head ipx_interfaces;
|
||||
+struct ipx_interface *ipx_interfaces_head(void);
|
||||
+extern spinlock_t ipx_interfaces_lock;
|
||||
+
|
||||
+extern struct ipx_interface *ipx_primary_net;
|
||||
+
|
||||
+int ipx_proc_init(void);
|
||||
+void ipx_proc_exit(void);
|
||||
+
|
||||
+const char *ipx_frame_name(__be16);
|
||||
+const char *ipx_device_name(struct ipx_interface *intrfc);
|
||||
+
|
||||
+static __inline__ void ipxitf_hold(struct ipx_interface *intrfc)
|
||||
+{
|
||||
+ refcount_inc(&intrfc->refcnt);
|
||||
+}
|
||||
+
|
||||
+void ipxitf_down(struct ipx_interface *intrfc);
|
||||
+struct ipx_interface *ipxitf_find_using_net(__be32 net);
|
||||
+int ipxitf_send(struct ipx_interface *intrfc, struct sk_buff *skb, char *node);
|
||||
+__be16 ipx_cksum(struct ipxhdr *packet, int length);
|
||||
+int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc,
|
||||
+ unsigned char *node);
|
||||
+void ipxrtr_del_routes(struct ipx_interface *intrfc);
|
||||
+int ipxrtr_route_packet(struct sock *sk, struct sockaddr_ipx *usipx,
|
||||
+ struct msghdr *msg, size_t len, int noblock);
|
||||
+int ipxrtr_route_skb(struct sk_buff *skb);
|
||||
+struct ipx_route *ipxrtr_lookup(__be32 net);
|
||||
+int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
|
||||
+
|
||||
+static __inline__ void ipxitf_put(struct ipx_interface *intrfc)
|
||||
+{
|
||||
+ if (refcount_dec_and_test(&intrfc->refcnt))
|
||||
+ ipxitf_down(intrfc);
|
||||
+}
|
||||
+
|
||||
+static __inline__ void ipxrtr_hold(struct ipx_route *rt)
|
||||
+{
|
||||
+ refcount_inc(&rt->refcnt);
|
||||
+}
|
||||
+
|
||||
+static __inline__ void ipxrtr_put(struct ipx_route *rt)
|
||||
+{
|
||||
+ if (refcount_dec_and_test(&rt->refcnt))
|
||||
+ kfree(rt);
|
||||
+}
|
||||
+#endif /* _NET_INET_IPX_H_ */
|
||||
diff --git a/include/uapi/linux/ipx.h b/include/uapi/linux/ipx.h
|
||||
new file mode 100644
|
||||
index 000000000000..3168137adae8
|
||||
--- /dev/null
|
||||
+++ b/include/uapi/linux/ipx.h
|
||||
@@ -0,0 +1,87 @@
|
||||
+/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */
|
||||
+#ifndef _IPX_H_
|
||||
+#define _IPX_H_
|
||||
+#include <linux/libc-compat.h> /* for compatibility with glibc netipx/ipx.h */
|
||||
+#include <linux/types.h>
|
||||
+#include <linux/sockios.h>
|
||||
+#include <linux/socket.h>
|
||||
+#define IPX_NODE_LEN 6
|
||||
+#define IPX_MTU 576
|
||||
+
|
||||
+#if __UAPI_DEF_SOCKADDR_IPX
|
||||
+struct sockaddr_ipx {
|
||||
+ __kernel_sa_family_t sipx_family;
|
||||
+ __be16 sipx_port;
|
||||
+ __be32 sipx_network;
|
||||
+ unsigned char sipx_node[IPX_NODE_LEN];
|
||||
+ __u8 sipx_type;
|
||||
+ unsigned char sipx_zero; /* 16 byte fill */
|
||||
+};
|
||||
+#endif /* __UAPI_DEF_SOCKADDR_IPX */
|
||||
+
|
||||
+/*
|
||||
+ * So we can fit the extra info for SIOCSIFADDR into the address nicely
|
||||
+ */
|
||||
+#define sipx_special sipx_port
|
||||
+#define sipx_action sipx_zero
|
||||
+#define IPX_DLTITF 0
|
||||
+#define IPX_CRTITF 1
|
||||
+
|
||||
+#if __UAPI_DEF_IPX_ROUTE_DEFINITION
|
||||
+struct ipx_route_definition {
|
||||
+ __be32 ipx_network;
|
||||
+ __be32 ipx_router_network;
|
||||
+ unsigned char ipx_router_node[IPX_NODE_LEN];
|
||||
+};
|
||||
+#endif /* __UAPI_DEF_IPX_ROUTE_DEFINITION */
|
||||
+
|
||||
+#if __UAPI_DEF_IPX_INTERFACE_DEFINITION
|
||||
+struct ipx_interface_definition {
|
||||
+ __be32 ipx_network;
|
||||
+ unsigned char ipx_device[16];
|
||||
+ unsigned char ipx_dlink_type;
|
||||
+#define IPX_FRAME_NONE 0
|
||||
+#define IPX_FRAME_SNAP 1
|
||||
+#define IPX_FRAME_8022 2
|
||||
+#define IPX_FRAME_ETHERII 3
|
||||
+#define IPX_FRAME_8023 4
|
||||
+#define IPX_FRAME_TR_8022 5 /* obsolete */
|
||||
+ unsigned char ipx_special;
|
||||
+#define IPX_SPECIAL_NONE 0
|
||||
+#define IPX_PRIMARY 1
|
||||
+#define IPX_INTERNAL 2
|
||||
+ unsigned char ipx_node[IPX_NODE_LEN];
|
||||
+};
|
||||
+#endif /* __UAPI_DEF_IPX_INTERFACE_DEFINITION */
|
||||
+
|
||||
+#if __UAPI_DEF_IPX_CONFIG_DATA
|
||||
+struct ipx_config_data {
|
||||
+ unsigned char ipxcfg_auto_select_primary;
|
||||
+ unsigned char ipxcfg_auto_create_interfaces;
|
||||
+};
|
||||
+#endif /* __UAPI_DEF_IPX_CONFIG_DATA */
|
||||
+
|
||||
+/*
|
||||
+ * OLD Route Definition for backward compatibility.
|
||||
+ */
|
||||
+
|
||||
+#if __UAPI_DEF_IPX_ROUTE_DEF
|
||||
+struct ipx_route_def {
|
||||
+ __be32 ipx_network;
|
||||
+ __be32 ipx_router_network;
|
||||
+#define IPX_ROUTE_NO_ROUTER 0
|
||||
+ unsigned char ipx_router_node[IPX_NODE_LEN];
|
||||
+ unsigned char ipx_device[16];
|
||||
+ unsigned short ipx_flags;
|
||||
+#define IPX_RT_SNAP 8
|
||||
+#define IPX_RT_8022 4
|
||||
+#define IPX_RT_BLUEBOOK 2
|
||||
+#define IPX_RT_ROUTED 1
|
||||
+};
|
||||
+#endif /* __UAPI_DEF_IPX_ROUTE_DEF */
|
||||
+
|
||||
+#define SIOCAIPXITFCRT (SIOCPROTOPRIVATE)
|
||||
+#define SIOCAIPXPRISLT (SIOCPROTOPRIVATE + 1)
|
||||
+#define SIOCIPXCFGDATA (SIOCPROTOPRIVATE + 2)
|
||||
+#define SIOCIPXNCPCONN (SIOCPROTOPRIVATE + 3)
|
||||
+#endif /* _IPX_H_ */
|
||||
--
|
||||
2.25.1
|
||||
|
||||
1
patch/kernel/uefi-x86-edge
Symbolic link
1
patch/kernel/uefi-x86-edge
Symbolic link
@@ -0,0 +1 @@
|
||||
archive/uefi-x86-5.15
|
||||
Reference in New Issue
Block a user