Skip to content

Commit 437ae4f

Browse files
committed
add-dtbo: CLI to apply /etc/kernel/dtbo overlays to the booted entry
flipper-bls.sh: dt_overlay_line (+profile-only) shared by emit_entry and the new flipper_rewrite_overlay; add-dtbo (--list/--clear/--all-kernels, or copy FILE.dtbo) rewrites only the booted profile+kernel entry's devicetree-overlay line, no kernel-install.
1 parent 2108285 commit 437ae4f

2 files changed

Lines changed: 138 additions & 15 deletions

File tree

overlays/usr/lib/flipper-bls.sh

Lines changed: 53 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,15 @@ discover_devicetreedir() {
281281
OVERLAY_DIR="${DEVICETREEDIR_SRC:-$DTB_DIR}/$VENDOR"
282282
}
283283

284+
# devicetree-overlay value for an entry: profile overlays ($2 = dtbos names) + user drop-ins,
285+
# subvol-prefixed from $1 (options). Empty if none. Shared by emit_entry and flipper_rewrite_overlay.
286+
dt_overlay_line() {
287+
_p="$(fdt_prefix "$1")"
288+
_o="$(overlay_paths "$_p" $2 2>/dev/null)" || _o=""
289+
_u="$(user_overlay_paths "$_p")"
290+
printf '%s' "$_o${_o:+${_u:+ }}$_u"
291+
}
292+
284293
# emit_entry SUF EXTRA GATE DTBOS -> write one BLS entry for the current $ENTRY_TOKEN.
285294
# The filename is $ENTRY_TOKEN-$KERNEL_VERSION.conf. The token is <NN>-flipperos-<subvol>, so it
286295
# LEADS with the 3-digit menu band and U-Boot's bls (filename sort, descending) orders entries by
@@ -297,25 +306,14 @@ emit_entry() {
297306
_opts="$BASE_OPTS"
298307
[ -n "$_extra" ] && _opts="$_opts $_extra"
299308
_fn="$ENTRIES/$ENTRY_TOKEN-$KERNEL_VERSION.conf"
300-
_user="$(user_overlay_paths "$(fdt_prefix "$_opts")")" # user drop-ins, always optional
301-
302-
if [ -z "$_dtbos" ]; then
303-
write_entry "$_fn" "$(make_title "$_suf")" "$_opts" "$_user"
304-
return 0
305-
fi
306-
307-
# A leading '!' on the overlay list = required (skip the entry if the overlays are
308-
# absent); otherwise optional (the entry is still written, sans overlay).
309+
# a leading '!' on the list = required: skip the whole entry if those profile overlays are absent
309310
_required=0
310311
case "$_dtbos" in '!'*) _required=1; _dtbos="$(trim "${_dtbos#\!}")" ;; esac
311-
312-
_paths="$(overlay_paths "$(fdt_prefix "$_opts")" $_dtbos)" || _paths=""
313-
if [ -z "$_paths" ] && [ "$_required" = 1 ]; then
314-
log "skip $ENTRY_TOKEN (overlays not found for $KERNEL_VERSION)"
312+
if [ "$_required" = 1 ] && [ -z "$(overlay_paths "$(fdt_prefix "$_opts")" $_dtbos 2>/dev/null)" ]; then
313+
log "skip $ENTRY_TOKEN (required overlays not found for $KERNEL_VERSION)"
315314
return 0
316315
fi
317-
# profile overlays first, then the user's drop-ins layered on top
318-
write_entry "$_fn" "$(make_title "$_suf")" "$_opts" "$_paths${_paths:+${_user:+ }}$_user"
316+
write_entry "$_fn" "$(make_title "$_suf")" "$_opts" "$(dt_overlay_line "$_opts" "$_dtbos")"
319317
}
320318

