Skip to content

Commit 9e10a14

Browse files
authored
Merge branch 'main' into desktop-to-armbian-config
2 parents 2fd03d0 + 7c39bd9 commit 9e10a14

1,625 files changed

Lines changed: 652 additions & 264589 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
name: "Validate board configs"
2+
3+
# Runs on PRs that touch config/boards/*. Validates only the changed
4+
# files (not all 500+) via tools/validate-board-config.py and emits
5+
# GitHub Actions annotations on the PR diff. Blocks merge on errors.
6+
7+
on:
8+
pull_request:
9+
paths:
10+
- "config/boards/**"
11+
- "tools/validate-board-config.py"
12+
- ".github/workflows/maintenance-validate-board-configs.yml"
13+
14+
permissions:
15+
contents: read
16+
pull-requests: read
17+
18+
jobs:
19+
validate:
20+
name: "Validate changed board configs"
21+
runs-on: ubuntu-latest
22+
steps:
23+
- name: "Checkout PR"
24+
uses: actions/checkout@v4
25+
with:
26+
# Need the merge-base to compute changed files; depth 0 is
27+
# heaviest but bulletproof. Most PRs are small enough this
28+
# is fine; switch to fetch-depth: 2 + explicit base ref if
29+
# repo size becomes a problem.
30+
fetch-depth: 0
31+
32+
- name: "Set up Python"
33+
uses: actions/setup-python@v5
34+
with:
35+
python-version: "3.12"
36+
37+
- name: "Collect changed board configs"
38+
id: changed
39+
run: |
40+
set -euo pipefail
41+
base="${{ github.event.pull_request.base.sha }}"
42+
head="${{ github.event.pull_request.head.sha }}"
43+
44+
# Limit to known config-bearing extensions to avoid wasting CI
45+
# cycles on README.md or other non-config files in the dir.
46+
mapfile -t files < <(
47+
git diff --name-only --diff-filter=ACMR "${base}" "${head}" -- 'config/boards/*.conf' 'config/boards/*.csc' 'config/boards/*.tvb' 'config/boards/*.wip' 'config/boards/*.eos'
48+
)
49+
50+
echo "Changed board configs: ${#files[@]}"
51+
printf ' %s\n' "${files[@]}"
52+
53+
# Output the list as a space-joined string for the next step.
54+
# If empty, set a marker so we can short-circuit.
55+
if [[ ${#files[@]} -eq 0 ]]; then
56+
echo "files=" >> "$GITHUB_OUTPUT"
57+
else
58+
echo "files=${files[*]}" >> "$GITHUB_OUTPUT"
59+
fi
60+
61+
- name: "Run validator"
62+
if: steps.changed.outputs.files != ''
63+
env:
64+
FILES: ${{ steps.changed.outputs.files }}
65+
run: |
66+
set -euo pipefail
67+
# shellcheck disable=SC2086
68+
python3 tools/validate-board-config.py --github ${FILES}
69+
70+
- name: "No board configs changed"
71+
if: steps.changed.outputs.files == ''
72+
run: echo "No config/boards/*.{conf,csc,tvb,wip,eos} changes in this PR — nothing to validate."

extensions/gateway-dk-ask.sh

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# Source repos and refs (pinned to match Yocto)
1616
# For local testing: set ASK_REPO="file:///path/to/ASK" — the Docker mount hook below handles it
1717
declare -g ASK_REPO="https://github.com/we-are-mono/ASK.git"
18-
declare -g ASK_BRANCH="commit:252b6db5a274383917c7a7688c931d61409978c2"
18+
declare -g ASK_BRANCH="commit:a211ea865379362058c6656b9c448e4a7050e93c"
1919
declare -g FMLIB_REPO="https://github.com/nxp-qoriq/fmlib.git"
2020
declare -g FMLIB_COMMIT="7a58ecaf0d90d71d6b78d3ac7998282a472c4394"
2121
declare -g FMC_REPO="https://github.com/nxp-qoriq/fmc.git"
@@ -161,11 +161,13 @@ function post_install_kernel_debs__ask_module_autoload() {
161161

162162
# Copy patches into chroot before patched library builds (runs before build_ask_userspace)
163163
function pre_customize_image__000_prepare_ask_patches() {
164-
mkdir -p "${SDCARD}/tmp/ask-patches"
164+
# Stage per-package trees (version subdirs preserved) so rebuild_patched_deb
165+
# can pick the patch matching the upstream source version.
165166
local patch_dirs=("libnetfilter-conntrack" "libnfnetlink")
166167
for pdir in "${patch_dirs[@]}"; do
167168
[[ -d "${ASK_CACHE_DIR}/patches/${pdir}" ]] || exit_with_error "ASK patch directory missing" "${ASK_CACHE_DIR}/patches/${pdir}"
168-
cp "${ASK_CACHE_DIR}/patches/${pdir}/"*.patch "${SDCARD}/tmp/ask-patches/"
169+
mkdir -p "${SDCARD}/tmp/ask-patches/${pdir}"
170+
cp -a "${ASK_CACHE_DIR}/patches/${pdir}/." "${SDCARD}/tmp/ask-patches/${pdir}/"
169171
done
170172

171173
# Enable deb-src for apt-get source (handles both Debian and Ubuntu)
@@ -409,8 +411,8 @@ Version: ${ask_version}
409411
Architecture: arm64
410412
Section: net
411413
Priority: optional
412-
Maintainer: Mono Technologies <support@mono.si>
413-
Depends: linux-image-${BRANCH}-${LINUXFAMILY} (>= ${kernel_ver}), libxml2, libpcap0.8, iptables
414+
Maintainer: Tomaz Zaman <tomaz@mono.si>
415+
Depends: linux-image-${BRANCH}-${LINUXFAMILY} (>= ${kernel_ver}), libxml2 | libxml2-16, libpcap0.8, iptables
414416
Description: NXP ASK hardware offloading userspace for Mono Gateway DK
415417
Userspace tools (fmlib, fmc, libfci, libcli, dpa-app, cmm) and configuration
416418
for NXP ASK data-plane acceleration on the LS1046A Gateway DK.
@@ -452,6 +454,9 @@ EOF
452454
/etc/cdx_pcd.xml
453455
/etc/cdx_sp.xml
454456
/etc/config/fastforward
457+
/etc/fmc/config/cfgdata.xsd
458+
/etc/fmc/config/hxs_pdl_v3.xml
459+
/etc/fmc/config/netpcd.xsd
455460
/etc/sysctl.d/99-ls1046a-conntrack.conf
456461
CONFFILES
457462

@@ -461,7 +466,8 @@ CONFFILES
461466
run_host_command_logged dpkg-deb -b "${pkgdir}" "${SRC}/output/debs/${debfile}" \
462467
|| exit_with_error "dpkg-deb failed for ${debfile}"
463468
cp "${SRC}/output/debs/${debfile}" "${SDCARD}/root/"
464-
chroot_sdcard "dpkg -i /root/${debfile}" || exit_with_error "dpkg -i failed for ${debfile}"
469+
chroot_sdcard "DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends /root/${debfile}" \
470+
|| exit_with_error "apt install failed for ${debfile}"
465471
rm -f "${SDCARD}/root/${debfile}"
466472

467473
rm -rf "${pkgdir}"
@@ -495,8 +501,12 @@ function build_ask_patched_libraries() {
495501
rm -rf "${SDCARD}/tmp/ask-patched-debs"
496502
}
497503

498-
# Helper: rebuild a Debian package with an ASK patch in an isolated chroot directory
504+
# Helper: rebuild a Debian package with an ASK patch in an isolated chroot directory.
499505
# Usage: rebuild_patched_deb <pkg_name> <patch_file> <deb_globs>
506+
# The patch is resolved under /tmp/ask-patches/<pkg>/<upstream_version>/<patch_file>,
507+
# where <upstream_version> is parsed from the source tree's debian/changelog after
508+
# apt-get source. This lets a single ASK repo cover multiple target distros whose
509+
# upstream library versions differ (e.g. Trixie/Noble 1.1.0 vs Resolute 1.1.1).
500510
function rebuild_patched_deb() {
501511
local pkg="$1" patch="$2" debs="$3"
502512
local workdir="/tmp/ask-rebuild-${pkg}"
@@ -507,7 +517,14 @@ function rebuild_patched_deb() {
507517
rm -rf '${workdir}' && mkdir -p '${workdir}' && cd '${workdir}' && \
508518
apt-get source '${pkg}' && \
509519
cd \$(ls -d ${pkg}-*/ | head -1) && \
510-
patch -p1 < '/tmp/ask-patches/${patch}' && \
520+
upstream_ver=\$(dpkg-parsechangelog -l debian/changelog -S Version \
521+
| sed -E 's/^[0-9]+://; s/-[^-]+\$//; s/^([0-9]+\\.[0-9]+\\.[0-9]+).*/\\1/') && \
522+
patch_path=\"/tmp/ask-patches/${pkg}/\${upstream_ver}/${patch}\" && \
523+
if [ ! -f \"\${patch_path}\" ]; then \
524+
echo \"ERROR: no ASK patch for ${pkg} upstream \${upstream_ver} (looked for \${patch_path})\" >&2; \
525+
exit 1; \
526+
fi && \
527+
patch -p1 < \"\${patch_path}\" && \
511528
DEB_BUILD_OPTIONS=nocheck dpkg-buildpackage -b -uc -us && \
512529
cd '${workdir}' && dpkg -i ${debs} && \
513530
cp ${debs} /tmp/ask-patched-debs/ && \

extensions/grub-riscv64.sh

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,9 +112,17 @@ configure_grub() {
112112
[[ -n "$SERIALCON" ]] &&
113113
GRUB_CMDLINE_LINUX_DEFAULT+=" console=${SERIALCON}"
114114

115-
[[ "$BOOT_LOGO" == "yes" || "$BOOT_LOGO" == "desktop" && "$BUILD_DESKTOP" == "yes" ]] &&
116-
GRUB_CMDLINE_LINUX_DEFAULT+=" quiet splash plymouth.ignore-serial-consoles i915.force_probe=* loglevel=3" ||
117-
GRUB_CMDLINE_LINUX_DEFAULT+=" splash=verbose i915.force_probe=*"
115+
# Kernel cmdline. Always pass the graphical-Plymouth flags
116+
# regardless of whether this image is being built as CLI or
117+
# desktop — same reasoning as in extensions/grub.sh: users
118+
# add a desktop later via armbian-config and we can't
119+
# regenerate grub.cfg from there. Plymouth handles the
120+
# "no theme installed" / "no DRM" cases gracefully.
121+
# (No i915.force_probe here — that's an x86 Intel-graphics
122+
# driver knob and is meaningless on riscv64. No 'quiet' /
123+
# 'loglevel=3' either: kernel boot messages stay visible
124+
# underneath the splash so users can see what's happening.)
125+
GRUB_CMDLINE_LINUX_DEFAULT+=" splash plymouth.ignore-serial-consoles"
118126

119127
# Enable Armbian Wallpaper on GRUB
120128
if [[ "${VENDOR}" == Armbian ]]; then
@@ -135,7 +143,7 @@ configure_grub() {
135143
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)
136144
GRUB_DISABLE_OS_PROBER=false # Have to be explicit about enabling os-prober
137145
GRUB_GFXMODE=1024x768
138-
GRUB_GFXPAYLOAD=keep
146+
GRUB_GFXPAYLOAD_LINUX=text # See extensions/grub.sh — correct var name is GRUB_GFXPAYLOAD_LINUX, not GRUB_GFXPAYLOAD, and 'text' disables Ubuntu's vt.handoff=7 injection.
139147
GRUB_DISABLE_UUID=false # Be explicit about wanting UUID
140148
GRUB_DISABLE_LINUX_UUID=false # Be explicit about wanting UUID
141149
grubCfgFrag

extensions/grub.sh

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -265,9 +265,29 @@ configure_grub() {
265265
[[ -n "$SERIALCON" ]] &&
266266
GRUB_CMDLINE_LINUX_DEFAULT+=" console=${SERIALCON}"
267267

268-
[[ "$BOOT_LOGO" == "yes" || "$BOOT_LOGO" == "desktop" && "$BUILD_DESKTOP" == "yes" ]] &&
269-
GRUB_CMDLINE_LINUX_DEFAULT+=" quiet splash plymouth.ignore-serial-consoles i915.force_probe=* loglevel=3" ||
270-
GRUB_CMDLINE_LINUX_DEFAULT+=" splash=verbose i915.force_probe=*"
268+
# Kernel cmdline. We always pass the graphical-Plymouth flags
269+
# (splash plymouth.ignore-serial-consoles) on UEFI x86,
270+
# regardless of whether this image is being built as CLI or
271+
# desktop. Two reasons:
272+
# 1. Users routinely add a desktop later via armbian-config
273+
# and we don't want that to require regenerating grub.cfg.
274+
# The .cfg is baked once at image-build time and stays
275+
# put across desktop installs.
276+
# 2. Plymouth handles the "no theme installed" / "no DRM"
277+
# cases gracefully — the flags are harmless on a CLI
278+
# install. They are NOT harmless when wrong: the previous
279+
# 'splash=verbose' value was rejected by the kernel
280+
# ("Unknown kernel command line parameters splash=verbose"
281+
# in dmesg) AND interpreted by Plymouth as "render the
282+
# verbose/text theme", so a desktop installed later still
283+
# booted to a black/text screen.
284+
#
285+
# Deliberately NO 'quiet' and NO 'loglevel=3' here. Plymouth
286+
# still draws the splash on top of the kernel boot messages,
287+
# but the messages remain visible underneath so users can see
288+
# what their system is doing. Press Esc during boot to drop
289+
# the splash and read the messages directly.
290+
GRUB_CMDLINE_LINUX_DEFAULT+=" splash plymouth.ignore-serial-consoles i915.force_probe=*"
271291

272292
# Enable Armbian Wallpaper on GRUB
273293
if [[ "${VENDOR}" == Armbian ]]; then
@@ -290,7 +310,7 @@ configure_grub() {
290310
GRUB_DISABLE_SUBMENU=y # Do not put all kernel options into a submenu, instead, list them all on the main menu.
291311
GRUB_DISABLE_OS_PROBER=false # Have to be explicit about enabling os-prober
292312
GRUB_FONT="/usr/share/grub/unicode.pf2" # Be explicit about the font to use so Ubuntu does not freak out and mess gfxterm
293-
GRUB_GFXPAYLOAD=keep
313+
GRUB_GFXPAYLOAD_LINUX=text # Note the correct var name is GRUB_GFXPAYLOAD_LINUX, not GRUB_GFXPAYLOAD (the latter is silently ignored). The 'text' value disables Ubuntu's vt.handoff=7 injection: Ubuntu's grub2 10_linux only expands 'vt.handoff=7' inside grub.cfg's gfxmode function when the gfxpayload arg is exactly 'keep'. Setting it to 'text' makes the runtime check fail and the framebuffer console stays bound to fbcon for the entire userspace lifetime — which is what we want, otherwise after Plymouth quits on a CLI install (or after the user uninstalls the desktop), the kernel hands the framebuffer to VT7 waiting for an X server, nothing ever claims it, and the local console goes black even though getty@tty1 is running.
294314
GRUB_DISABLE_UUID=false # Be explicit about wanting UUID
295315
GRUB_DISABLE_LINUX_UUID=false # Be explicit about wanting UUID
296316
grubCfgFrag
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#!/usr/bin/env bash
2+
#
3+
# SPDX-License-Identifier: GPL-2.0
4+
#
5+
# Copyright (c) 2013-2026 Igor Pecovnik, igor@armbian.com
6+
#
7+
# This file is a part of the Armbian Build Framework
8+
# https://github.com/armbian/build/
9+
#
10+
# Fix binman's use of pkg_resources (removed in setuptools >= 82)
11+
# by migrating to importlib.resources.
12+
#
13+
# Safe for all U-Boot versions: no-op if pkg_resources is not used.
14+
# Can be removed once all BOOTBRANCH versions are >= v2025.10.
15+
16+
function pre_config_uboot_target__fix_binman_pkg_resources() {
17+
local control_py="tools/binman/control.py"
18+
19+
# Skip if file doesn't exist or doesn't use pkg_resources
20+
[[ -f "${control_py}" ]] || return 0
21+
grep -q 'import pkg_resources' "${control_py}" || return 0
22+
23+
display_alert "Patching binman" "migrating pkg_resources to importlib.resources" "info"
24+
25+
python3 << 'PYTHON_SCRIPT'
26+
import re
27+
28+
control_py = "tools/binman/control.py"
29+
30+
with open(control_py, "r") as f:
31+
content = f.read()
32+
33+
# 1. Remove "import pkg_resources" line
34+
content = re.sub(r'^import pkg_resources\b[^\n]*\n', '', content, flags=re.MULTILINE)
35+
36+
# 2. Ensure importlib_resources alias is available
37+
has_importlib_alias = 'importlib_resources' in content
38+
has_importlib_dotted = re.search(r'^import importlib\.resources\s*$', content, flags=re.MULTILINE)
39+
40+
if not has_importlib_alias and has_importlib_dotted:
41+
# New U-Boot (v2024.01+): has "import importlib.resources" without alias
42+
content = re.sub(
43+
r'^import importlib\.resources\s*$',
44+
'import importlib.resources as importlib_resources',
45+
content, count=1, flags=re.MULTILINE
46+
)
47+
# Update existing dotted usage to use the alias
48+
content = re.sub(r'\bimportlib\.resources\.', 'importlib_resources.', content)
49+
elif not has_importlib_alias:
50+
# Old U-Boot (<=v2023.x): no importlib.resources at all
51+
import_block = (
52+
'try:\n'
53+
' import importlib.resources as importlib_resources\n'
54+
' importlib_resources.files\n'
55+
'except (ImportError, AttributeError):\n'
56+
' import importlib_resources\n'
57+
)
58+
# Insert after the last top-level import line
59+
lines = content.split('\n')
60+
last_import_idx = 0
61+
for i, line in enumerate(lines):
62+
if re.match(r'^(?:import |from \S+ import )', line):
63+
last_import_idx = i
64+
lines.insert(last_import_idx + 1, import_block)
65+
content = '\n'.join(lines)
66+
67+
# 3. Replace pkg_resources.resource_string(__name__, X)
68+
# with importlib_resources.files(__package__).joinpath(X).read_bytes()
69+
content = re.sub(
70+
r'pkg_resources\.resource_string\s*\(\s*__name__\s*,\s*(.+?)\s*\)',
71+
r'importlib_resources.files(__package__).joinpath(\1).read_bytes()',
72+
content
73+
)
74+
75+
# 4. Replace pkg_resources.resource_listdir(__name__, X)
76+
# with [r.name for r in importlib_resources.files(__package__).joinpath(X).iterdir() if r.is_file()]
77+
content = re.sub(
78+
r'pkg_resources\.resource_listdir\s*\(\s*__name__\s*,\s*(.+?)\s*\)',
79+
r'[r.name for r in importlib_resources.files(__package__).joinpath(\1).iterdir() if r.is_file()]',
80+
content
81+
)
82+
83+
with open(control_py, "w") as f:
84+
f.write(content)
85+
86+
print("binman control.py patched successfully")
87+
PYTHON_SCRIPT
88+
}

lib/functions/artifacts/artifact-armbian-base-files.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,25 @@ function compile_armbian-base-files() {
168168
sed -i "s|^PRIVACY_POLICY_URL=.*|PRIVACY_POLICY_URL=\"${VENDORPRIVACY}\"|" "${destination}"/etc/os-release
169169
sed -i "s|^LOGO=.*|LOGO=\"${VENDORLOGO}\"|" "${destination}"/etc/os-release
170170

171+
# Replace Ubuntu logo files with symlinks to Armbian's.
172+
# Ubuntu hardcodes lookups for ubuntu-logo*.svg / ubuntu-logo*.png
173+
# in GNOME Settings → About and other places. The Armbian logos
174+
# are shipped by armbian-bsp-cli (packages/bsp/common/usr/share/
175+
# pixmaps/armbian-logo*). Since we own this base-files repack,
176+
# we can safely replace the upstream files with relative symlinks.
177+
if [[ -d "${destination}/usr/share/pixmaps" ]]; then
178+
for suffix in ".svg" "-text.png" "-text-dark.png" "-text.svg" "-text-dark.svg"; do
179+
# Only replace files actually present in the upstream
180+
# base-files payload — don't create symlinks for variants
181+
# that don't exist in this release.
182+
local upstream="${destination}/usr/share/pixmaps/ubuntu-logo${suffix}"
183+
if [[ -f "${upstream}" ]]; then
184+
rm -f "${upstream}"
185+
ln -sf "armbian-logo${suffix}" "${upstream}"
186+
fi
187+
done
188+
fi
189+
171190
# Remove content from motd: Ubuntu header, welcome text and news. We have our own
172191
rm -f "${destination}"/etc/update-motd.d/00-header
173192
sed -i "\/etc\/update-motd.d\/00-header/d" "${destination}/DEBIAN/conffiles"

lib/functions/artifacts/artifact-kernel.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ function artifact_kernel_prepare_version() {
125125

126126
# run the extensions. they _must_ behave, and not try to modify the .config, instead just fill kernel_config_modifying_hashes
127127
declare kernel_config_modifying_hashes_hash="undetermined"
128-
declare -a kernel_config_modifying_hashes=()
128+
declare -ga kernel_config_modifying_hashes=()
129129
call_extensions_kernel_config
130130
# Reduce to last assignment per key to keep hashing stable and ignore overridden options.
131131
# tac reverses order so last becomes first, then sort -uk keeps first occurrence of each key.

lib/functions/compilation/armbian-kernel.sh

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,7 @@ function kernel_config_set_m() {
616616
declare module="$1"
617617
display_alert "Enabling kernel module" "${module}=m" "debug"
618618
run_host_command_logged ./scripts/config --module "${module}"
619+
kernel_config_modifying_hashes+=("${module}=m")
619620
}
620621

621622
# Sets a kernel configuration option to be built-in (=y).
@@ -627,6 +628,7 @@ function kernel_config_set_y() {
627628
declare config="$1"
628629
display_alert "Enabling kernel config/built-in" "${config}=y" "debug"
629630
run_host_command_logged ./scripts/config --enable "${config}"
631+
kernel_config_modifying_hashes+=("${config}=y")
630632
}
631633

632634
# Disables a kernel configuration option (=n).
@@ -637,6 +639,7 @@ function kernel_config_set_n() {
637639
declare config="$1"
638640
display_alert "Disabling kernel config/module" "${config}=n" "debug"
639641
run_host_command_logged ./scripts/config --disable "${config}"
642+
kernel_config_modifying_hashes+=("${config}=n")
640643
}
641644

642645
# Sets a kernel configuration option to a string value.
@@ -649,6 +652,7 @@ function kernel_config_set_string() {
649652
declare value="${2}"
650653
display_alert "Setting kernel config/module string" "${config}=${value}" "debug"
651654
run_host_command_logged ./scripts/config --set-str "${config}" "${value}"
655+
kernel_config_modifying_hashes+=("${config}=\"${value}\"")
652656
}
653657

654658
# Sets a kernel configuration option to a numeric or hexadecimal value.
@@ -661,6 +665,7 @@ function kernel_config_set_val() {
661665
declare value="${2}"
662666
display_alert "Setting kernel config/module value" "${config}=${value}" "debug"
663667
run_host_command_logged ./scripts/config --set-val "${config}" "${value}"
668+
kernel_config_modifying_hashes+=("${config}=${value}")
664669
}
665670

666671
# Applies kernel configuration options from arrays to hashes and the .config file.

0 commit comments

Comments
 (0)