1*d2c16535SElliott Hughes#!/bin/sh 2*d2c16535SElliott Hughes# SPDX-License-Identifier: 0BSD 3*d2c16535SElliott Hughes# 4*d2c16535SElliott Hughes# This is a wrapper for xz to compress the kernel image using appropriate 5*d2c16535SElliott Hughes# compression options depending on the architecture. 6*d2c16535SElliott Hughes# 7*d2c16535SElliott Hughes# Author: Lasse Collin <[email protected]> 8*d2c16535SElliott Hughes 9*d2c16535SElliott Hughes# This has specialized settings for the following archs. However, 10*d2c16535SElliott Hughes# XZ-compressed kernel isn't currently supported on every listed arch. 11*d2c16535SElliott Hughes# 12*d2c16535SElliott Hughes# Arch Align Notes 13*d2c16535SElliott Hughes# arm 2/4 ARM and ARM-Thumb2 14*d2c16535SElliott Hughes# arm64 4 15*d2c16535SElliott Hughes# csky 2 16*d2c16535SElliott Hughes# loongarch 4 17*d2c16535SElliott Hughes# mips 2/4 MicroMIPS is 2-byte aligned 18*d2c16535SElliott Hughes# parisc 4 19*d2c16535SElliott Hughes# powerpc 4 Uses its own wrapper for compressors instead of this. 20*d2c16535SElliott Hughes# riscv 2/4 21*d2c16535SElliott Hughes# s390 2 22*d2c16535SElliott Hughes# sh 2 23*d2c16535SElliott Hughes# sparc 4 24*d2c16535SElliott Hughes# x86 1 25*d2c16535SElliott Hughes 26*d2c16535SElliott Hughes# A few archs use 2-byte or 4-byte aligned instructions depending on 27*d2c16535SElliott Hughes# the kernel config. This function is used to check if the relevant 28*d2c16535SElliott Hughes# config option is set to "y". 29*d2c16535SElliott Hughesis_enabled() 30*d2c16535SElliott Hughes{ 31*d2c16535SElliott Hughes grep -q "^$1=y$" include/config/auto.conf 32*d2c16535SElliott Hughes} 33*d2c16535SElliott Hughes 34*d2c16535SElliott Hughes# XZ_VERSION is needed to disable features that aren't available in 35*d2c16535SElliott Hughes# old XZ Utils versions. 36*d2c16535SElliott HughesXZ_VERSION=$($XZ --robot --version) || exit 37*d2c16535SElliott HughesXZ_VERSION=$(printf '%s\n' "$XZ_VERSION" | sed -n 's/^XZ_VERSION=//p') 38*d2c16535SElliott Hughes 39*d2c16535SElliott Hughes# Assume that no BCJ filter is available. 40*d2c16535SElliott HughesBCJ= 41*d2c16535SElliott Hughes 42*d2c16535SElliott Hughes# Set the instruction alignment to 1, 2, or 4 bytes. 43*d2c16535SElliott Hughes# 44*d2c16535SElliott Hughes# Set the BCJ filter if one is available. 45*d2c16535SElliott Hughes# It must match the #ifdef usage in lib/decompress_unxz.c. 46*d2c16535SElliott Hughescase $SRCARCH in 47*d2c16535SElliott Hughes arm) 48*d2c16535SElliott Hughes if is_enabled CONFIG_THUMB2_KERNEL; then 49*d2c16535SElliott Hughes ALIGN=2 50*d2c16535SElliott Hughes BCJ=--armthumb 51*d2c16535SElliott Hughes else 52*d2c16535SElliott Hughes ALIGN=4 53*d2c16535SElliott Hughes BCJ=--arm 54*d2c16535SElliott Hughes fi 55*d2c16535SElliott Hughes ;; 56*d2c16535SElliott Hughes 57*d2c16535SElliott Hughes arm64) 58*d2c16535SElliott Hughes ALIGN=4 59*d2c16535SElliott Hughes 60*d2c16535SElliott Hughes # ARM64 filter was added in XZ Utils 5.4.0. 61*d2c16535SElliott Hughes if [ "$XZ_VERSION" -ge 50040002 ]; then 62*d2c16535SElliott Hughes BCJ=--arm64 63*d2c16535SElliott Hughes else 64*d2c16535SElliott Hughes echo "$0: Upgrading to xz >= 5.4.0" \ 65*d2c16535SElliott Hughes "would enable the ARM64 filter" \ 66*d2c16535SElliott Hughes "for better compression" >&2 67*d2c16535SElliott Hughes fi 68*d2c16535SElliott Hughes ;; 69*d2c16535SElliott Hughes 70*d2c16535SElliott Hughes csky) 71*d2c16535SElliott Hughes ALIGN=2 72*d2c16535SElliott Hughes ;; 73*d2c16535SElliott Hughes 74*d2c16535SElliott Hughes loongarch) 75*d2c16535SElliott Hughes ALIGN=4 76*d2c16535SElliott Hughes ;; 77*d2c16535SElliott Hughes 78*d2c16535SElliott Hughes mips) 79*d2c16535SElliott Hughes if is_enabled CONFIG_CPU_MICROMIPS; then 80*d2c16535SElliott Hughes ALIGN=2 81*d2c16535SElliott Hughes else 82*d2c16535SElliott Hughes ALIGN=4 83*d2c16535SElliott Hughes fi 84*d2c16535SElliott Hughes ;; 85*d2c16535SElliott Hughes 86*d2c16535SElliott Hughes parisc) 87*d2c16535SElliott Hughes ALIGN=4 88*d2c16535SElliott Hughes ;; 89*d2c16535SElliott Hughes 90*d2c16535SElliott Hughes powerpc) 91*d2c16535SElliott Hughes ALIGN=4 92*d2c16535SElliott Hughes 93*d2c16535SElliott Hughes # The filter is only for big endian instruction encoding. 94*d2c16535SElliott Hughes if is_enabled CONFIG_CPU_BIG_ENDIAN; then 95*d2c16535SElliott Hughes BCJ=--powerpc 96*d2c16535SElliott Hughes fi 97*d2c16535SElliott Hughes ;; 98*d2c16535SElliott Hughes 99*d2c16535SElliott Hughes riscv) 100*d2c16535SElliott Hughes if is_enabled CONFIG_RISCV_ISA_C; then 101*d2c16535SElliott Hughes ALIGN=2 102*d2c16535SElliott Hughes else 103*d2c16535SElliott Hughes ALIGN=4 104*d2c16535SElliott Hughes fi 105*d2c16535SElliott Hughes 106*d2c16535SElliott Hughes # RISC-V filter was added in XZ Utils 5.6.0. 107*d2c16535SElliott Hughes if [ "$XZ_VERSION" -ge 50060002 ]; then 108*d2c16535SElliott Hughes BCJ=--riscv 109*d2c16535SElliott Hughes else 110*d2c16535SElliott Hughes echo "$0: Upgrading to xz >= 5.6.0" \ 111*d2c16535SElliott Hughes "would enable the RISC-V filter" \ 112*d2c16535SElliott Hughes "for better compression" >&2 113*d2c16535SElliott Hughes fi 114*d2c16535SElliott Hughes ;; 115*d2c16535SElliott Hughes 116*d2c16535SElliott Hughes s390) 117*d2c16535SElliott Hughes ALIGN=2 118*d2c16535SElliott Hughes ;; 119*d2c16535SElliott Hughes 120*d2c16535SElliott Hughes sh) 121*d2c16535SElliott Hughes ALIGN=2 122*d2c16535SElliott Hughes ;; 123*d2c16535SElliott Hughes 124*d2c16535SElliott Hughes sparc) 125*d2c16535SElliott Hughes ALIGN=4 126*d2c16535SElliott Hughes BCJ=--sparc 127*d2c16535SElliott Hughes ;; 128*d2c16535SElliott Hughes 129*d2c16535SElliott Hughes x86) 130*d2c16535SElliott Hughes ALIGN=1 131*d2c16535SElliott Hughes BCJ=--x86 132*d2c16535SElliott Hughes ;; 133*d2c16535SElliott Hughes 134*d2c16535SElliott Hughes *) 135*d2c16535SElliott Hughes echo "$0: Arch-specific tuning is missing for '$SRCARCH'" >&2 136*d2c16535SElliott Hughes 137*d2c16535SElliott Hughes # Guess 2-byte-aligned instructions. Guessing too low 138*d2c16535SElliott Hughes # should hurt less than guessing too high. 139*d2c16535SElliott Hughes ALIGN=2 140*d2c16535SElliott Hughes ;; 141*d2c16535SElliott Hughesesac 142*d2c16535SElliott Hughes 143*d2c16535SElliott Hughes# Select the LZMA2 options matching the instruction alignment. 144*d2c16535SElliott Hughescase $ALIGN in 145*d2c16535SElliott Hughes 1) LZMA2OPTS= ;; 146*d2c16535SElliott Hughes 2) LZMA2OPTS=lp=1 ;; 147*d2c16535SElliott Hughes 4) LZMA2OPTS=lp=2,lc=2 ;; 148*d2c16535SElliott Hughes *) echo "$0: ALIGN wrong or missing" >&2; exit 1 ;; 149*d2c16535SElliott Hughesesac 150*d2c16535SElliott Hughes 151*d2c16535SElliott Hughes# Use single-threaded mode because it compresses a little better 152*d2c16535SElliott Hughes# (and uses less RAM) than multithreaded mode. 153*d2c16535SElliott Hughes# 154*d2c16535SElliott Hughes# For the best compression, the dictionary size shouldn't be 155*d2c16535SElliott Hughes# smaller than the uncompressed kernel. 128 MiB dictionary 156*d2c16535SElliott Hughes# needs less than 1400 MiB of RAM in single-threaded mode. 157*d2c16535SElliott Hughes# 158*d2c16535SElliott Hughes# On the archs that use this script to compress the kernel, 159*d2c16535SElliott Hughes# decompression in the preboot code is done in single-call mode. 160*d2c16535SElliott Hughes# Thus the dictionary size doesn't affect the memory requirements 161*d2c16535SElliott Hughes# of the preboot decompressor at all. 162*d2c16535SElliott Hughesexec $XZ --check=crc32 --threads=1 $BCJ --lzma2=$LZMA2OPTS,dict=128MiB 163