diff mbox series

[SRU,kernel-snaps-uc20,1/1] Remove unnecessary firmware binaries

Message ID 20220113151456.607468-2-juergh@canonical.com
State New
Headers show
Series Ucore kernel snap size: netronome smartnic fw (LP: #1951422) | expand

Commit Message

Juerg Haefliger Jan. 13, 2022, 3:14 p.m. UTC
BugLink: https://bugs.launchpad.net/bugs/1951422
BugLink: https://bugs.launchpad.net/bugs/1951423

linux-firmware provides a lot of binaries that are not needed/required and
just blow up the size of the kernel snap. In order to reduce the snap size,
remove all firmware binaries that are not referenced by the kernel. But
only if TRIM_FIRMWARE is set to 'true'.

Note that older kernels don't reference brcm firmware config files so
copy the whole directory content to be on the safe side.

Signed-off-by: Juerg Haefliger <juergh@canonical.com>
---
 Makefile      |  4 ++++
 trim-firmware | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)
 create mode 100755 trim-firmware
diff mbox series

Patch

diff --git a/Makefile b/Makefile
index fdf18dd7738e..9795ca558678 100644
--- a/Makefile
+++ b/Makefile
@@ -105,3 +105,7 @@  install: install-image
 	# create all links
 	cd $(DESTDIR)/lib; ln -s ../firmware .
 	cd $(DESTDIR)/lib; ln -s ../modules .
+	# Remove unnecessary firmwares
+	if [ "$(TRIM_FIRMWARE)" = "true" ]; then \
+	  ./trim-firmware "$(DESTDIR)"; \
+	fi
diff --git a/trim-firmware b/trim-firmware
new file mode 100755
index 000000000000..19c4b82a36af
--- /dev/null
+++ b/trim-firmware
@@ -0,0 +1,56 @@ 
+#!/bin/bash -eu
+#
+# Remove unnecessary firmware files
+#
+
+function list_firmware()
+{
+	local modules_dir=${1}
+	local module modinfo
+
+	# List module firmware files
+	while IFS= read -r module ; do
+		/sbin/modinfo "${module}" | sed -n 's/^firmware:\s*//p'
+	done < <(find "${modules_dir}" -name '*.ko')
+
+	# List built-in module firmware files
+	while IFS= read -r modinfo ; do
+		tr '\0' '\n' < "${modinfo}" | sed -n 's/^.*\.firmware=//p'
+	done < <(find "${modules_dir}" -name modules.builtin.modinfo)
+}
+
+DESTDIR=${1}
+
+# Copy required firmware files to a new directory
+while IFS= read -r fw_file ; do
+	for src_file in "${DESTDIR}"/firmware/${fw_file} ; do
+		if ! [ -e "${src_file}" ] ; then
+			continue  # Skip non-existing source files
+		fi
+
+		src_dir=${src_file%/*}
+		dst_dir=${DESTDIR}/firmware.new/${src_dir#${DESTDIR}/firmware}
+
+		mkdir -p "${dst_dir}"
+		# Note: We dereference symlinks which might result in duplicate
+		# binaries but that's much easier than following the symlinks
+		cp "${src_file}" "${dst_dir}"
+	done
+done < <(list_firmware "${DESTDIR}"/modules | sort -u)
+
+# Copy all brcm files, since there might be config files that the kernel
+# doesn't expose via modinfo
+if [ -d "${DESTDIR}"/firmware.new/brcm ] ; then
+	cp "${DESTDIR}"/firmware/brcm/* "${DESTDIR}"/firmware.new/brcm
+fi
+
+# Move kernel firmware files to the new firmware directory
+for d in "${DESTDIR}"/modules/* ; do
+	if [ -d "${DESTDIR}"/firmware/"${d##*/}" ] ; then
+		mv "${DESTDIR}"/firmware/"${d##*/}" "${DESTDIR}"/firmware.new
+	fi
+done
+
+# Switch to the new firmware directory
+rm -rf "${DESTDIR}"/firmware
+mv "${DESTDIR}"/firmware.new "${DESTDIR}"/firmware