From b7ec3331b41a0ec98bd12b7bfdfe1e811578212c Mon Sep 17 00:00:00 2001 From: dann frazier Date: Thu, 27 Jan 2022 08:45:53 -0700 Subject: [PATCH] Introduce "Boot-Kernel-Max-Size" and support for compressing kernel images exceeed it. This will allow installation of larger uncompressed kernels on HP ProLiant m400 cartridges. LP: #1954692 --- db/all.db | 4 +++ debian/changelog | 8 +++++ functions | 43 +++++++++++++++++++++- test_db | 2 +- test_functions | 92 +++++++++++++++++++++++++++++++++++++++++++++++- 5 files changed, 146 insertions(+), 3 deletions(-) diff --git a/db/all.db b/db/all.db index aea19db..6abae33 100644 --- a/db/all.db +++ b/db/all.db @@ -643,6 +643,10 @@ U-Boot-Script-Address: 0x4004000000 U-Boot-Script-Name: bootscr.xgene Required-Packages: u-boot-tools Boot-Kernel-Path: /boot/uImage +# A kernel too large can over-run the firmware-provided dtb +# ${fdt_addr_r} - ${kern_addr_r} - uImageEnvelope = +# 0x4003000000 - 0x4002000000 - 64 +Boot-Kernel-Max-Size: 16777152 Boot-Initrd-Path: /boot/uInitrd Boot-Script-Path: /boot/boot.scr Bootloader-Has-Broken-Ext4-Extent-Support: yes diff --git a/debian/changelog b/debian/changelog index 3355ebe..96c549e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,11 @@ +flash-kernel (3.104ubuntu6) UNRELEASED; urgency=medium + + * Introduce "Boot-Kernel-Max-Size" and support for compressing kernel + images that exceed it. This will allow installation of larger + uncompressed kernels on HP ProLiant m400 cartridges. LP: #1954692 + + -- dann frazier Mon, 24 Jan 2022 17:26:13 -0700 + flash-kernel (3.104ubuntu5) impish; urgency=medium * Drop the "systemd.gpt_auto=0 rd.systemd.unit=basic.target" values from diff --git a/functions b/functions index 387442f..bb476c6 100644 --- a/functions +++ b/functions @@ -490,6 +490,39 @@ maybe_defrag() { fi } +check_kernel_size() { + local kdata="$1" + local kdatasize + local maxsize + + maxsize="$(get_machine_field "$machine" "Boot-Kernel-Max-Size")" + echo "maxsize is $maxsize" > /tmp/debug + if [ -z "$maxsize" ]; then + return 0 + fi + kdatasize=$(stat -c '%s' "$kdata") + if [ "$kdatasize" -le "$maxsize" ]; then + return 0 + fi + return 1 +} + +try_shrink_kernel() { + local kdata="$1" + local kdataz + local comptype + + comptype="$(compress_type $kdata)" + if [ "$comptype" != "none" ]; then + echo "WARNING: try_shrink_kernel: $kdata is already compressed." >&2 + echo "$kdata" + return + fi + kdataz="$(mktemp -p $tmpdir)" + gzip -9 < "$kdata" > "$kdataz" + echo "$kdataz" +} + mkimage_kernel() { local kaddr="$1" local epoint="$2" @@ -498,7 +531,15 @@ mkimage_kernel() { local uimage="$5" local comp - comp="$(compress_type $kdata)" + if ! check_kernel_size "$kdata"; then + printf "$kdata is too large for this machine, attempting to compress..." >&2 + kdata="$(try_shrink_kernel "$kdata")" + if ! check_kernel_size "$kdata"; then + error "Compressed file $kdata is too large for this machine" + fi + fi + + comp="$(compress_type "$kdata")" printf "Generating kernel u-boot image... " >&2 mkimage -A "$mkarch" -O linux -T kernel -C $comp -a "$kaddr" -e "$epoint" \ diff --git a/test_db b/test_db index 19a02ee..c5a6f06 100755 --- a/test_db +++ b/test_db @@ -22,7 +22,7 @@ MACHINE_DB="$(cat "${FK_CHECKOUT:-$FK_DIR}/db/"*.db)" test_no_unknown_fields() { - local expected='Android-Boot-Device Android-Skip-Initrd Boot-Device Boot-DTB-Path Boot-FIT-Path Boot-Initrd-Path Boot-ITS-File-Name Boot-Kernel-Path Bootloader-Has-Broken-Ext4-Extent-Support Bootloader-Sets-Incorrect-Root Bootloader-sets-root Boot-Multi-Path Boot-Script-Path DTB-Append DTB-Append-From DTB-Id Kernel-Flavors Machine Machine-Id Method Mtd-Initrd Mtd-Kernel Optional-Packages Required-Packages U-Boot-Initrd-Address U-Boot-Kernel-Address U-Boot-Kernel-Entry-Point U-Boot-Multi-Address U-Boot-Script-Address U-Boot-Script-Name' + local expected='Android-Boot-Device Android-Skip-Initrd Boot-Device Boot-DTB-Path Boot-FIT-Path Boot-Initrd-Path Boot-ITS-File-Name Boot-Kernel-Path Boot-Kernel-Max-Size Bootloader-Has-Broken-Ext4-Extent-Support Bootloader-Sets-Incorrect-Root Bootloader-sets-root Boot-Multi-Path Boot-Script-Path DTB-Append DTB-Append-From DTB-Id Kernel-Flavors Machine Machine-Id Method Mtd-Initrd Mtd-Kernel Optional-Packages Required-Packages U-Boot-Initrd-Address U-Boot-Kernel-Address U-Boot-Kernel-Entry-Point U-Boot-Multi-Address U-Boot-Script-Address U-Boot-Script-Name' expected="$(echo "$expected" | sed 's/ /\n/g' | sort -u | xargs)" local fields="$(echo "$MACHINE_DB" | sed -n '/^[^#]*:/s/:.*//p' | sort -u | xargs)" if [ "$fields" != "$expected" ]; then diff --git a/test_functions b/test_functions index 6e0b49b..cc0f05c 100755 --- a/test_functions +++ b/test_functions @@ -589,7 +589,9 @@ _test_mkimage_kernel() { } test_mkimage_kernel() { - local kdata="/dev/zero" + get_tempfile + local kdata="$last_tempfile" + echo "uncompressed" > "$kdata" local expected="-A arm -O linux -T kernel -C none -a 0xdeadbeef -e 0xbaddcafe -n desc -d $kdata output" _test_mkimage_kernel "$kdata" "$expected" } @@ -695,6 +697,94 @@ test_mkimage_multi() { } add_test test_mkimage_multi +test_check_kernel_size_no_max() { + get_tempfile + local kdata="$last_tempfile" + # Larger than the smallest Boot-Kernel-Max-Size in all.db + dd if=/dev/zero of="$kdata" seek=16777153 bs=1 count=0 status=none + ( + . "$functions" + machine="none" + if ! check_kernel_size "$kdata"; then + echo "Did not expect an error from check_kernel_size()" >&2 + exit 1 + fi + ) +} +add_test test_check_kernel_size_no_max + +test_check_kernel_size_fits() { + get_tempfile + local kdata="$last_tempfile" + # Within the machine's Boot-Kernel-Max-Size + dd if=/dev/zero of="$kdata" seek=16777152 bs=1 count=0 status=none + ( + . "$functions" + machine="HP ProLiant m400 Server Cartridge" + if ! check_kernel_size "$kdata"; then + echo "Did not expect an error from check_kernel_size()" >&2 + exit 1 + fi + ) +} +add_test test_check_kernel_size_fits + +test_check_kernel_size_too_big() { + get_tempfile + local kdata="$last_tempfile" + # Larger than the machine's Boot-Kernel-Max-Size + dd if=/dev/zero of="$kdata" seek=16777153 bs=1 count=0 status=none + ( + . "$functions" + machine="HP ProLiant m400 Server Cartridge" + if check_kernel_size "$kdata"; then + echo "Expected an error from check_kernel_size()" >&2 + exit 1 + fi + ) +} +add_test test_check_kernel_size_too_big + +test_try_shrink_kernel_should_compress() { + get_tempfile + local kdata="$last_tempfile" + echo uncompressed > "$kdata" + ( + . "$functions" + # Duplicate (some of) cleanups and tmpdir from main() + cleanups() { + rm -rf "$tmpdir" + } + trap cleanups EXIT HUP INT QUIT ILL KILL SEGV PIPE TERM + tmpdir="$(mktemp -dt "test_mkimage_script.XXXXXXXX")" + new_kdata="$(try_shrink_kernel "$kdata")" + if [ "$new_kdata" = "$kdata" ]; then + echo "Expected a new (compressed) file" >&2 + exit 1 + fi + if [ "$(compress_type "$new_kdata")" != "gzip" ]; then + echo "Expected $new_kdata to be gzipped" >&2 + exit 1 + fi + ) +} +add_test test_try_shrink_kernel_should_compress + +test_try_shrink_kernel_should_NOT_compress() { + get_tempfile + local kdata="$last_tempfile" + gzip < /dev/null > "$kdata" + ( + . "$functions" + new_kdata="$(try_shrink_kernel "$kdata")" + if [ "$new_kdata" != "$kdata" ]; then + echo "Expected function to return input file as-is" >&2 + exit 1 + fi + ) +} +add_test test_try_shrink_kernel_should_NOT_compress + test_gen_kernel() { get_tempfile kernel_input="$last_tempfile" -- 2.34.1