2017-08-25 00:54:18 -04:00
#!/bin/sh
# XIP kernel .data segment compressor
#
# Created by: Nicolas Pitre, August 2017
# Copyright: (C) 2017 Linaro Limited
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
# This script locates the start of the .data section in xipImage and
# substitutes it with a compressed version. The needed offsets are obtained
# from symbol addresses in vmlinux. It is expected that .data extends to
# the end of xipImage.
set -e
VMLINUX = " $1 "
XIPIMAGE = " $2 "
DD = "dd status=none"
# Use "make V=1" to debug this script.
case " $KBUILD_VERBOSE " in
*1*)
set -x
; ;
esac
sym_val( ) {
# extract hex value for symbol in $1
2018-03-12 15:51:26 +01:00
local val = $( $NM " $VMLINUX " 2>/dev/null | sed -n " / $1 \$/{s/ .* $//p;q} " )
2017-08-25 00:54:18 -04:00
[ " $val " ] || { echo " can't find $1 in $VMLINUX " 1>& 2; exit 1; }
# convert from hex to decimal
echo $(( 0 x$val ))
}
__data_loc = $( sym_val __data_loc)
_edata_loc = $( sym_val _edata_loc)
base_offset = $( sym_val _xiprom)
# convert to file based offsets
data_start = $(( $__data_loc - $base_offset ))
data_end = $(( $_edata_loc - $base_offset ))
# Make sure data occupies the last part of the file.
kbuild: Use ls(1) instead of stat(1) to obtain file size
stat(1) is not standardized and different implementations have their own
(conflicting) flags for querying the size of a file.
ls(1) provides the same information (value of st.st_size) in the 5th
column, except when the file is a character or block device. This output
is standardized[0]. The -n option turns on -l, which writes lines
formatted like
"%s %u %s %s %u %s %s\n", <file mode>, <number of links>,
<owner name>, <group name>, <size>, <date and time>,
<pathname>
but instead of writing the <owner name> and <group name>, it writes the
numeric owner and group IDs (this avoids /etc/passwd and /etc/group
lookups as well as potential field splitting issues).
The <size> field is specified as "the value that would be returned for
the file in the st_size field of struct stat".
To avoid duplicating logic in several locations in the tree, create
scripts/file-size.sh and update callers to use that instead of stat(1).
[0] http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ls.html#tag_20_73_10
Signed-off-by: Michael Forney <forney@google.com>
Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
2018-03-18 17:54:02 -07:00
file_end = $( ${ CONFIG_SHELL } " ${ srctree } /scripts/file-size.sh " " $XIPIMAGE " )
2017-08-25 00:54:18 -04:00
if [ " $file_end " != " $data_end " ] ; then
printf "end of xipImage doesn't match with _edata_loc (%#x vs %#x)\n" \
2018-03-12 15:51:26 +01:00
$(( $file_end + $base_offset )) $_edata_loc 1>& 2
2017-08-25 00:54:18 -04:00
exit 1;
fi
# be ready to clean up
2018-03-12 15:51:26 +01:00
trap 'rm -f "$XIPIMAGE.tmp"; exit 1' 1 2 3
2017-08-25 00:54:18 -04:00
# substitute the data section by a compressed version
$DD if = " $XIPIMAGE " count = $data_start iflag = count_bytes of = " $XIPIMAGE .tmp "
$DD if = " $XIPIMAGE " skip = $data_start iflag = skip_bytes |
gzip -9 >> " $XIPIMAGE .tmp "
# replace kernel binary
mv -f " $XIPIMAGE .tmp " " $XIPIMAGE "