| #!/bin/sh | 
 | # SPDX-License-Identifier: 0BSD | 
 | # | 
 | # This is a wrapper for xz to compress the kernel image using appropriate | 
 | # compression options depending on the architecture. | 
 | # | 
 | # Author: Lasse Collin <lasse.collin@tukaani.org> | 
 |  | 
 | # This has specialized settings for the following archs. However, | 
 | # XZ-compressed kernel isn't currently supported on every listed arch. | 
 | # | 
 | #   Arch        Align   Notes | 
 | #   arm          2/4    ARM and ARM-Thumb2 | 
 | #   arm64         4 | 
 | #   csky          2 | 
 | #   loongarch     4 | 
 | #   mips         2/4    MicroMIPS is 2-byte aligned | 
 | #   parisc        4 | 
 | #   powerpc       4     Uses its own wrapper for compressors instead of this. | 
 | #   riscv        2/4 | 
 | #   s390          2 | 
 | #   sh            2 | 
 | #   sparc         4 | 
 | #   x86           1 | 
 |  | 
 | # A few archs use 2-byte or 4-byte aligned instructions depending on | 
 | # the kernel config. This function is used to check if the relevant | 
 | # config option is set to "y". | 
 | is_enabled() | 
 | { | 
 | 	grep -q "^$1=y$" include/config/auto.conf | 
 | } | 
 |  | 
 | # XZ_VERSION is needed to disable features that aren't available in | 
 | # old XZ Utils versions. | 
 | XZ_VERSION=$($XZ --robot --version) || exit | 
 | XZ_VERSION=$(printf '%s\n' "$XZ_VERSION" | sed -n 's/^XZ_VERSION=//p') | 
 |  | 
 | # Assume that no BCJ filter is available. | 
 | BCJ= | 
 |  | 
 | # Set the instruction alignment to 1, 2, or 4 bytes. | 
 | # | 
 | # Set the BCJ filter if one is available. | 
 | # It must match the #ifdef usage in lib/decompress_unxz.c. | 
 | case $SRCARCH in | 
 | 	arm) | 
 | 		if is_enabled CONFIG_THUMB2_KERNEL; then | 
 | 			ALIGN=2 | 
 | 			BCJ=--armthumb | 
 | 		else | 
 | 			ALIGN=4 | 
 | 			BCJ=--arm | 
 | 		fi | 
 | 		;; | 
 |  | 
 | 	arm64) | 
 | 		ALIGN=4 | 
 |  | 
 | 		# ARM64 filter was added in XZ Utils 5.4.0. | 
 | 		if [ "$XZ_VERSION" -ge 50040002 ]; then | 
 | 			BCJ=--arm64 | 
 | 		else | 
 | 			echo "$0: Upgrading to xz >= 5.4.0" \ | 
 | 				"would enable the ARM64 filter" \ | 
 | 				"for better compression" >&2 | 
 | 		fi | 
 | 		;; | 
 |  | 
 | 	csky) | 
 | 		ALIGN=2 | 
 | 		;; | 
 |  | 
 | 	loongarch) | 
 | 		ALIGN=4 | 
 | 		;; | 
 |  | 
 | 	mips) | 
 | 		if is_enabled CONFIG_CPU_MICROMIPS; then | 
 | 			ALIGN=2 | 
 | 		else | 
 | 			ALIGN=4 | 
 | 		fi | 
 | 		;; | 
 |  | 
 | 	parisc) | 
 | 		ALIGN=4 | 
 | 		;; | 
 |  | 
 | 	powerpc) | 
 | 		ALIGN=4 | 
 |  | 
 | 		# The filter is only for big endian instruction encoding. | 
 | 		if is_enabled CONFIG_CPU_BIG_ENDIAN; then | 
 | 			BCJ=--powerpc | 
 | 		fi | 
 | 		;; | 
 |  | 
 | 	riscv) | 
 | 		if is_enabled CONFIG_RISCV_ISA_C; then | 
 | 			ALIGN=2 | 
 | 		else | 
 | 			ALIGN=4 | 
 | 		fi | 
 |  | 
 | 		# RISC-V filter was added in XZ Utils 5.6.0. | 
 | 		if [ "$XZ_VERSION" -ge 50060002 ]; then | 
 | 			BCJ=--riscv | 
 | 		else | 
 | 			echo "$0: Upgrading to xz >= 5.6.0" \ | 
 | 				"would enable the RISC-V filter" \ | 
 | 				"for better compression" >&2 | 
 | 		fi | 
 | 		;; | 
 |  | 
 | 	s390) | 
 | 		ALIGN=2 | 
 | 		;; | 
 |  | 
 | 	sh) | 
 | 		ALIGN=2 | 
 | 		;; | 
 |  | 
 | 	sparc) | 
 | 		ALIGN=4 | 
 | 		BCJ=--sparc | 
 | 		;; | 
 |  | 
 | 	x86) | 
 | 		ALIGN=1 | 
 | 		BCJ=--x86 | 
 | 		;; | 
 |  | 
 | 	*) | 
 | 		echo "$0: Arch-specific tuning is missing for '$SRCARCH'" >&2 | 
 |  | 
 | 		# Guess 2-byte-aligned instructions. Guessing too low | 
 | 		# should hurt less than guessing too high. | 
 | 		ALIGN=2 | 
 | 		;; | 
 | esac | 
 |  | 
 | # Select the LZMA2 options matching the instruction alignment. | 
 | case $ALIGN in | 
 | 	1)  LZMA2OPTS= ;; | 
 | 	2)  LZMA2OPTS=lp=1 ;; | 
 | 	4)  LZMA2OPTS=lp=2,lc=2 ;; | 
 | 	*)  echo "$0: ALIGN wrong or missing" >&2; exit 1 ;; | 
 | esac | 
 |  | 
 | # Use single-threaded mode because it compresses a little better | 
 | # (and uses less RAM) than multithreaded mode. | 
 | # | 
 | # For the best compression, the dictionary size shouldn't be | 
 | # smaller than the uncompressed kernel. 128 MiB dictionary | 
 | # needs less than 1400 MiB of RAM in single-threaded mode. | 
 | # | 
 | # On the archs that use this script to compress the kernel, | 
 | # decompression in the preboot code is done in single-call mode. | 
 | # Thus the dictionary size doesn't affect the memory requirements | 
 | # of the preboot decompressor at all. | 
 | exec $XZ --check=crc32 --threads=1 $BCJ --lzma2=$LZMA2OPTS,dict=128MiB |