18c2ecf20Sopenharmony_ci#!/bin/sh
28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ci# XIP kernel .data segment compressor
58c2ecf20Sopenharmony_ci#
68c2ecf20Sopenharmony_ci# Created by:	Nicolas Pitre, August 2017
78c2ecf20Sopenharmony_ci# Copyright:	(C) 2017  Linaro Limited
88c2ecf20Sopenharmony_ci#
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci# This script locates the start of the .data section in xipImage and
118c2ecf20Sopenharmony_ci# substitutes it with a compressed version. The needed offsets are obtained
128c2ecf20Sopenharmony_ci# from symbol addresses in vmlinux. It is expected that .data extends to
138c2ecf20Sopenharmony_ci# the end of xipImage.
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ciset -e
168c2ecf20Sopenharmony_ci
178c2ecf20Sopenharmony_ciVMLINUX="$1"
188c2ecf20Sopenharmony_ciXIPIMAGE="$2"
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ciDD="dd status=none"
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ci# Use "make V=1" to debug this script.
238c2ecf20Sopenharmony_cicase "$KBUILD_VERBOSE" in
248c2ecf20Sopenharmony_ci*1*)
258c2ecf20Sopenharmony_ci	set -x
268c2ecf20Sopenharmony_ci	;;
278c2ecf20Sopenharmony_ciesac
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_cisym_val() {
308c2ecf20Sopenharmony_ci	# extract hex value for symbol in $1
318c2ecf20Sopenharmony_ci	local val=$($NM "$VMLINUX" 2>/dev/null | sed -n "/ $1\$/{s/ .*$//p;q}")
328c2ecf20Sopenharmony_ci	[ "$val" ] || { echo "can't find $1 in $VMLINUX" 1>&2; exit 1; }
338c2ecf20Sopenharmony_ci	# convert from hex to decimal
348c2ecf20Sopenharmony_ci	echo $((0x$val))
358c2ecf20Sopenharmony_ci}
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci__data_loc=$(sym_val __data_loc)
388c2ecf20Sopenharmony_ci_edata_loc=$(sym_val _edata_loc)
398c2ecf20Sopenharmony_cibase_offset=$(sym_val _xiprom)
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ci# convert to file based offsets
428c2ecf20Sopenharmony_cidata_start=$(($__data_loc - $base_offset))
438c2ecf20Sopenharmony_cidata_end=$(($_edata_loc - $base_offset))
448c2ecf20Sopenharmony_ci
458c2ecf20Sopenharmony_ci# Make sure data occupies the last part of the file.
468c2ecf20Sopenharmony_cifile_end=$(${CONFIG_SHELL} "${srctree}/scripts/file-size.sh" "$XIPIMAGE")
478c2ecf20Sopenharmony_ciif [ "$file_end" != "$data_end" ]; then
488c2ecf20Sopenharmony_ci	printf "end of xipImage doesn't match with _edata_loc (%#x vs %#x)\n" \
498c2ecf20Sopenharmony_ci	       $(($file_end + $base_offset)) $_edata_loc 1>&2
508c2ecf20Sopenharmony_ci	exit 1;
518c2ecf20Sopenharmony_cifi
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ci# be ready to clean up
548c2ecf20Sopenharmony_citrap 'rm -f "$XIPIMAGE.tmp"; exit 1' 1 2 3
558c2ecf20Sopenharmony_ci
568c2ecf20Sopenharmony_ci# substitute the data section by a compressed version
578c2ecf20Sopenharmony_ci$DD if="$XIPIMAGE" count=$data_start iflag=count_bytes of="$XIPIMAGE.tmp"
588c2ecf20Sopenharmony_ci$DD if="$XIPIMAGE"  skip=$data_start iflag=skip_bytes |
598c2ecf20Sopenharmony_ci$KGZIP -9 >> "$XIPIMAGE.tmp"
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_ci# replace kernel binary
628c2ecf20Sopenharmony_cimv -f "$XIPIMAGE.tmp" "$XIPIMAGE"
63