163 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			163 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
| #!/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
 |