diff --git a/doc/mkimage.1 b/doc/mkimage.1
index 1b9d18cbc9f4ab8951ac6409769b18938eb8401a..146c114d9d6a3a7aaf37cbf13fb5076d8928ff86 100644
--- a/doc/mkimage.1
+++ b/doc/mkimage.1
@@ -108,10 +108,15 @@ Provide special options to the device tree compiler that is used to
 create the image.
 
 .TP
-.BI "\-f [" "image tree source file" "]"
+.BI "\-f [" "image tree source file" " | " "auto" "]"
 Image tree source file that describes the structure and contents of the
 FIT image.
 
+This can be automatically generated for some simple cases.
+Use "-f auto" for this. In that case the arguments -d, -A, -O, -T, -C, -a
+and -e are used to specify the image to include in the FIT and its attributes.
+No .its file is required.
+
 .TP
 .BI "\-F"
 Indicates that an existing FIT image should be modified. No dtc
@@ -178,6 +183,15 @@ with unavailable keys are skipped.
 .B -c """Kernel 3.8 image for production devices""" kernel.itb
 .fi
 
+.P
+Create a FIT image containing a kernel, using automatic mode. No .its file
+is required.
+.nf
+.B mkimage -f auto -A arm -O linux -T kernel -C none -a 43e00000 -e 0 \\\\
+.br
+.B -c """Kernel 4.4 image for production devices""" -d vmlinuz kernel.itb
+.fi
+
 .SH HOMEPAGE
 http://www.denx.de/wiki/U-Boot/WebHome
 .PP
diff --git a/tools/fit_image.c b/tools/fit_image.c
index eb2a25eeac6aebcd7ae764ff8a593d18cc482528..ed101f1d31dac9154a0db61887b09f7eb998d968 100644
--- a/tools/fit_image.c
+++ b/tools/fit_image.c
@@ -18,6 +18,8 @@
 #include "fit_common.h"
 #include "mkimage.h"
 #include <image.h>
+#include <stdarg.h>
+#include <version.h>
 #include <u-boot/crc.h>
 
 static image_header_t header;
@@ -70,6 +72,207 @@ err_keydest:
 	return ret;
 }
 
