diff --git a/doc/README.mx28_common b/doc/README.mx28_common
index 8bacaf8..f0a5112 100644
--- a/doc/README.mx28_common
+++ b/doc/README.mx28_common
@@ -134,7 +134,7 @@ The partition layout is ready, next the special partition must be filled with
 proper contents. The contents is generated by running the following command
 (see chapter 2)):
 
-	$ ./tools/mxsboot sd u-boot.sb u-boot.sd
+	$ ./tools/mxsboot mx28 sd u-boot.sb u-boot.sd
 
 The resulting file, "u-boot.sd", shall then be written to the partition. In this
 case, we assume the first partition of the SD card is /dev/mmcblk0p1:
@@ -162,7 +162,7 @@ There are two possibilities when preparing an image writable to NAND flash.
 	   there is a tool called "mxsboot" in the "tools/" directory. The tool
 	   is invoked on "u-boot.sb" file from chapter 2):
 
-		 $ ./tools/mxsboot nand u-boot.sb u-boot.nand
+		 $ ./tools/mxsboot mx28 nand u-boot.sb u-boot.nand
 
 	   NOTE: The above invokation works for NAND flash with geometry of
 		 2048b per page, 64b OOB data, 128kb erase size. If your chip
diff --git a/tools/mxsboot.c b/tools/mxsboot.c
index 6c05aa4..e348877 100644
--- a/tools/mxsboot.c
+++ b/tools/mxsboot.c
@@ -1,7 +1,7 @@
 /*
- * Freescale i.MX28 image generator
+ * Freescale i.MX23/i.MX28 image generator
  *
- * Copyright (C) 2011 Marek Vasut <marek.vasut@gmail.com>
+ * Copyright (C) 2011, 2013 Marek Vasut <marek.vasut@gmail.com>
  * on behalf of DENX Software Engineering GmbH
  *
  * See file CREDITS for list of people who contributed to this
@@ -49,6 +49,11 @@ uint32_t nand_oobsize = 64;
 uint32_t nand_erasesize = 128 * 1024;
 
 /*
+ * SoC type
+ */
+enum { MX23, MX28 } soc_type;
+
+/*
  * Sector on which the SigmaTel boot partition (0x53) starts.
  */
 uint32_t sd_sector = 2048;
@@ -125,6 +130,13 @@ struct mx28_nand_bbt {
 	uint32_t		badblock[510];
 };
 
+struct mx23_sd_config_block {
+	uint32_t		reserved1[2];
+	uint32_t		first_sector_number;
+	uint32_t		reserved2;
+	uint32_t		sector_count;
+};
+
 struct mx28_sd_drive_info {
 	uint32_t		chip_num;
 	uint32_t		drive_type;
@@ -453,9 +465,10 @@ static int mx28_nand_write_firmware(struct mx28_nand_fcb *fcb, int infd,
 void usage(void)
 {
 	printf(
-		"Usage: mxsboot [ops] <type> <infile> <outfile>\n"
-		"Augment BootStream file with a proper header for i.MX28 boot\n"
+		"Usage: mxsboot [ops] <soc> <type> <infile> <outfile>\n"
+		"Augment BootStream file with a proper header for i.MX23/i.MX28 boot\n"
 		"\n"
+		"  <soc>	\"mx23\" or \"mx28\"\n"
 		"  <type>	type of image:\n"
 		"                 \"nand\" for NAND image\n"
 		"                 \"sd\" for SD image\n"
@@ -540,6 +553,50 @@ err0:
 	return ret;
 }
 
+static int mx23_create_sd_image(int infd, int outfd)
+{
+	int ret = -1;
+	uint32_t *buf;
+	int size;
+	off_t fsize;
+	ssize_t wr_size;
+	ssize_t offset = 512 * 4;
+	struct mx23_sd_config_block *cb;
+
+	fsize = lseek(infd, 0, SEEK_END);
+	lseek(infd, 0, SEEK_SET);
+	size = fsize + offset;
+
+	buf = malloc(size);
+	if (!buf) {
+		printf("Can not allocate output buffer of %d bytes\n", size);
+		goto err0;
+	}
+
+	ret = read(infd, (uint8_t *)buf + offset, fsize);
+	if (ret != fsize) {
+		ret = -1;
+		goto err1;
+	}
+
+	cb = (struct mx23_sd_config_block *)buf;
+
+	cb->first_sector_number = sd_sector + 1;
+	cb->sector_count = (size - 1) / 512;
+	wr_size = write(outfd, buf, size);
+	if (wr_size != size) {
+		ret = -1;
+		goto err1;
+	}
+
+	ret = 0;
+
+err1:
+	free(buf);
+err0:
+	return ret;
+}
+
 static int mx28_create_sd_image(int infd, int outfd)
 {
 	int ret = -1;
@@ -576,7 +633,6 @@ static int mx28_create_sd_image(int infd, int outfd)
 	cb->drv_info[0].tag = 0x1;
 	cb->drv_info[0].first_sector_number = sd_sector + 1;
 	cb->drv_info[0].sector_count = (size - 1) / 512;
-
 	wr_size = write(outfd, buf, size);
 	if (wr_size != size) {
 		ret = -1;
@@ -606,7 +662,7 @@ int parse_ops(int argc, char **argv)
 	};
 	int type;
 
-	if (argc < 4)
+	if (argc < 5)
 		return -1;
 
 	for (i = 1; i < argc; i++) {
@@ -618,7 +674,7 @@ int parse_ops(int argc, char **argv)
 			type = PARAM_ERASE;
 		else if (!strncmp(argv[i], "-p", 2))
 			type = PARAM_PART;
-		else	/* SD/MMC */
+		else	/* SoC type */
 			break;
 
 		tmp = strtol(argv[++i], &end, 10);
@@ -636,7 +692,14 @@ int parse_ops(int argc, char **argv)
 		if (type == PARAM_PART)
 			sd_sector = tmp;
 	}
+	if (strcmp(argv[i], "mx23") == 0)
+		soc_type = MX23;
+	else if (strcmp(argv[i], "mx28") == 0)
+		soc_type = MX28;
+	else
+		return -1;
 
+	i++;
 	if (strcmp(argv[i], "sd") && strcmp(argv[i], "nand"))
 		return -1;
 
@@ -674,10 +737,17 @@ int main(int argc, char **argv)
 		goto err2;
 	}
 
-	if (!strcmp(argv[offset], "sd"))
-		ret = mx28_create_sd_image(infd, outfd);
-	else if (!strcmp(argv[offset], "nand"))
-		ret = mx28_create_nand_image(infd, outfd);
+	if (!strcmp(argv[offset], "sd")) {
+		if (soc_type == MX23)
+			ret = mx23_create_sd_image(infd, outfd);
+		else
+			ret = mx28_create_sd_image(infd, outfd);
+	} else if (!strcmp(argv[offset], "nand")) {
+		if (soc_type == MX23)
+			printf("Not implemented yet\n");
+		else
+			ret = mx28_create_nand_image(infd, outfd);
+	}
 
 	close(outfd);
 err2:
