Skip to content

Commit 90e94fc

Browse files
committed
Fix BLS devicetreedir path resolution for btrfs subvolumes
Derive the devicetreedir/overlay prefix from each entry's root subvolume so U-Boot resolves the in-entry paths correctly, with FDT_SUBVOL_PREFIX as an override.
1 parent f940797 commit 90e94fc

1 file changed

Lines changed: 26 additions & 17 deletions

File tree

overlays/configs/kernel/install.d/90-loaderentry.install

Lines changed: 26 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,18 @@ TITLE_MAX="${FLIPPER_TITLE_MAX:-26}"
3535
DTB_DIR="/usr/lib/linux-image-$KERNEL_VERSION"
3636
DTB_DIRS="$DTB_DIR /usr/lib/modules/$KERNEL_VERSION/dtb"
3737

38-
# Those DTB/overlay dirs live in the root (@) subvolume, but U-Boot reads the
39-
# top-level subvolume, where @ appears as /@. Prefix the in-entry devicetreedir /
40-
# devicetree-overlay paths (which reference /usr in place) so U-Boot can reach them.
41-
# Staged artifacts (kernel/initrd/single devicetree) go under /boot and are NOT
42-
# prefixed. Set FDT_SUBVOL_PREFIX="" when the root filesystem is not a subvolume.
43-
FDT_SUBVOL_PREFIX="${FDT_SUBVOL_PREFIX-/@}"
38+
# U-Boot reads the btrfs TOP LEVEL (subvolid 5), so in-entry devicetreedir/overlay paths must
39+
# be prefixed with the root subvolume the entry boots -- /@<subvol>/usr/lib/... -- where that
40+
# root's DTBs live (the kernel package installs them in every root's /usr/lib). The prefix is
41+
# derived per entry from its own rootflags=subvol= (each profile boots a different root). The
42+
# staged kernel/initrd live under /boot (the boot subvolume) and are never prefixed.
43+
# Set FDT_SUBVOL_PREFIX to override the derivation (e.g. "" if the root is not a subvolume).
44+
fdt_prefix() { # $1 = options string -> "/<rootflags-subvol>" (or $FDT_SUBVOL_PREFIX if set)
45+
if [ "${FDT_SUBVOL_PREFIX+x}" = x ]; then printf '%s' "$FDT_SUBVOL_PREFIX"; return 0; fi
46+
_sv=$(printf '%s' "$1" | tr ' ' '\n' | sed -n 's/^rootflags=subvol=//p' | tail -n1)
47+
[ -n "$_sv" ] && printf '/%s' "$_sv"
48+
return 0
49+
}
4450