+/**
+ * fit_calc_size() - Calculate the approximate size of the FIT we will generate
+ */
+static int fit_calc_size(struct image_tool_params *params)
+{
+	int size, total_size;
+
+	size = imagetool_get_filesize(params, params->datafile);
+	if (size < 0)
+		return -1;
+
+	total_size = size;
+
+	/* TODO(sjg@chromium.org): Add in the size of any other files */
+
+	/* Add plenty of space for headers, properties, nodes, etc. */
+	total_size += 4096;
+
+	return total_size;
+}
+
+static int fdt_property_file(struct image_tool_params *params,
+			     void *fdt, const char *name, const char *fname)
+{
+	struct stat sbuf;
+	void *ptr;
+	int ret;
+	int fd;
+
+	fd = open(fname, O_RDWR | O_BINARY);
+	if (fd < 0) {
+		fprintf(stderr, "%s: Can't open %s: %s\n",
+			params->cmdname, fname, strerror(errno));
+		return -1;
+	}
+
+	if (fstat(fd, &sbuf) < 0) {
+		fprintf(stderr, "%s: Can't stat %s: %s\n",
+			params->cmdname, fname, strerror(errno));
+		goto err;
+	}
+
+	ret = fdt_property_placeholder(fdt, "data", sbuf.st_size, &ptr);
+	if (ret)
+		return ret;
+	ret = read(fd, ptr, sbuf.st_size);
+	if (ret != sbuf.st_size) {
+		fprintf(stderr, "%s: Can't read %s: %s\n",
+			params->cmdname, fname, strerror(errno));
+		goto err;
+	}
+
+	return 0;
+err:
+	close(fd);
+	return -1;
+}
+
+static int fdt_property_strf(void *fdt, const char *name, const char *fmt, ...)
+{
+	char str[100];
+	va_list ptr;
+
+	va_start(ptr, fmt);
+	vsnprintf(str, sizeof(str), fmt, ptr);
+	va_end(ptr);
+	return fdt_property_string(fdt, name, str);
+}
+
+/**
+ * fit_write_images() - Write out a list of images to the FIT
+ *
+ * Include the main image (params->datafile).
+ */
+static int fit_write_images(struct image_tool_params *params, char *fdt)
+{
+	const char *typename;
+	char str[100];
+	int ret;
+
+	fdt_begin_node(fdt, "images");
+
+	/* First the main image */
+	typename = genimg_get_type_short_name(params->fit_image_type);
+	snprintf(str, sizeof(str), "%s@1", typename);
+	fdt_begin_node(fdt, str);
+	fdt_property_string(fdt, "description", params->imagename);
+	fdt_property_string(fdt, "type", typename);
+	fdt_property_string(fdt, "arch", genimg_get_arch_name(params->arch));
+	fdt_property_string(fdt, "os", genimg_get_os_short_name(params->os));
+	fdt_property_string(fdt, "compression",
+			    genimg_get_comp_short_name(params->comp));
+	fdt_property_u32(fdt, "load", params->addr);
+	fdt_property_u32(fdt, "entry", params->ep);
+
+	/*
+	 * Put data last since it is large. SPL may only load the first part
+	 * of the DT, so this way it can access all the above fields.
+	 */
+	ret = fdt_property_file(params, fdt, "data", params->datafile);
+	if (ret)
+		return ret;
+	fdt_end_node(fdt);
+
+	fdt_end_node(fdt);
+
+	return 0;
+}
+
+/**
+ * fit_write_configs() - Write out a list of configurations to the FIT
+ *
+ * Create a configuration with the main image in it.
+ */
+static void fit_write_configs(struct image_tool_params *params, char *fdt)
+{
+	const char *typename;
+	char str[100];
+
+	fdt_begin_node(fdt, "configurations");
+	fdt_property_string(fdt, "default", "conf@1");
+
+	fdt_begin_node(fdt, "conf@1");
+	typename = genimg_get_type_short_name(params->fit_image_type);
+	snprintf(str, sizeof(str), "%s@1", typename);
+	fdt_property_string(fdt, typename, str);
+	fdt_end_node(fdt);
+
+	fdt_end_node(fdt);
+}
+
+static int fit_build_fdt(struct image_tool_params *params, char *fdt, int size)
+{
+	int ret;
+
+	ret = fdt_create(fdt, size);
+	if (ret)
+		return ret;
+	fdt_finish_reservemap(fdt);
+	fdt_begin_node(fdt, "");
+	fdt_property_strf(fdt, "description",
+			  "%s image with one or more FDT blobs",
+			  genimg_get_type_name(params->fit_image_type));
+	fdt_property_strf(fdt, "creator", "U-Boot mkimage %s", PLAIN_VERSION);
+	fdt_property_u32(fdt, "#address-cells", 1);
+	ret = fit_write_images(params, fdt);
+	if (ret)
+		return ret;
+	fit_write_configs(params, fdt);
+	fdt_end_node(fdt);
+	ret = fdt_finish(fdt);
+	if (ret)
+		return ret;
+
+	return fdt_totalsize(fdt);
+}
+
+static int fit_build(struct image_tool_params *params, const char *fname)
+{
+	char *buf;
+	int size;
+	int ret;
+	int fd;
+
+	size = fit_calc_size(params);
+	if (size < 0)
+		return -1;
+	buf = malloc(size);
+	if (!buf) {
+		fprintf(stderr, "%s: Out of memory (%d bytes)\n",
+			params->cmdname, size);
+		return -1;
+	}
+	ret = fit_build_fdt(params, buf, size);
+	if (ret < 0) {
+		fprintf(stderr, "%s: Failed to build FIT image\n",
+			params->cmdname);
+		goto err;
+	}
+	size = ret;
+	fd = open(fname, O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0666);
+	if (fd < 0) {
+		fprintf(stderr, "%s: Can't open %s: %s\n",
+			params->cmdname, fname, strerror(errno));
+		goto err;
+	}
+	ret = write(fd, buf, size);
+	if (ret != size) {
+		fprintf(stderr, "%s: Can't write %s: %s\n",
+			params->cmdname, fname, strerror(errno));
+		close(fd);
+		goto err;
+	}
+	close(fd);
+
+	return 0;
+err:
+	free(buf);
+	return -1;
+}
+
 /**
  * fit_handle_file - main FIT file processing function
  *
@@ -103,7 +306,14 @@ static int fit_handle_file(struct image_tool_params *params)
 	sprintf (tmpfile, "%s%s", params->imagefile, MKIMAGE_TMPFILE_SUFFIX);
 
 	/* We either compile the source file, or use the existing FIT image */
