mirror of
https://github.com/linuxboot/heads.git
synced 2024-12-24 15:16:42 +00:00
Blob jail: Make device firmware available during initrd
Some device firmware, such as the graphics microcontroller, is needed during the initrd - i915 is often loaded in the initrd, and this is the only chance to load GuC firmware. Device firmware must still be available after the real root is mounted too, so update the custom firmware path in the kernel when the firmware is moved to /run. Signed-off-by: Jonathon Hall <jonathon.hall@puri.sm>
This commit is contained in:
parent
439aba5f05
commit
af5eb2edf9
@ -55,26 +55,36 @@ if ! grep -E -q '^exec run-init .*\$\{rootmnt\}' "$INITRD_ROOT/init"; then
|
|||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# The initrd's /init has to copy the firmware to /run/firmware, so it will be
|
# In general, firmware files must be available _both_ during the initrd _and_
|
||||||
# present when the real root is moved to /.
|
# once root is moved to /. Firmware loading may happen in either phase (e.g.
|
||||||
# * Wi-Fi/BT firmware loading doesn't happen during the initrd - these modules
|
# i915 GUC firmware is usually loaded in the initrd because i915 is used there,
|
||||||
# aren't in the initrd anyway, typically.
|
# but Wi-Fi/BT modules typically are not in the initrd, they're loaded later).
|
||||||
# * /run is a tmpfs mount, so this works even if the root filesystem is
|
|
||||||
# read-only, and it doesn't persist anything.
|
|
||||||
#
|
#
|
||||||
# kexec-boot will add a kernel parameter for the kernel to look for firmware in
|
# We want to place the firmware after boot in /run, since this is a tmpfs mount
|
||||||
# /run/firmware.
|
# - it works even if the root filesystem is read-only and does not persist
|
||||||
|
# anything. But we cannot place it there for the initrd, since the initrd also
|
||||||
|
# mounts a tmpfs on /run. We can only specify one custom firmware path, but we
|
||||||
|
# can change it at runtime.
|
||||||
|
#
|
||||||
|
# So during the initrd, the firmware is in /firmware, and we provide that path
|
||||||
|
# on the kernel command line. Just before invoking the real init (after root is
|
||||||
|
# mounted), we copy it to /run/firmware and also change the firmware path.
|
||||||
#
|
#
|
||||||
# Debian's init script ends with an "exec run-init ..." (followed by a few lines
|
# Debian's init script ends with an "exec run-init ..." (followed by a few lines
|
||||||
# to print a message in case it fails). At that point, root is mounted, and
|
# to print a message in case it fails). At that point, root is mounted, and
|
||||||
# run-init will move it to / and then exec init. We can copy the firmware just
|
# run-init will move it to / and then exec init. We can insert the firmware
|
||||||
# before that, so we don't have to know anything about how root was mounted.
|
# actions just before that, so we don't have to know anything about how root was
|
||||||
|
# mounted.
|
||||||
#
|
#
|
||||||
# The root path is in ${rootmnt}, which should appear in the run-init command.
|
# The root path is in ${rootmnt}, which should appear in the run-init command.
|
||||||
# If it doesn't, then we don't understand the init script.
|
# If it doesn't, then we don't understand the init script.
|
||||||
AWK_INSERT_CP='
|
AWK_INSERT_CP='
|
||||||
BEGIN{inserted=0}
|
BEGIN{inserted=0}
|
||||||
/^exec run-init .*\$\{rootmnt\}/ && inserted==0 {print "cp -r /firmware ${rootmnt}/run/firmware"; inserted=1}
|
/^exec run-init .*\$\{rootmnt\}/ && inserted==0 {
|
||||||
|
print "cp -r /firmware ${rootmnt}/run/firmware"
|
||||||
|
print "echo -n /run/firmware >${rootmnt}/sys/module/firmware_class/parameters/path"
|
||||||
|
inserted=1
|
||||||
|
}
|
||||||
{print $0}'
|
{print $0}'
|
||||||
|
|
||||||
awk -e "$AWK_INSERT_CP" "$INITRD_ROOT/init" >"$INITRD_ROOT/init_fw"
|
awk -e "$AWK_INSERT_CP" "$INITRD_ROOT/init" >"$INITRD_ROOT/init_fw"
|
||||||
|
@ -35,7 +35,7 @@ cmdadd="$CONFIG_BOOT_KERNEL_ADD $cmdadd"
|
|||||||
cmdremove="$CONFIG_BOOT_KERNEL_REMOVE $cmdremove"
|
cmdremove="$CONFIG_BOOT_KERNEL_REMOVE $cmdremove"
|
||||||
|
|
||||||
if [ "$(load_config_value CONFIG_USE_BLOB_JAIL)" = "y" ]; then
|
if [ "$(load_config_value CONFIG_USE_BLOB_JAIL)" = "y" ]; then
|
||||||
cmdadd="$cmdadd firmware_class.path=/run/firmware/"
|
cmdadd="$cmdadd firmware_class.path=/firmware/"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fix_file_path() {
|
fix_file_path() {
|
||||||
|
Loading…
Reference in New Issue
Block a user