[U-Boot] [PATCH v2] build: create time and date independent binary

Heiko Schocher hs at denx.de
Tue Jun 23 10:32:37 CEST 2015


With this option enabled each compilation creates the exact
same binary. There are no timestamps, with which a U-Boot
binary can be identified.

This option is disabled by default.

Signed-off-by: Heiko Schocher <hs at denx.de>
Tested-by: Chris Kuethe <chris.kuethe at gmail.com>
---
For testing this patch, I wrote the following 2 scripts,
and add a patch, which enables CONFIG_SYS_EXACT_BINARY,
as this is normally disabled in default configs.

steps:
- create file, which contains a list of boards you want
  to check, if they create a date/time independent binary
  for example:
$ cat test_list
at91sam9g20ek_2mmc
cairo
corvus
smartweb
axm

- create reference files with
$ ./comp_list_boards.sh test_list init
init boards in test_list
check board at91sam9g20ek_2mmc
init at91sam9g20ek_2mmc
check board cairo
init cairo
check board corvus
init corvus
check board smartweb
init smartweb
check board axm
init axm

- start another round of compile and compare with base
$ ./comp_list_boards.sh test_list
checking boards in test_list
check board at91sam9g20ek_2mmc
compile at91sam9g20ek_2mmc
check board cairo
compile cairo
check board corvus
compile corvus
check board smartweb
compile smartweb
check board axm
compile axm

and here the scripts:
exact_bin_defconfig.patch:
--- a/.config	2015-06-15 15:53:11.855529259 +0200
+++ b/.config	2015-06-15 15:53:00.186220214 +0200
@@ -228,7 +228,7 @@ CONFIG_LOCALVERSION_AUTO=y
 CONFIG_CC_OPTIMIZE_FOR_SIZE=y
 # CONFIG_SYS_MALLOC_F is not set
 CONFIG_EXPERT=y
-# CONFIG_SYS_EXACT_BINARY is not set
+CONFIG_SYS_EXACT_BINARY=y

 #
 # Boot images
-------------------------------------------
comp_diff_board.sh

base_bin_dir="base_bin"
logfile_base="/tmp/comp"

