public inbox for u-boot@lists.denx.de
 help / color / mirror / Atom feed
* [U-Boot-Users] [PATCH 1/5] OneNAND support
@ 2007-09-07  0:57 Kyungmin Park
  2007-09-08 22:53 ` Wolfgang Denk
  0 siblings, 1 reply; 4+ messages in thread
From: Kyungmin Park @ 2007-09-07  0:57 UTC (permalink / raw)
  To: u-boot

[PATCH] OneNAND support

This patch enables the OneNAND at U-boot

Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
diff --git a/Makefile b/Makefile
index 0477cd3..d42f2ef 100644
--- a/Makefile
+++ b/Makefile
@@ -211,6 +211,7 @@ LIBS += drivers/libdrivers.a
 LIBS += drivers/bios_emulator/libatibiosemu.a
 LIBS += drivers/nand/libnand.a
 LIBS += drivers/nand_legacy/libnand_legacy.a
+LIBS += drivers/onenand/libonenand.a
 LIBS += drivers/net/libnet.a
 ifeq ($(CPU),mpc83xx)
 LIBS += drivers/qe/qe.a
diff --git a/common/Makefile b/common/Makefile
index ef7d097..fde5ad9 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -37,13 +37,14 @@ COBJS	= main.o ACEX1K.o altera.o bedbug.o circbuf.o cmd_autoscript.o \
 	  cmd_load.o cmd_log.o \
 	  cmd_mem.o cmd_mii.o cmd_misc.o cmd_mmc.o \
 	  cmd_nand.o cmd_net.o cmd_nvedit.o \
+	  cmd_onenand.o \
 	  cmd_pci.o cmd_pcmcia.o cmd_portio.o \
 	  cmd_reginfo.o cmd_reiser.o cmd_sata.o cmd_scsi.o cmd_spi.o \
 	  cmd_universe.o cmd_usb.o cmd_vfd.o \
 	  command.o console.o cyclon2.o devices.o dlmalloc.o docecc.o \
 	  environment.o env_common.o \
 	  env_nand.o env_dataflash.o env_flash.o env_eeprom.o \
-	  env_nvram.o env_nowhere.o \
+	  env_onenand.o env_nvram.o env_nowhere.o \
 	  exports.o \
 	  fdt_support.o flash.o fpga.o ft_build.o \
 	  hush.o kgdb.o lcd.o lists.o lynxkdi.o \
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 1db0fc3..6770408 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -57,8 +57,9 @@ DECLARE_GLOBAL_DATA_PTR;
     !defined(CFG_ENV_IS_IN_FLASH)	&& \
     !defined(CFG_ENV_IS_IN_DATAFLASH)	&& \
     !defined(CFG_ENV_IS_IN_NAND)	&& \
+    !defined(CFG_ENV_IS_IN_ONENAND)	&& \
     !defined(CFG_ENV_IS_NOWHERE)
-# error Define one of CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|NOWHERE}
+# error Define one of CFG_ENV_IS_IN_{NVRAM|EEPROM|FLASH|DATAFLASH|ONENAND|NOWHERE}
 #endif
 
 #define XMK_STR(x)	#x
@@ -553,7 +554,8 @@ int getenv_r (char *name, char *buf, unsigned len)
 
 #if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) \
     || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_FLASH)) \
-    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND))
+    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND)) \
+    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND))
 int do_saveenv (cmd_tbl_t *cmdtp, int flag, int argc, char *argv[])
 {
 	extern char * env_name_spec;
@@ -608,7 +610,8 @@ U_BOOT_CMD(
 
 #if defined(CFG_ENV_IS_IN_NVRAM) || defined(CFG_ENV_IS_IN_EEPROM) \
     || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_FLASH)) \
-    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND))
+    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_NAND)) \
+    || (defined(CONFIG_CMD_ENV) && defined(CONFIG_CMD_ONENAND))
 U_BOOT_CMD(
 	saveenv, 1, 0,	do_saveenv,
 	"saveenv - save environment variables to persistent storage\n",
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c
new file mode 100644
index 0000000..257a614
--- /dev/null
+++ b/common/cmd_onenand.c
@@ -0,0 +1,201 @@
+/*
+ *  U-Boot command for OneNAND support
+ *
+ *  Copyright (C) 2005-2007 Samsung Electronics
+ *  Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * 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.
+ */
+
+#include <common.h>
+#include <command.h>
+
+#if (CONFIG_COMMANDS & CFG_CMD_ONENAND)
+
+#include <linux/mtd/onenand.h>
+
+extern struct mtd_info onenand_mtd;
+extern struct onenand_chip onenand_chip;
+
+int do_onenand (cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])
+{
+	int ret = 0;
+
+	switch (argc) {
+	case 0:
+	case 1:
+		printf ("Usage:\n%s\n", cmdtp->usage);
+		return 1;
+
+	case 2:
+		if (strncmp (argv[1], "open", 4) == 0) {
+			onenand_init ();
+			return 0;
+		}
+		onenand_print_device_info (onenand_chip.device_id, 1);
+		return 0;
+
+	default:
+		/* At least 4 args */
+		if (strncmp (argv[1], "erase", 5) == 0) {
+			struct erase_info instr;
+			ulong start, end;
+			char *endtail;
+			ulong block;
+
+			if (strncmp (argv[2], "block", 5) == 0) {
+				start = simple_strtoul (argv[3], NULL, 10);
+				endtail = strchr (argv[3], '-');
+				end = simple_strtoul (endtail + 1, NULL, 10);
+			} else {
+				start = simple_strtoul (argv[2], NULL, 10);
+				end = simple_strtoul (argv[3], NULL, 10);
+				start -= (unsigned long)onenand_chip.base;
+				end -= (unsigned long)onenand_chip.base;
+			}
+
+			if (!end || end < 0)
+				end = start;
+
+			printf ("Erase block from %d to %d\n", start, end);
+
+			for (block = start; block <= end; block++) {
+				instr.addr = block << onenand_chip.erase_shift;
+				instr.len = 1 << onenand_chip.erase_shift;
+				ret = onenand_erase (&onenand_mtd, &instr);
+				if (ret) {
+					printf ("erase failed %d\n", block);
+					break;
+				}
+			}
+
+			return 0;
+		}
+
+		if (strncmp (argv[1], "read", 4) == 0) {
+			ulong addr = simple_strtoul (argv[2], NULL, 16);
+			ulong ofs = simple_strtoul (argv[3], NULL, 16);
+			size_t len = simple_strtoul (argv[4], NULL, 16);
+			size_t retlen = 0;
+			int oob = strncmp (argv[1], "read.oob", 8) ? 0 : 1;
+
+			ofs -= (unsigned long)onenand_chip.base;
+
+			if (oob)
+				onenand_read_oob (&onenand_mtd, ofs, len,
+						  &retlen, (u_char *) addr);
+			else
+				onenand_read (&onenand_mtd, ofs, len, &retlen,
+					      (u_char *) addr);
+			printf ("Done\n");
+
+			return 0;
+		}
+
+		if (strncmp (argv[1], "write", 5) == 0) {
+			ulong addr = simple_strtoul (argv[2], NULL, 16);
+			ulong ofs = simple_strtoul (argv[3], NULL, 16);
+			size_t len = simple_strtoul (argv[4], NULL, 16);
+			size_t retlen = 0;
+
+			ofs -= (unsigned long)onenand_chip.base;
+
+			onenand_write (&onenand_mtd, ofs, len, &retlen,
+				       (u_char *) addr);
+			printf ("Done\n");
+
+			return 0;
+		}
+
+		if (strncmp (argv[1], "block", 5) == 0) {
+			ulong addr = simple_strtoul (argv[2], NULL, 16);
+			ulong block = simple_strtoul (argv[3], NULL, 10);
+			ulong page = simple_strtoul (argv[4], NULL, 10);
+			size_t len = simple_strtol (argv[5], NULL, 10);
+			size_t retlen = 0;
+			ulong ofs;
+			int oob = strncmp (argv[1], "block.oob", 9) ? 0 : 1;
+
+			ofs = block << onenand_chip.erase_shift;
+			if (page)
+				ofs += page << onenand_chip.page_shift;
+
+			if (!len) {
+				if (oob)
+					len = 64;
+				else
+					len = 512;
+			}
+
+			if (oob)
+				onenand_read_oob (&onenand_mtd, ofs, len,
+						  &retlen, (u_char *) addr);
+			else
+				onenand_read (&onenand_mtd, ofs, len, &retlen,
+					      (u_char *) addr);
+			return 0;
+		}
+
+		if (strncmp (argv[1], "unlock", 6) == 0) {
+			ulong start = simple_strtoul (argv[2], NULL, 10);
+			ulong ofs = simple_strtoul (argv[3], NULL, 10);
+
+			if (!ofs)
+				ofs = (1 << onenand_chip.erase_shift);
+
+			start = start << onenand_chip.erase_shift;
+#if 0
+			printk ("start = 0x%08x, ofs = 0x%08x\n", start, ofs);
+#endif
+			onenand_unlock (&onenand_mtd, start, start + ofs);
+
+			return 0;
+		}
+
+		if (strncmp (argv[1], "save", 4) == 0 &&
+		    strncmp (argv[2], "bootloader", 10) == 0) {
+			ulong addr = simple_strtoul (argv[3], NULL, 16);
+			struct erase_info instr;
+			int ofs = 0;
+			int len = 0x20000;
+			int retlen;
+
+			printf ("save bootloader...\n");
+
+			if (!addr)
+				break;
+
+			onenand_unlock (&onenand_mtd, ofs, len);
+
+			instr.addr = 0 << onenand_chip.erase_shift;
+			instr.len = 1 << onenand_chip.erase_shift;
+			onenand_erase (&onenand_mtd, &instr);
+
+			onenand_write (&onenand_mtd, ofs, len, &retlen,
+				       (u_char *) addr);
+			onenand_unlock (&onenand_mtd, CFG_ENV_ADDR,
+					onenand_mtd.size - CFG_ENV_ADDR);
+			return 0;
+		}
+
+		break;
+	}
+
+	return 0;
+}
+
+U_BOOT_CMD (onenand, 6, 1, do_onenand,
+	    "onenand - OneNAND sub-system\n",
+	    "info   - show available OneNAND devices\n"
+	    "onenand read[.oob] addr ofs len - read data at ofs with len to addr\n"
+	    "onenand write addr ofs len - write data at ofs with len from addr\n"
+	    "onenand erase block start-end - erase block from start to end\n"
+	    "onenand erase saddr eaddr - erase block start addr to end addr\n"
+	    "onenand block[.oob] addr block [page] [len] - "
+	    "read data with (block [, page]) to addr\n"
+	    "onenand unlock start-end - unlock block from start to end\n"
+	    "onenand save bootloader addr - save bootloader at addr\n");
+
+#endif				/* (CONFIG_COMMANDS & CFG_CMD_ONENAND) */
diff --git a/common/env_onenand.c b/common/env_onenand.c
new file mode 100644
index 0000000..2597d1e
--- /dev/null
+++ b/common/env_onenand.c
@@ -0,0 +1,133 @@
+/*
+ * (C) Copyright 2005-2007 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+
+#if defined(CFG_ENV_IS_IN_ONENAND)	/* Environment is in OneNAND */
+
+#include <command.h>
+#include <environment.h>
+#include <linux/stddef.h>
+#include <malloc.h>
+
+#include <linux/mtd/onenand.h>
+
+extern struct mtd_info onenand_mtd;
+extern struct onenand_chip onenand_chip;
+
+/* References to names in env_common.c */
+extern uchar default_environment[];
+
+#define ONENAND_ENV_SIZE(mtd)	(mtd.oobblock - ENV_HEADER_SIZE)
+
+char *env_name_spec = "OneNAND";
+
+#ifdef ENV_IS_EMBEDDED
+extern uchar environment[];
+env_t *env_ptr = (env_t *) (&environment[0]);
+#else				/* ! ENV_IS_EMBEDDED */
+static unsigned char onenand_env[MAX_ONENAND_PAGESIZE];
+env_t *env_ptr = (env_t *) onenand_env;
+#endif				/* ENV_IS_EMBEDDED */
+
+uchar env_get_char_spec (int index)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	return (*((uchar *) (gd->env_addr + index)));
+}
+
+void env_relocate_spec (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+	unsigned long env_addr;
+	int use_default = 0;
+	int retlen;
+
+	env_addr = CFG_ENV_ADDR;
+	env_addr -= (unsigned long)onenand_chip.base;
+
+	/* Check OneNAND exist */
+	if (onenand_mtd.oobblock)
+		/* Ignore read fail */
+		onenand_read (&onenand_mtd, env_addr, onenand_mtd.oobblock,
+			      &retlen, (u_char *) env_ptr);
+	else
+		onenand_mtd.oobblock = MAX_ONENAND_PAGESIZE;
+
+	if (crc32 (0, env_ptr->data, ONENAND_ENV_SIZE (onenand_mtd)) !=
+	    env_ptr->crc)
+		use_default = 1;
+
+	if (use_default) {
+		memcpy (env_ptr->data, default_environment,
+			ONENAND_ENV_SIZE (onenand_mtd));
+		env_ptr->crc =
+		    crc32 (0, env_ptr->data, ONENAND_ENV_SIZE (onenand_mtd));
+	}
+
+	gd->env_addr = (ulong) & env_ptr->data;
+	gd->env_valid = 1;
+}
+
+int saveenv (void)
+{
+	unsigned long env_addr = CFG_ENV_ADDR;
+	struct erase_info instr;
+	int retlen;
+
+	instr.len = CFG_ENV_SIZE;
+	instr.addr = env_addr;
+	instr.addr -= (unsigned long)onenand_chip.base;
+	if (onenand_erase (&onenand_mtd, &instr)) {
+		printf ("OneNAND: erase failed at 0x%08x\n", env_addr);
+		return 1;
+	}
+
+	/* update crc */
+	env_ptr->crc =
+	    crc32 (0, env_ptr->data, onenand_mtd.oobblock - ENV_HEADER_SIZE);
+
+	env_addr -= (unsigned long)onenand_chip.base;
+	if (onenand_write
+	    (&onenand_mtd, env_addr, onenand_mtd.oobblock, &retlen,
+	     (u_char *) env_ptr)) {
+		printf ("OneNAND: write failed at 0x%08x\n", instr.addr);
+		return 2;
+	}
+
+	return 0;
+}
+
+int env_init (void)
+{
+	DECLARE_GLOBAL_DATA_PTR;
+
+	/* use default */
+	gd->env_addr = (ulong) & default_environment[0];
+	gd->env_valid = 1;
+
+	return 0;
+}
+
+#endif				/* CFG_ENV_IS_IN_ONENAND */

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [U-Boot-Users] [PATCH 1/5] OneNAND support
  2007-09-07  0:57 [U-Boot-Users] [PATCH 1/5] OneNAND support Kyungmin Park
@ 2007-09-08 22:53 ` Wolfgang Denk
  2007-09-10  0:48   ` Kyungmin Park
  0 siblings, 1 reply; 4+ messages in thread
From: Wolfgang Denk @ 2007-09-08 22:53 UTC (permalink / raw)
  To: u-boot

In message <20070907005723.GA19727@party> you wrote:
> [PATCH] OneNAND support
> 
> This patch enables the OneNAND at U-boot

I cannot comment much on this code as I have no access to any hardware
with such a device, but here are a few formal comments:

> +U_BOOT_CMD (onenand, 6, 1, do_onenand,
> +	    "onenand - OneNAND sub-system\n",
> +	    "info   - show available OneNAND devices\n"
> +	    "onenand read[.oob] addr ofs len - read data at ofs with len to addr\n"
> +	    "onenand write addr ofs len - write data at ofs with len from addr\n"
> +	    "onenand erase block start-end - erase block from start to end\n"
> +	    "onenand erase saddr eaddr - erase block start addr to end addr\n"
> +	    "onenand block[.oob] addr block [page] [len] - "
> +	    "read data with (block [, page]) to addr\n"

This line is probably missing some additional indentation?

> +	    "onenand unlock start-end - unlock block from start to end\n"
> +	    "onenand save bootloader addr - save bootloader at addr\n");

I'm not happy with the parameter format of the "erase"  and  "unlock"
commands  -  using  an  address  specification  of "start-end" breaks
existing conventions in U-Boot. Please  use  two  separate  arguments
instead.

Also, I don;t see what  the  difference  between  "erase  block"  and
"erase"  is  -  can  we  avoid  "erase block" all together? If not, I
recommend to  change  it  into  "eraseblock"  (which  could  then  be
shortened to "eraseb") to avoid too different command formats.


After changing this, you have my ACK.

Thanks a lot.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
In the beginning there was nothing.
And the Lord said "Let There Be Light!"
And still there was nothing, but at least now you could see it.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [U-Boot-Users] [PATCH 1/5] OneNAND support
  2007-09-08 22:53 ` Wolfgang Denk
