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