-	if (params->datafile) {
+	if (params->auto_its) {
+		if (fit_build(params, tmpfile)) {
+			fprintf(stderr, "%s: failed to build FIT\n",
+				params->cmdname);
+			return EXIT_FAILURE;
+		}
+		*cmd = '\0';
+	} else if (params->datafile) {
 		/* dtc -I dts -O dtb -p 500 datafile > tmpfile */
 		snprintf(cmd, sizeof(cmd), "%s %s %s > %s",
 			 MKIMAGE_DTC, params->dtc, params->datafile, tmpfile);
@@ -112,7 +322,7 @@ static int fit_handle_file(struct image_tool_params *params)
 		snprintf(cmd, sizeof(cmd), "cp %s %s",
 			 params->imagefile, tmpfile);
 	}
-	if (system (cmd) == -1) {
+	if (*cmd && system(cmd) == -1) {
 		fprintf (stderr, "%s: system(%s) failed: %s\n",
 				params->cmdname, cmd, strerror(errno));
 		goto err_system;
@@ -248,6 +458,8 @@ static int fit_extract_contents(void *ptr, struct image_tool_params *params)
 
 static int fit_check_params(struct image_tool_params *params)
 {
+	if (params->auto_its)
+		return 0;
 	return	((params->dflag && (params->fflag || params->lflag)) ||
 		(params->fflag && (params->dflag || params->lflag)) ||
 		(params->lflag && (params->dflag || params->fflag)));
diff --git a/tools/imagetool.h b/tools/imagetool.h
index 3cf42ac96ab1d84c89385d461b8ef1b464cf69f6..4f426e40a04043581d8acb2b09cdfac4bb6c79a4 100644
--- a/tools/imagetool.h
+++ b/tools/imagetool.h
@@ -61,6 +61,7 @@ struct image_tool_params {
 	int require_keys;	/* 1 to mark signing keys as 'required' */
 	int file_size;		/* Total size of output file */
 	int orig_file_size;	/* Original size for file before padding */
+	bool auto_its;		/* Automatically create the .its file */
 	int fit_image_type;	/* Image type to put into the FIT */
 };
 
diff --git a/tools/mkimage.c b/tools/mkimage.c
index 4526da20b572899b5f0c95658acb47cb18efd0e6..7add86c13d09074cb6bcb09f446c71fa0b290b4b 100644
--- a/tools/mkimage.c
+++ b/tools/mkimage.c
@@ -85,7 +85,7 @@ static void usage(const char *msg)
 		"          -x ==> set XIP (execute in place)\n",
 		params.cmdname);
 	fprintf(stderr,
-		"       %s [-D dtc_options] [-f fit-image.its|-F] fit-image\n",
+		"       %s [-D dtc_options] [-f fit-image.its|-f auto|-F] fit-image\n",
 		params.cmdname);
 	fprintf(stderr,
 		"          -D => set all options for device tree compiler\n"
@@ -159,7 +159,8 @@ static void process_args(int argc, char **argv)
 			params.eflag = 1;
 			break;
 		case 'f':
-			params.datafile = optarg;
+			datafile = optarg;
+			params.auto_its = !strcmp(datafile, "auto");
 			/* no break */
 		case 'F':
 			/*
@@ -235,7 +236,8 @@ static void process_args(int argc, char **argv)
 	 */
 	if (params.type == IH_TYPE_FLATDT) {
 		params.fit_image_type = type;
-		params.datafile = datafile;
+		if (!params.auto_its)
+			params.datafile = datafile;
 	} else if (type != IH_TYPE_INVALID) {
 		params.type = type;
 	}