| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- #!/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
|