321319
# flipper_write_entry <subvol> <mounted-path> [<origin-hint>]: write a BLS entry for an EXISTING
@@ -349,3 +347,43 @@ flipper_write_entry() {
349347
emit_entry "$(printf '%s' "$_name" | tr -d '@')" "rootflags=subvol=$_name" "" ""
350348
echo "flipper-bls: wrote entry for $_name (kernel $KERNEL_VERSION, token $ENTRY_TOKEN)"
351349
}
350+
351+
# Rewrite the devicetree-overlay line of the booted profile's BLS entries in place from the current
352+
# profile overlays + /etc/kernel/dtbo drop-ins, so changes take effect next boot without a full
353+
# kernel-install (no re-staging, no initrd rebuild).
354+
# $1 scope: ""=the RUNNING kernel's entry only, "all"=every installed kernel of this profile
355+
# Root only; reboot afterwards.
356+
flipper_rewrite_overlay() {
357+
_scope="${1:-}"
358+
[ "$(id -u)" -eq 0 ] || { echo "flipper-bls: must run as root (use sudo)" >&2; return 1; }
359+
ENTRIES="${KERNEL_INSTALL_BOOT_ROOT:-/boot}/loader/entries"
360+
CONF_ROOT="${KERNEL_INSTALL_CONF_ROOT:-/etc/kernel}"
361+
_sv="$(current_subvol)"
362+
[ -n "$_sv" ] || { echo "flipper-bls: cannot determine current subvol" >&2; return 1; }
363+
_run="$(uname -r)"
364+
365+
_dtbos=""
366+
_pf="${FLIPPER_PROFILES:-$CONF_ROOT/flipper-profiles}"
367+
if [ -f "$_pf" ]; then
368+
while IFS='|' read -r _t _s _e _g _d _r; do
369+
case "$_t" in ''|\#*) continue ;; esac
370+
if [ "$(subvol_of "$(trim "$_e")")" = "$_sv" ]; then _dtbos="$(trim "${_d#\!}")"; break; fi
371+
done <"$_pf"
372+
fi
373+
374+
_n=0
375+
for _f in "$ENTRIES"/*.conf; do
376+
[ -f "$_f" ] || continue
377+
_opts="$(sed -n 's/^options[[:space:]]*//p' "$_f")"
378+
[ "$(subvol_of "$_opts")" = "$_sv" ] || continue
379+
KERNEL_VERSION="$(sed -n 's/^version[[:space:]]*//p' "$_f")"
380+
[ -n "$KERNEL_VERSION" ] || continue
381+
[ "$_scope" = all ] || [ "$KERNEL_VERSION" = "$_run" ] || continue
382+
set_dtb_dirs; OVERLAY_DIR="$DTB_DIR/$VENDOR"
383+
_line="$(dt_overlay_line "$_opts" "$_dtbos")"
384+
sed -i '/^devicetree-overlay[[:space:]]/d' "$_f"
385+
[ -n "$_line" ] && printf 'devicetree-overlay %s\n' "$_line" >>"$_f"
386+
_n=$((_n + 1)); echo "flipper-bls: updated ${_f##*/}"
387+
done
388+
[ "$_n" -gt 0 ] || { echo "flipper-bls: no matching entries for $_sv" >&2; return 1; }
389+
}

overlays/usr/local/sbin/add-dtbo

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/bin/sh
2+
# add-dtbo - manage this profile's user device-tree overlays in /etc/kernel/dtbo and apply them to
3+
# the booted profile's BLS boot entry without a full kernel-install. Reboot to load changes. By
4+
# default only the BOOTED kernel's entry is touched; --all-kernels does every installed kernel.
5+
set -eu
6+
DROPDIR=/etc/kernel/dtbo
7+
8+
usage() {
9+
cat <<EOF
10+
Usage: add-dtbo [--all-kernels] FILE.dtbo ... copy each FILE into $DROPDIR, then apply
11+
add-dtbo [--all-kernels] --rm NAME ... remove each named overlay from $DROPDIR, then apply
12+
add-dtbo [--all-kernels] --apply apply the overlays already in $DROPDIR
13+
add-dtbo [--all-kernels] --clear remove all user overlays from $DROPDIR, then apply
14+
add-dtbo --list list the *.dtbo in $DROPDIR
15+
add-dtbo --help show this help
16+
EOF
17+
}
18+
19+
_scope=""; _action=""
20+
while [ $# -gt 0 ]; do
21+
case "$1" in
22+
--all-kernels) _scope=all ;;
23+
--rm) _action=rm ;;
24+
--apply) _action=apply ;;
25+
--clear) _action=clear ;;
26+
--list) _action=list ;;
27+
-h|--help) usage; exit 0 ;;
28+
--) shift; break ;;
29+
-?*) echo "Error: unknown option: $1" >&2; usage >&2; exit 1 ;;
30+
*) break ;;
31+
esac
32+
shift
33+
done
34+
35+
if [ $# -gt 0 ]; then
36+
case "$_action" in
37+
'') _action=apply ;;
38+
apply|rm) ;;
39+
*) echo "Error: files cannot be combined with --$_action" >&2; exit 1 ;;
40+
esac
41+
elif [ "$_action" = rm ]; then
42+
echo "Error: --rm needs at least one NAME" >&2; exit 1
43+
fi
44+
[ -n "$_action" ] || { usage; exit 0; }
45+
46+
if [ "$_action" = list ]; then
47+
echo "User overlays in $DROPDIR:"
48+
if ls "$DROPDIR"/*.dtbo >/dev/null 2>&1; then
49+
for f in "$DROPDIR"/*.dtbo; do echo " ${f##*/}"; done
50+
else
51+
echo " (none)"
52+
fi
53+
exit 0
54+
fi
55+
56+
. /usr/lib/flipper-bls.sh 2>/dev/null || { echo "Error: /usr/lib/flipper-bls.sh not found" >&2; exit 1; }
57+
[ "$(id -u)" -eq 0 ] || { echo "Error: must run as root (use sudo)" >&2; exit 1; }
58+
59+
case "$_action" in
60+
clear)
61+
rm -f "$DROPDIR"/*.dtbo
62+
echo "Removed all user overlays from $DROPDIR"
63+
;;
64+
rm)
65+
for f in "$@"; do
66+
_t="$DROPDIR/${f##*/}"
67+
[ -f "$_t" ] || { echo "Error: no such overlay: ${f##*/}" >&2; exit 1; }
68+
rm -f "$_t"
69+
echo "removed ${f##*/}"
70+
done
71+
;;
72+
apply)
73+
install -d -m 755 "$DROPDIR"
74+
btrfs property set "$DROPDIR" compression none 2>/dev/null || :
75+
for f in "$@"; do
76+
[ -f "$f" ] || { echo "Error: no such file: $f" >&2; exit 1; }
77+
case "$f" in *.dtbo) ;; *) echo "Error: not a .dtbo: $f" >&2; exit 1 ;; esac
78+
cp -f --reflink=never "$f" "$DROPDIR/"
79+
echo "copied ${f##*/} -> $DROPDIR/"
80+
done
81+
;;
82+
esac
83+
84+
flipper_rewrite_overlay "$_scope"
85+
echo "Reboot to load changes."

0 commit comments

Comments
 (0)