| Nicolas Pitre | ca8b5d9 | 2017-08-25 00:54:18 -0400 | [diff] [blame] | 1 | #!/bin/sh | 
| Thomas Gleixner | d2912cb | 2019-06-04 10:11:33 +0200 | [diff] [blame^] | 2 | # SPDX-License-Identifier: GPL-2.0-only | 
| Nicolas Pitre | ca8b5d9 | 2017-08-25 00:54:18 -0400 | [diff] [blame] | 3 |  | 
 | 4 | # XIP kernel .data segment compressor | 
 | 5 | # | 
 | 6 | # Created by:	Nicolas Pitre, August 2017 | 
 | 7 | # Copyright:	(C) 2017  Linaro Limited | 
 | 8 | # | 
| Nicolas Pitre | ca8b5d9 | 2017-08-25 00:54:18 -0400 | [diff] [blame] | 9 |  | 
 | 10 | # This script locates the start of the .data section in xipImage and | 
 | 11 | # substitutes it with a compressed version. The needed offsets are obtained | 
 | 12 | # from symbol addresses in vmlinux. It is expected that .data extends to | 
 | 13 | # the end of xipImage. | 
 | 14 |  | 
 | 15 | set -e | 
 | 16 |  | 
 | 17 | VMLINUX="$1" | 
 | 18 | XIPIMAGE="$2" | 
 | 19 |  | 
 | 20 | DD="dd status=none" | 
 | 21 |  | 
 | 22 | # Use "make V=1" to debug this script. | 
 | 23 | case "$KBUILD_VERBOSE" in | 
 | 24 | *1*) | 
 | 25 | 	set -x | 
 | 26 | 	;; | 
 | 27 | esac | 
 | 28 |  | 
 | 29 | sym_val() { | 
 | 30 | 	# extract hex value for symbol in $1 | 
| Nicolas Pitre | 1b8837b | 2018-03-12 15:51:26 +0100 | [diff] [blame] | 31 | 	local val=$($NM "$VMLINUX" 2>/dev/null | sed -n "/ $1\$/{s/ .*$//p;q}") | 
| Nicolas Pitre | ca8b5d9 | 2017-08-25 00:54:18 -0400 | [diff] [blame] | 32 | 	[ "$val" ] || { echo "can't find $1 in $VMLINUX" 1>&2; exit 1; } | 
 | 33 | 	# convert from hex to decimal | 
 | 34 | 	echo $((0x$val)) | 
 | 35 | } | 
 | 36 |  | 
 | 37 | __data_loc=$(sym_val __data_loc) | 
 | 38 | _edata_loc=$(sym_val _edata_loc) | 
 | 39 | base_offset=$(sym_val _xiprom) | 
 | 40 |  | 
 | 41 | # convert to file based offsets | 
 | 42 | data_start=$(($__data_loc - $base_offset)) | 
 | 43 | data_end=$(($_edata_loc - $base_offset)) | 
 | 44 |  | 
 | 45 | # Make sure data occupies the last part of the file. | 
| Michael Forney | a670b0b | 2018-03-18 17:54:02 -0700 | [diff] [blame] | 46 | file_end=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" "$XIPIMAGE") | 
| Nicolas Pitre | ca8b5d9 | 2017-08-25 00:54:18 -0400 | [diff] [blame] | 47 | if [ "$file_end" != "$data_end" ]; then | 
 | 48 | 	printf "end of xipImage doesn't match with _edata_loc (%#x vs %#x)\n" \ | 
| Nicolas Pitre | 1b8837b | 2018-03-12 15:51:26 +0100 | [diff] [blame] | 49 | 	       $(($file_end + $base_offset)) $_edata_loc 1>&2 | 
| Nicolas Pitre | ca8b5d9 | 2017-08-25 00:54:18 -0400 | [diff] [blame] | 50 | 	exit 1; | 
 | 51 | fi | 
 | 52 |  | 
 | 53 | # be ready to clean up | 
| Nicolas Pitre | 1b8837b | 2018-03-12 15:51:26 +0100 | [diff] [blame] | 54 | trap 'rm -f "$XIPIMAGE.tmp"; exit 1' 1 2 3 | 
| Nicolas Pitre | ca8b5d9 | 2017-08-25 00:54:18 -0400 | [diff] [blame] | 55 |  | 
 | 56 | # substitute the data section by a compressed version | 
 | 57 | $DD if="$XIPIMAGE" count=$data_start iflag=count_bytes of="$XIPIMAGE.tmp" | 
 | 58 | $DD if="$XIPIMAGE"  skip=$data_start iflag=skip_bytes | | 
 | 59 | gzip -9 >> "$XIPIMAGE.tmp" | 
 | 60 |  | 
 | 61 | # replace kernel binary | 
 | 62 | mv -f "$XIPIMAGE.tmp" "$XIPIMAGE" |