xz_wrap.sh 3.4 KB

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