1
0
mirror of https://github.com/systemd/systemd.git synced 2025-01-11 09:18:07 +03:00

Merge pull request #29523 from keszybz/kernel-install-dtb-files

Do not look for dtb files in /boot, add support in 60-ukify.install
This commit is contained in:
Lennart Poettering 2023-10-12 10:43:24 +02:00 committed by GitHub
commit 9ff6876555
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 180 additions and 111 deletions

View File

@ -471,64 +471,81 @@
<title>Files</title> <title>Files</title>
<variablelist> <variablelist>
<varlistentry> <varlistentry>
<term> <term><filename>/etc/kernel/install.d/*.install</filename></term>
<filename>/usr/lib/kernel/install.d/*.install</filename> <term><filename>/usr/lib/kernel/install.d/*.install</filename></term>
<filename>/etc/kernel/install.d/*.install</filename> <listitem>
</term> <para>Drop-in files which are executed by <command>kernel-install</command>.</para>
<listitem>
<para>Drop-in files which are executed by kernel-install.</para>
<xi:include href="version-info.xml" xpointer="v198"/> <xi:include href="version-info.xml" xpointer="v198"/>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term><filename>/etc/kernel/cmdline</filename></term>
<filename>/usr/lib/kernel/cmdline</filename> <term><filename>/usr/lib/kernel/cmdline</filename></term>
<filename>/etc/kernel/cmdline</filename> <term><filename>/proc/cmdline</filename></term>
<filename>/proc/cmdline</filename> <listitem>
</term> <para>Specifies the kernel command line to use. The first of the files that is found will be used.
<listitem> <varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the search path; see below for
<para>Read by <filename>90-loaderentry.install</filename>. The content of the file details.</para>
<filename>/etc/kernel/cmdline</filename> specifies the kernel command line to use. If that file
does not exist, <filename>/usr/lib/kernel/cmdline</filename> is used. If that also does not
exist, <filename>/proc/cmdline</filename> is used. <varname>$KERNEL_INSTALL_CONF_ROOT</varname>
may be used to override the path.</para>
<xi:include href="version-info.xml" xpointer="v198"/> <xi:include href="version-info.xml" xpointer="v198"/>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term><filename>/etc/kernel/devicetree</filename></term>
<filename>/etc/kernel/tries</filename> <term><filename>/usr/lib/kernel/devicetree</filename></term>
</term> <listitem>
<listitem> <para>Specifies the partial path to the file containing the device tree blob to install with the
<para>Read by <filename>90-loaderentry.install</filename> and kernel and use at boot. The first of the files that is found will be used.
<filename>90-uki-copy.install</filename>. If this file exists a numeric value is read from it <varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the search path; see below for
and the naming of the generated entry file or UKI is slightly altered to include it as details.</para>
<filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>+<replaceable>TRIES</replaceable>.conf</filename>
or <para>The <filename>devicetree</filename> file contains a path, and this path specifies a location
<filename>$BOOT/EFI/Linux/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>+<replaceable>TRIES</replaceable>.efi</filename>, respectively. This relative to the kernel install tree. A set of locations is checked, including in particular
is useful for boot loaders such as <filename>/usr/lib/modules/<replaceable>KERNEL_VERSION</replaceable>/dtb/</filename>, which is the
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry> recommended location to place the dtb files under. For example, with
which implement boot attempt counting with a counter embedded in the entry file name. <literal>broadcom/bcm2711-rpi-4-b.dtb</literal> in the <filename>devicetree</filename> file, the
<varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the path.</para> device tree blob for the Raspberry Pi 4 Model B would be installed, and the actual file would be
<filename index='false'>/usr/lib/modules/<replaceable>KERNEL_VERSION</replaceable>/dtb/broadcom/bcm2711-rpi-4-b.dtb</filename>.
</para>
<xi:include href="version-info.xml" xpointer="v255"/>
</listitem>
</varlistentry>
<varlistentry>
<term><filename>/etc/kernel/tries</filename></term>
<listitem>
<para>Read by <filename>90-loaderentry.install</filename> and
<filename>90-uki-copy.install</filename>. If this file exists, a numeric value is read from it and
the naming of the generated entry file or UKI is altered to include it as
<filename>$BOOT/loader/entries/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>+<replaceable>TRIES</replaceable>.conf</filename>
or
<filename>$BOOT/EFI/Linux/<replaceable>ENTRY-TOKEN</replaceable>-<replaceable>KERNEL-VERSION</replaceable>+<replaceable>TRIES</replaceable>.efi</filename>,
respectively. This is useful for boot loaders such as
<citerefentry><refentrytitle>systemd-boot</refentrytitle><manvolnum>7</manvolnum></citerefentry>
which implement boot attempt counting with a counter embedded in the entry file name.
<varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the search path; see below for
details.</para>
<xi:include href="version-info.xml" xpointer="v240"/> <xi:include href="version-info.xml" xpointer="v240"/>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term>
<filename>/etc/kernel/entry-token</filename>
</term>
<listitem>
<para>If this file exists it is read and used as "entry token" for this system, i.e. is used for
naming Boot Loader Specification entries, see <varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname>
above for details. <varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the
path.</para>
<xi:include href="version-info.xml" xpointer="v251"/> <varlistentry>
</listitem> <term><filename>/etc/kernel/entry-token</filename></term>
<listitem>
<para>If this file exists it is read and used as "entry token" for this system, i.e. is used for
naming Boot Loader Specification entries. See <varname>$KERNEL_INSTALL_ENTRY_TOKEN</varname> above
for details. <varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the search path; see
below for details.</para>
<xi:include href="version-info.xml" xpointer="v251"/>
</listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term>
<filename>/etc/machine-id</filename> <filename>/etc/machine-id</filename>
@ -540,63 +557,62 @@
<xi:include href="version-info.xml" xpointer="v198"/> <xi:include href="version-info.xml" xpointer="v198"/>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term><filename>/etc/os-release</filename></term>
<filename>/etc/os-release</filename> <term><filename>/usr/lib/os-release</filename></term>
<filename>/usr/lib/os-release</filename>
</term>
<listitem> <listitem>
<para>Read by <filename>90-loaderentry.install</filename>. <para>Read by <filename>90-loaderentry.install</filename>. If available,
If available, <varname>PRETTY_NAME=</varname> is read from these files and used as the title of the boot menu entry. <varname>PRETTY_NAME=</varname> is read from these files and used as the title of the boot menu
Otherwise, <literal>Linux <replaceable>KERNEL-VERSION</replaceable></literal> will be used.</para> entry. Otherwise, <literal>Linux <replaceable>KERNEL-VERSION</replaceable></literal> will be
used.</para>
<xi:include href="version-info.xml" xpointer="v198"/> <xi:include href="version-info.xml" xpointer="v198"/>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term><filename>/etc/kernel/install.conf</filename></term>
<filename>/usr/lib/kernel/install.conf</filename> <term><filename>/usr/lib/kernel/install.conf</filename></term>
<filename>/etc/kernel/install.conf</filename> <listitem>
</term> <para>Configuration file with options for <command>kernel-install</command>, as a series of
<listitem> <varname>KEY=</varname><replaceable>VALUE</replaceable> assignments, compatible with shell syntax,
<para>Configuration options for <command>kernel-install</command>, as a series of following the same rules as described in
<varname>KEY=</varname><replaceable>VALUE</replaceable> assignments, compatible with shell <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>. The
syntax, following the same rules as described in first of the files that is found will be used. <varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be
<citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry>. used to override the search path; see below for details.</para>
<filename>/etc/kernel/install.conf</filename> will be read if present, and
<filename>/usr/lib/kernel/install.conf</filename> otherwise. This file is optional.
<varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the path.
</para>
<para>Currently, the following keys are supported: <para>Currently, the following keys are supported:
<varname>MACHINE_ID=</varname>, <varname>MACHINE_ID=</varname>,
<varname>BOOT_ROOT=</varname>, <varname>BOOT_ROOT=</varname>,
<varname>layout=</varname>, <varname>layout=</varname>,
<varname>initrd_generator=</varname>, <varname>initrd_generator=</varname>,
<varname>uki_generator=</varname>. <varname>uki_generator=</varname>.
See the Environment variables section above for details.</para> See the Environment variables section above for details.</para>
<xi:include href="version-info.xml" xpointer="v250"/> <xi:include href="version-info.xml" xpointer="v250"/>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term> <term><filename>/etc/kernel/uki.conf</filename></term>
<filename>/etc/kernel/uki.conf</filename> <listitem>
</term> <para>Ini-style configuration file for
<listitem> <citerefentry><refentrytitle>ukify</refentrytitle><manvolnum>1</manvolnum></citerefentry> which is
<para>Ini-style configuration file for only effective when <varname>$KERNEL_INSTALL_LAYOUT</varname> or <varname>layout=</varname> in
<citerefentry><refentrytitle>ukify</refentrytitle><manvolnum>1</manvolnum></citerefentry> which <filename>install.conf</filename> is set to <option>uki</option> and
is only effective when <varname>$KERNEL_INSTALL_LAYOUT</varname> or <varname>layout=</varname> in <varname>$KERNEL_INSTALL_UKI_GENERATOR</varname> or <varname>uki_generator=</varname> in
<filename>install.conf</filename> is set to <option>uki</option> and <filename>install.conf</filename> is set to <option>ukify</option>.
<varname>$KERNEL_INSTALL_UKI_GENERATOR</varname> or <varname>uki_generator=</varname> in <varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the search path; see below for
<filename>install.conf</filename> is set to <option>ukify</option>. details.</para>
<varname>$KERNEL_INSTALL_CONF_ROOT</varname> may be used to override the path.
</para>
<xi:include href="version-info.xml" xpointer="v255"/> <xi:include href="version-info.xml" xpointer="v255"/>
</listitem> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>
<para>For various cases listed above, if the <varname>$KERNEL_INSTALL_CONF_ROOT</varname> environment
variable is set, it will override the search path. The files will be loaded <emphasis>only</emphasis>
from the directory specified by the environment variable. When the variable is not set, the listed paths
are tried in turn, and the first file that exists is used.</para>
</refsect1> </refsect1>
<refsect1> <refsect1>

View File

@ -124,27 +124,60 @@ def we_are_wanted() -> bool:
return True return True
def config_file_location() -> Optional[Path]: def input_file_location(
filename: str,
*search_directories: str) -> Optional[Path]:
if root := os.getenv('KERNEL_INSTALL_CONF_ROOT'): if root := os.getenv('KERNEL_INSTALL_CONF_ROOT'):
p = Path(root) / 'uki.conf' search_directories = (root,)
else: elif not search_directories:
p = Path('/etc/kernel/uki.conf') # This is the default search path.
if p.exists(): search_directories = ('/etc/kernel',
return p '/usr/lib/kernel')
for dir in search_directories:
p = Path(dir) / filename
if p.exists():
return p
return None return None
def uki_conf_location() -> Optional[Path]:
return input_file_location('uki.conf',
'/etc/kernel')
def devicetree_config_location() -> Optional[Path]:
return input_file_location('devicetree')
def devicetree_file_location(opts) -> Optional[Path]:
# This mirrors the logic in 90-loaderentry.install. Keep in sync.
configfile = devicetree_config_location()
if configfile is None:
return None
devicetree = configfile.read_text().strip()
if not devicetree:
raise ValueError(f'{configfile!r} is empty')
path = input_file_location(
devicetree,
f'/usr/lib/firmware/{opts.kernel_version}/device-tree',
f'/usr/lib/linux-image-{opts.kernel_version}',
f'/usr/lib/modules/{opts.kernel_version}/dtb',
)
if path is None:
raise FileNotFoundError(f'DeviceTree file {devicetree} not found')
return path
def kernel_cmdline_base() -> list[str]: def kernel_cmdline_base() -> list[str]:
if root := os.getenv('KERNEL_INSTALL_CONF_ROOT'): path = input_file_location('cmdline')
return Path(root).joinpath('cmdline').read_text().split() if path:
return path.read_text().split()
for cmdline in ('/etc/kernel/cmdline',
'/usr/lib/kernel/cmdline'):
try:
return Path(cmdline).read_text().split()
except FileNotFoundError:
continue
# If we read /proc/cmdline, we need to do some additional filtering.
options = Path('/proc/cmdline').read_text().split() options = Path('/proc/cmdline').read_text().split()
return [opt for opt in options return [opt for opt in options
if not opt.startswith(('BOOT_IMAGE=', 'initrd='))] if not opt.startswith(('BOOT_IMAGE=', 'initrd='))]
@ -193,13 +226,16 @@ def call_ukify(opts):
# argument set to prepopulate the namespace with the defaults. # argument set to prepopulate the namespace with the defaults.
opts2 = ukify['create_parser']().parse_args(['build']) opts2 = ukify['create_parser']().parse_args(['build'])
opts2.config = config_file_location() opts2.config = uki_conf_location()
opts2.uname = opts.kernel_version opts2.uname = opts.kernel_version
opts2.linux = opts.kernel_image opts2.linux = opts.kernel_image
opts2.initrd = initrd_list(opts) opts2.initrd = initrd_list(opts)
# Note that 'uki.efi' is the name required by 90-uki-copy.install. # Note that 'uki.efi' is the name required by 90-uki-copy.install.
opts2.output = opts.staging_area / 'uki.efi' opts2.output = opts.staging_area / 'uki.efi'
if devicetree := devicetree_file_location(opts):
opts2.devicetree = devicetree
opts2.cmdline = kernel_cmdline(opts) opts2.cmdline = kernel_cmdline(opts)
if BOOT_STUB: if BOOT_STUB:
opts2.stub = BOOT_STUB opts2.stub = BOOT_STUB

View File

@ -126,12 +126,12 @@ elif [ -f /usr/lib/kernel/devicetree ]; then
fi fi
if [ -n "$DEVICETREE" ]; then if [ -n "$DEVICETREE" ]; then
for prefix in \ for prefix in \
"/boot/dtb-$KERNEL_VERSION" \ "$KERNEL_INSTALL_CONF_ROOT" \
"/boot/dtbs/$KERNEL_VERSION" \ "/usr/lib/firmware/$KERNEL_VERSION/device-tree" \
"/lib/firmware/$KERNEL_VERSION/device-tree" \ "/usr/lib/linux-image-$KERNEL_VERSION" \
"/lib/linux-image-$KERNEL_VERSION" \ "/usr/lib/modules/$KERNEL_VERSION/dtb"
"/lib/modules/$KERNEL_VERSION/dtb"
do do
[ -n "$prefix" ] || continue
[ -f "$prefix/$DEVICETREE" ] || continue [ -f "$prefix/$DEVICETREE" ] || continue
DEVICETREE_SRC="$prefix/$DEVICETREE" DEVICETREE_SRC="$prefix/$DEVICETREE"
break break

View File

@ -39,6 +39,11 @@ BOOT_ROOT="$D/badboot"
MACHINE_ID=badbadbadbadbadbad6abadbadbadbad MACHINE_ID=badbadbadbadbadbad6abadbadbadbad
EOF EOF
# Create a 'devicetree' config file that points to a fake dtb file
echo 'subdir/whatever.dtb' >"$D/sources/devicetree"
mkdir "$D/sources/subdir"
echo 'DTBDTBDTBDTB' >"$D/sources/subdir/whatever.dtb"
export KERNEL_INSTALL_CONF_ROOT="$D/sources" export KERNEL_INSTALL_CONF_ROOT="$D/sources"
# We "install" multiple plugins, but control which ones will be active via install.conf. # We "install" multiple plugins, but control which ones will be active via install.conf.
export KERNEL_INSTALL_PLUGINS="${ukify_install} ${loaderentry_install} ${uki_copy_install}" export KERNEL_INSTALL_PLUGINS="${ukify_install} ${loaderentry_install} ${uki_copy_install}"
@ -60,9 +65,11 @@ grep -qE '^version +1.1.1' "$entry"
grep -qE '^options +opt1 opt2' "$entry" grep -qE '^options +opt1 opt2' "$entry"
grep -qE '^linux .*/the-token/1.1.1/linux' "$entry" grep -qE '^linux .*/the-token/1.1.1/linux' "$entry"
grep -qE '^initrd .*/the-token/1.1.1/initrd' "$entry" grep -qE '^initrd .*/the-token/1.1.1/initrd' "$entry"
grep -qE '^devicetree .*/the-token/1.1.1/whatever.dtb' "$entry"
grep -qE 'image' "$BOOT_ROOT/the-token/1.1.1/linux" grep -qE 'image' "$BOOT_ROOT/the-token/1.1.1/linux"
grep -qE 'initrd' "$BOOT_ROOT/the-token/1.1.1/initrd" grep -qE 'initrd' "$BOOT_ROOT/the-token/1.1.1/initrd"
grep -qE 'DTBDTB' "$BOOT_ROOT/the-token/1.1.1/whatever.dtb"
"$kernel_install" inspect "$kernel_install" inspect
"$kernel_install" inspect "$D/sources/linux" "$kernel_install" inspect "$D/sources/linux"
@ -95,9 +102,11 @@ grep -qE '^version +1.1.2' "$entry"
grep -qE '^options +opt1 opt2' "$entry" grep -qE '^options +opt1 opt2' "$entry"
grep -qE '^linux .*/the-token/1.1.2/linux' "$entry" grep -qE '^linux .*/the-token/1.1.2/linux' "$entry"
( ! grep -qE '^initrd' "$entry" ) ( ! grep -qE '^initrd' "$entry" )
grep -qE '^devicetree .*/the-token/1.1.2/whatever.dtb' "$entry"
grep -qE 'image' "$BOOT_ROOT/the-token/1.1.2/linux" grep -qE 'image' "$BOOT_ROOT/the-token/1.1.2/linux"
test ! -e "$BOOT_ROOT/the-token/1.1.2/initrd" test ! -e "$BOOT_ROOT/the-token/1.1.2/initrd"
grep -qE 'DTBDTB' "$BOOT_ROOT/the-token/1.1.2/whatever.dtb"
# Check installation with boot counting # Check installation with boot counting
echo '56' >"$D/sources/tries" echo '56' >"$D/sources/tries"
@ -120,6 +129,7 @@ if [ -f "$ukify" ]; then
layout=uki layout=uki
uki_generator=ukify uki_generator=ukify
EOF EOF
"$kernel_install" -v add 1.1.3 "$D/sources/linux" "$D/sources/initrd" "$kernel_install" -v add 1.1.3 "$D/sources/linux" "$D/sources/initrd"
uki="${BOOT_ROOT}/EFI/Linux/the-token-1.1.3+56.efi" uki="${BOOT_ROOT}/EFI/Linux/the-token-1.1.3+56.efi"
test -f "$uki" test -f "$uki"
@ -129,6 +139,13 @@ EOF
"$bootctl" kernel-inspect "$uki" | grep -qE 'Version: +1\.1\.3$' "$bootctl" kernel-inspect "$uki" | grep -qE 'Version: +1\.1\.3$'
"$bootctl" kernel-inspect "$uki" | grep -qE 'Cmdline: +opt1 opt2$' "$bootctl" kernel-inspect "$uki" | grep -qE 'Cmdline: +opt1 opt2$'
fi fi
"$ukify" inspect "$uki" | grep -qE '^.sbat'
"$ukify" inspect "$uki" | grep -qE '^.cmdline'
"$ukify" inspect "$uki" | grep -qE '^.uname'
"$ukify" inspect "$uki" | grep -qE '^.initrd'
"$ukify" inspect "$uki" | grep -qE '^.linux'
"$ukify" inspect "$uki" | grep -qE '^.dtb'
fi fi
# Test bootctl # Test bootctl

View File

@ -250,7 +250,7 @@ DEFAULT_SECTIONS_TO_SHOW = {
'.linux' : 'binary', '.linux' : 'binary',
'.initrd' : 'binary', '.initrd' : 'binary',
'.splash' : 'binary', '.splash' : 'binary',
'.dt' : 'binary', '.dtb' : 'binary',
'.cmdline' : 'text', '.cmdline' : 'text',
'.osrel' : 'text', '.osrel' : 'text',
'.uname' : 'text', '.uname' : 'text',