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:
Ricardo Pardini
2021-12-06 09:49:49 +01:00
committed by GitHub
parent 2ab8795ae9
commit 90e0fe0ba2
59 changed files with 35711 additions and 260 deletions

View File

@@ -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
View 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
}

View 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"

View 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"

View File

@@ -1,4 +1,3 @@
code
emacs
geany
vim

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

View File

@@ -1 +1 @@
arm64
arm64, amd64

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

19
config/sources/amd64.conf Normal file
View 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

View File

@@ -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-/-}"

View 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
}

View File

@@ -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"
}

View File

@@ -1,3 +1,4 @@
enable_extension "rkbin-tools"
ARCH=arm64
KERNEL_IMAGE_TYPE=Image
OFFSET=16

View File

@@ -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

View File

@@ -1,3 +1,4 @@
enable_extension "sunxi-tools"
ARCH=armhf
BOOTDELAY=1
BOOTPATCHDIR='u-boot-sunxi'

View 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

View File

@@ -1,3 +1,4 @@
enable_extension "marvell-tools"
ARCH=armhf
if [[ $BOARD == helios4 ]]; then
source "${BASH_SOURCE%/*}/include/mvebu-helios4.inc"

View File

@@ -1,3 +1,4 @@
enable_extension "marvell-tools"
ARCH=arm64
BOOTBRANCH='branch:v2021.01'
BOOTENV_FILE='mvebu64.txt'

View 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"

View 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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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 \

View 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
View 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"
}

View 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
View 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
}

View 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
View 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
View 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
}

View File

@@ -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))

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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
View 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
}

View File

@@ -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

View File

@@ -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
}

View File

@@ -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))

View File

@@ -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"

View File

@@ -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

View File

@@ -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"

View File

@@ -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
}

View File

@@ -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
View File

@@ -0,0 +1 @@
archive/uefi-x86-5.15