@ 2007-09-10  0:48   ` Kyungmin Park
  2007-09-10  6:59     ` Wolfgang Denk
  0 siblings, 1 reply; 4+ messages in thread
From: Kyungmin Park @ 2007-09-10  0:48 UTC (permalink / raw)
  To: u-boot

> > This patch enables the OneNAND at U-boot
> 
> I cannot comment much on this code as I have no access to any hardware
> with such a device, but here are a few formal comments:

After committing the OneNAND patch, I will post the Apollon board patches which uses the OneNAND.
> 
> > +U_BOOT_CMD (onenand, 6, 1, do_onenand,
> > +	    "onenand - OneNAND sub-system\n",
> > +	    "info   - show available OneNAND devices\n"
> > +	    "onenand read[.oob] addr ofs len - read data at ofs with len to addr\n"
> > +	    "onenand write addr ofs len - write data at ofs with len from addr\n"
> > +	    "onenand erase block start-end - erase block from start to end\n"
> > +	    "onenand erase saddr eaddr - erase block start addr to end addr\n"
> > +	    "onenand block[.oob] addr block [page] [len] - "
> > +	    "read data with (block [, page]) to addr\n"
> 
> This line is probably missing some additional indentation?

Yes, I add the tap indentation as nand does

> 
> > +	    "onenand unlock start-end - unlock block from start to end\n"
> > +	    "onenand save bootloader addr - save bootloader at addr\n");
> 
> I'm not happy with the parameter format of the "erase"  and  "unlock"
> commands  -  using  an  address  specification  of "start-end" breaks
> existing conventions in U-Boot. Please  use  two  separate  arguments
> instead.
> 
> Also, I don;t see what  the  difference  between  "erase  block"  and
> "erase"  is  -  can  we  avoid  "erase block" all together? If not, I
> recommend to  change  it  into  "eraseblock"  (which  could  then  be
> shortened to "eraseb") to avoid too different command formats.
> 