4551
log() { [ "${KERNEL_INSTALL_VERBOSE:-0}" -gt 0 ] && echo "flipper-bls: $*" >&2; return 0; }
4652
die() { echo "flipper-bls: $*" >&2; exit 1; }
@@ -141,7 +147,7 @@ fi
141147
# devicetreedir (U-Boot fdtdir extension) — referenced in place, opt-in via a
142148
# /etc/kernel/devicetreedir file containing a true boolean. Only when no single
143149
# devicetree was configured.
144-
DEVICETREEDIR_SRC=""; DEVICETREEDIR_ENTRY=""
150+
DEVICETREEDIR_SRC=""; DEVICETREEDIR_REL=""
145151
if [ -z "$DEVICETREE" ] && [ -f "$CONF_ROOT/devicetreedir" ]; then
146152
_v=""; read -r _v <"$CONF_ROOT/devicetreedir" || :
147153
case "$_v" in
@@ -154,7 +160,7 @@ if [ -z "$DEVICETREE" ] && [ -f "$CONF_ROOT/devicetreedir" ]; then
154160
[ -n "$DEVICETREEDIR_SRC" ] && break
155161
done
156162
[ -n "$DEVICETREEDIR_SRC" ] || die "no device-tree directory for $KERNEL_VERSION"
157-
DEVICETREEDIR_ENTRY="$FDT_SUBVOL_PREFIX$(boot_rel "$DEVICETREEDIR_SRC")"
163+
DEVICETREEDIR_REL="$(boot_rel "$DEVICETREEDIR_SRC")" # /usr/lib/...; prefixed per entry
158164
;;
159165
esac
160166
fi
@@ -191,6 +197,8 @@ done
191197
# write_entry FILE TITLE OPTIONS FDTOVERLAYS
192198
write_entry() {
193199
_f="$1"; _title="$2"; _opts="$3"; _fdtov="$4"
200+
# devicetreedir is prefixed with THIS entry's root subvol (U-Boot reads subvolid 5)
201+
_dtdir=""; [ -n "$DEVICETREEDIR_REL" ] && _dtdir="$(fdt_prefix "$_opts")$DEVICETREEDIR_REL"
194202
{
195203
echo "# Boot Loader Specification type#1 entry (Flipper One)"
196204
echo "title $_title"
@@ -199,21 +207,22 @@ write_entry() {
199207
[ -n "$SORT_KEY" ] && echo "sort-key $SORT_KEY"
200208
[ -n "$_opts" ] && echo "options $_opts"
201209
echo "linux $KERNEL_ENTRY"
202-
[ -n "$DEVICETREE_ENTRY" ] && echo "devicetree $DEVICETREE_ENTRY"
203-
[ -n "$DEVICETREEDIR_ENTRY" ] && echo "devicetreedir $DEVICETREEDIR_ENTRY"
204-
[ -n "$_fdtov" ] && echo "devicetree-overlay $_fdtov"
210+
[ -n "$DEVICETREE_ENTRY" ] && echo "devicetree $DEVICETREE_ENTRY"
211+
[ -n "$_dtdir" ] && echo "devicetreedir $_dtdir"
212+
[ -n "$_fdtov" ] && echo "devicetree-overlay $_fdtov"
205213
for _i in $INITRD_ENTRIES; do echo "initrd $_i"; done
206214
} >"$_f"
207215
return 0 # don't let a trailing empty conditional's status abort `set -e`
208216
}
209217

210218
# Echo the space-separated paths of the named DT overlays (flat, next to the DTBs).
211219
# Returns non-zero with no output if any one is missing.
212-
overlay_paths() {
220+
overlay_paths() { # $1 = subvol prefix (e.g. /@Desktop); remaining args = overlay names
221+
_pfx="$1"; shift
213222
_paths=""
214223
for _n in "$@"; do
215224
[ -f "$OVERLAY_DIR/$_n.dtbo" ] || return 1 # check the real on-disk path
216-
_paths="$_paths${_paths:+ }$FDT_SUBVOL_PREFIX$OVERLAY_DIR/$_n.dtbo"
225+
_paths="$_paths${_paths:+ }$_pfx$OVERLAY_DIR/$_n.dtbo"
217226
done
218227
printf '%s' "$_paths"
219228
}
@@ -236,10 +245,10 @@ make_title() {
236245
fi
237246
}
238247

239-
# Base entry == the [DEFAULT] profile.
240-
write_entry "$ENTRY_STEM.conf" "$(make_title '[DEFAULT]')" "$BASE_OPTS" ""
248+
# Base entry == the [DESKTOP] profile.
249+
write_entry "$ENTRY_STEM.conf" "$(make_title '[DESKTOP]')" "$BASE_OPTS" ""
241250

242-
[ -f "$PROFILES" ] || { log "$PROFILES not found, only the [DEFAULT] entry written"; exit 0; }
251+
[ -f "$PROFILES" ] || { log "$PROFILES not found, only the [DESKTOP] entry written"; exit 0; }
243252

244253
while IFS='|' read -r tok suf extra gate dtbos legend; do
245254
tok="$(echo "$tok" | tr -d '[:space:]')"
@@ -268,7 +277,7 @@ while IFS='|' read -r tok suf extra gate dtbos legend; do
268277
required=0
269278
case "$dtbos" in '!'*) required=1; dtbos="$(trim "${dtbos#\!}")" ;; esac
270279

271-
paths="$(overlay_paths $dtbos)" || paths=""
280+
paths="$(overlay_paths "$(fdt_prefix "$opts")" $dtbos)" || paths=""
272281
if [ -z "$paths" ] && [ "$required" = 1 ]; then
273282
log "skip $tok (overlays not found for $KERNEL_VERSION)"
274283
continue

0 commit comments

Comments
 (0)