projects/linux·blob master · refs

167 lines · 3.5 KiB

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