At code writing time, there are no strict rules to use address scheme, block scheme.
No problem, which one is used. Now temporally I removed it

Thank you,
Kyungmin Park

P.S. Now I just send the modified parts, after full comments, I will send it at once.

+U_BOOT_CMD(
+	onenand,	6,	1,	do_onenand,
+	"onenand - OneNAND sub-system\n",
+	"info   - show available OneNAND devices\n"
+	"onenand read[.oob] addr ofs len - read data at ofs with len to addr\n"
+	"onenand write addr ofs len - write data at ofs with len from addr\n"
+	"onenand erase saddr eaddr - erase block start addr to end addr\n"
+	"onenand block[.oob] addr block [page] [len] - "
+	"read data with (block [, page]) to addr\n"
+);

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [U-Boot-Users] [PATCH 1/5] OneNAND support
  2007-09-10  0:48   ` Kyungmin Park
@ 2007-09-10  6:59     ` Wolfgang Denk
  0 siblings, 0 replies; 4+ messages in thread
From: Wolfgang Denk @ 2007-09-10  6:59 UTC (permalink / raw)
  To: u-boot

Hello,

in message <002201c7f344$539d6c60$e1ac580a@swcenter.sec.samsung.co.kr> you wrote:
>
> P.S. Now I just send the modified parts, after full comments, I will send it at once.