boardname=""
if [ $# -lt 1 ]
then
	echo "need boardname"
	exit 1
else
boardname=$1
fi

if [ ! -d "$logfile_base" ]
then
mkdir $logfile_base
fi

logfile=$logfile_base"/"$boardname".log"
init=0
if [ $# -lt 2 ]
then
echo compile $boardname
else
init=1
echo init $boardname
fi

if [ -e $logfile ]
then
rm -rf $logfile
fi

function diff_and_fail (){
	echo "-------------------------------------"
	echo $boardname has differences
	if [ -n "$2" ]
	then
		hexdump -C $2 > gnlmpf2
	else
		hexdump -C $base_bin_dir/$boardname-$1 > gnlmpf2
	fi
	hexdump -C $1 > gnlmpf
	echo "-------------------------------------"
	exit 1
}

function diff_or_cp (){
if [ $init -eq 1 ]
then
	if [ -n "$2" ]
	then
		cp $1 $base_bin_dir/$boardname-$2
	else
		cp $1 $base_bin_dir/$boardname-$1
	fi
else
	if [ -n "$2" ]
	then
		cmp $1 $base_bin_dir/$boardname-$2
		if [ $? -ne 0 ]; then
			diff_and_fail $1 $base_bin_dir/$boardname-$2
		fi
	else
		cmp $1 $base_bin_dir/$boardname-$1
		if [ $? -ne 0 ]; then
			diff_and_fail $1
		fi
	fi
fi
}

make mrproper &>>$logfile
git reset --hard HEAD &>>$logfile
make $boardname"_defconfig" &>>$logfile
patch -p1 < exact_bin_defconfig.patch &>>$logfile
make -s all &>>$logfile

if [ -s "u-boot.bin" ];
then
	diff_or_cp u-boot.bin
fi

if [ -s "spl/u-boot-spl.bin" ];
then
	diff_or_cp spl/u-boot-spl.bin u-boot-spl.bin
fi

if [ -s "u-boot.img" ];
then
	diff_or_cp u-boot.img
fi

if [ -s "u-boot.kwb" ];
then
	diff_or_cp u-boot.kwb
fi

if [ -s "u-boot.pbl" ];
then
	diff_or_cp u-boot.pbl
fi

if [ -s "u-boot.pbl" ];
then
	diff_or_cp u-boot.pbl
fi

if [ -s "MLO" ];
then
	diff_or_cp MLO
fi

-------------------------------------------
comp_list_boards.sh

if [ $# -lt 1 ]
then
	echo "need boardlist"
	exit 1
else
boardlist=$1
fi

init=0
if [ $# -lt 2 ]
then
echo checking boards in $boardlist
else
init=1
echo init boards in $boardlist
fi

while read line
do
    echo check board $line
    if [ $init -eq 1 ]
    then
        comp_diff_board.sh $line init
    else
        comp_diff_board.sh $line
    fi
done < $boardlist


Changes in v2:
- add Tested-by: Chris Kuethe <chris.kuethe at gmail.com>
- add new cmdline parameter for mkimage "-b" so mkimage
  creates also headers without date/timing information
- add in patch notes 2 scripts and a patch for checking
  if created binaries are really time/date independent.

 Kconfig               |  9 +++++++++
 Makefile              | 16 +++++++++++++++-
 tools/default_image.c |  2 ++
 tools/imagetool.h     |  1 +
 tools/mkimage.c       |  5 +++++
 5 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/Kconfig b/Kconfig
index 15e15af..c0c7eb8 100644
--- a/Kconfig
+++ b/Kconfig
@@ -81,6 +81,15 @@ menuconfig EXPERT
 	  Only use this if you really know what you are doing.
 
 if EXPERT
+	config SYS_EXACT_BINARY
+	bool "Create time and date independent binary"
+	default n
+	help
+	  With this option enabled each compilation creates the exact
+	  same binary. There are no timestamps, with which a U-Boot
+	  binary can be identified.
+	  This option is disabled by default.
+
 	config SYS_MALLOC_CLEAR_ON_INIT
 	bool "Init with zeros the memory reserved for malloc (slow)"
 	default y
diff --git a/Makefile b/Makefile
index 0a674bf..713a3e2 100644
--- a/Makefile
+++ b/Makefile
@@ -780,8 +780,14 @@ endif
 quiet_cmd_objcopy = OBJCOPY $@
 cmd_objcopy = $(OBJCOPY) $(OBJCOPYFLAGS) $(OBJCOPYFLAGS_$(@F)) $< $@
 
+ifeq ($(CONFIG_SYS_EXACT_BINARY),y)
+MKIMAGEFLAGS_EXTRA = -b
+else
+MKIMAGEFLAGS_EXTRA =
+endif
+
 quiet_cmd_mkimage = MKIMAGE $@
-cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_$(@F)) -d $< $@ \
+cmd_mkimage = $(objtree)/tools/mkimage $(MKIMAGEFLAGS_EXTRA) $(MKIMAGEFLAGS_$(@F)) -d $< $@ \
 	$(if $(KBUILD_VERBOSE:1=), >/dev/null)
 
 quiet_cmd_cat = CAT     $@
@@ -1230,11 +1236,19 @@ define filechk_version.h
 	echo \#define LD_VERSION_STRING \"$$($(LD) --version | head -n 1)\"; )
 endef
 
+ifeq ($(CONFIG_SYS_EXACT_BINARY),y)
+define filechk_timestamp.h
+	(LC_ALL=C date +'#define U_BOOT_DATE "NODATE"'; \
+	LC_ALL=C date +'#define U_BOOT_TIME "NOTIME"'; \
+	LC_ALL=C date +'#define U_BOOT_TZ "NOTZ"')
+endef
+else
 define filechk_timestamp.h
 	(LC_ALL=C date +'#define U_BOOT_DATE "%b %d %C%y"'; \
 	LC_ALL=C date +'#define U_BOOT_TIME "%T"'; \
 	LC_ALL=C date +'#define U_BOOT_TZ "%z"')
 endef
+endif
 
 $(version_h): include/config/uboot.release FORCE
 	$(call filechk,version.h)
diff --git a/tools/default_image.c b/tools/default_image.c
index cf5c0d4..9bd3165 100644
--- a/tools/default_image.c
+++ b/tools/default_image.c
@@ -98,6 +98,8 @@ static void image_set_header(void *ptr, struct stat *sbuf, int ifd,
 
 	/* Build new header */
 	image_set_magic(hdr, IH_MAGIC);
+	if (params->bflag)
+		sbuf->st_mtime = 0;
 	image_set_time(hdr, sbuf->st_mtime);
 	image_set_size(hdr, sbuf->st_size - sizeof(image_header_t));
 	image_set_load(hdr, params->addr);
diff --git a/tools/imagetool.h b/tools/imagetool.h
index b7874f4..3abc385 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -33,6 +33,7 @@
  * type specific functions
  */
 struct image_tool_params {
+	int bflag;
 	int dflag;
 	int eflag;
 	int fflag;
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 5ccd951..38f48f3 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -51,6 +51,9 @@ main (int argc, char **argv)
 					genimg_get_arch_id (*++argv)) < 0)
 					usage ();
 				goto NXTARG;
+			case 'b':
+				params.bflag = 1;
+				break;
 			case 'c':
 				if (--argc <= 0)
 					usage();
@@ -544,6 +547,8 @@ static void usage(void)
 #else
 	fprintf(stderr, "Signing / verified boot not supported (CONFIG_FIT_SIGNATURE undefined)\n");
 #endif
+	fprintf(stderr, "       %s -b ==> build exact binary (without date/time stamp)\n",
+		params.cmdname);
 	fprintf (stderr, "       %s -V ==> print version information and exit\n",
 		params.cmdname);
 
-- 
2.1.0



More information about the U-Boot mailing list