OK - thanks!

> +U_BOOT_CMD(
> +	onenand,	6,	1,	do_onenand,
> +	"onenand - OneNAND sub-system\n",
> +	"info   - show available OneNAND devices\n"
> +	"onenand read[.oob] addr ofs len - read data at ofs with len to addr\n"
> +	"onenand write addr ofs len - write data at ofs with len from addr\n"
> +	"onenand erase saddr eaddr - erase block start addr to end addr\n"
> +	"onenand block[.oob] addr block [page] [len] - "
> +	"read data with (block [, page]) to addr\n"

Sorry for the nitpicking, but I recommend to make this:

> +	"onenand erase saddr eaddr - erase block start addr to end addr\n"
> +	"onenand block[.oob] addr block [page] [len] - "
> +		"read data with (block [, page]) to addr\n"

so it's clearly visible what that will look like. You may even use an
explicit continuation mark (trailing backslash) on the line before,
even though it's not necessary - just as a reminder for the reader.

Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd at denx.de
Unsichtbar macht sich die Dummheit, indem sie immer  gr??ere  Ausma?e
annimmt.                             -- Bertold Brecht: Der Tui-Roman

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-09-10  6:59 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-09-07  0:57 [U-Boot-Users] [PATCH 1/5] OneNAND support Kyungmin Park
2007-09-08 22:53 ` Wolfgang Denk
2007-09-10  0:48   ` Kyungmin Park
2007-09-10  6:59     ` Wolfgang Denk

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox