diff --git a/Makefile b/Makefile
index 3b339ad..9225a2d 100644
--- a/Makefile
+++ b/Makefile
@@ -274,13 +274,18 @@ NAND_SPL = nand_spl
 U_BOOT_NAND = $(obj)u-boot-nand.bin
 endif
 
+ifeq ($(CONFIG_ONENAND_U_BOOT),y)
+ONENAND_IPL = onenand_ipl
+U_BOOT_ONENAND = $(obj)u-boot-onenand.bin
+endif
+
 __OBJS := $(subst $(obj),,$(OBJS))
 __LIBS := $(subst $(obj),,$(LIBS))
 
 #########################################################################
 #########################################################################
 
-ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND)
+ALL += $(obj)u-boot.srec $(obj)u-boot.bin $(obj)System.map $(U_BOOT_NAND) $(U_BOOT_ONENAND)
 
 all:		$(ALL)
 
@@ -327,6 +332,12 @@ $(NAND_SPL):	$(VERSION_FILE)	$(obj)include/autoconf.mk
 $(U_BOOT_NAND):	$(NAND_SPL) $(obj)u-boot.bin $(obj)include/autoconf.mk
 		cat $(obj)nand_spl/u-boot-spl-16k.bin $(obj)u-boot.bin > $(obj)u-boot-nand.bin
 
+$(ONENAND_IPL):	$(VERSION_FILE)	$(obj)include/autoconf.mk
+		$(MAKE) -C onenand_ipl/board/$(BOARDDIR) all
+
+$(U_BOOT_ONENAND):	$(ONENAND_IPL) $(obj)u-boot.bin $(obj)include/autoconf.mk
+		cat $(obj)onenand_ipl/onenand-ipl-2k.bin $(obj)u-boot.bin > $(obj)u-boot-onenand.bin
+
 $(VERSION_FILE):
 		@( echo -n "#define U_BOOT_VERSION \"U-Boot " ; \
 		echo -n "$(U_BOOT_VERSION)" ; \
@@ -2597,7 +2608,9 @@ omap2420h4_config	: unconfig
 	@$(MKCONFIG) $(@:_config=) arm arm1136 omap2420h4
 
 apollon_config		: unconfig
+	@echo "#define CONFIG_ONENAND_U_BOOT" > $(obj)include/config.h
 	@$(MKCONFIG) $(@:_config=) arm arm1136 apollon
+	@echo "CONFIG_ONENAND_U_BOOT = y" >> $(obj)include/config.mk
 
 #========================================================================
 # i386
@@ -2898,6 +2911,8 @@ clean:
 	@rm -f $(obj)board/bf537-stamp/u-boot.lds $(obj)board/bf561-ezkit/u-boot.lds
 	@rm -f $(obj)include/bmp_logo.h
 	@rm -f $(obj)nand_spl/u-boot-spl $(obj)nand_spl/u-boot-spl.map
+	@rm -f $(obj)onenand_ipl/onenand-ipl $(obj)onenand_ipl/onenand-ipl.bin \
+		$(obj)onenand_ipl/onenand-ipl-2k.bin $(obj)onenand_ipl/onenand-ipl.map
 	@rm -f $(obj)api_examples/demo $(VERSION_FILE)
 
 clobber:	clean
@@ -2912,6 +2927,7 @@ clobber:	clean
 	@rm -f $(obj)tools/inca-swap-bytes $(obj)cpu/mpc824x/bedbug_603e.c
 	@rm -f $(obj)include/asm/proc $(obj)include/asm/arch $(obj)include/asm
 	@[ ! -d $(obj)nand_spl ] || find $(obj)nand_spl -lname "*" -print | xargs rm -f
+	@[ ! -d $(obj)onenand_ipl ] || find $(obj)onenand_ipl -lname "*" -print | xargs rm -f
 	@[ ! -d $(obj)api_examples ] || find $(obj)api_examples -lname "*" -print | xargs rm -f
 
 ifeq ($(OBJTREE),$(SRCTREE))
diff --git a/board/apollon/apollon.c b/board/apollon/apollon.c
index 064d143..383b064 100644
--- a/board/apollon/apollon.c
+++ b/board/apollon/apollon.c
@@ -440,7 +440,8 @@ void muxSetupTouchScreen(void)
 void muxSetupGPMC(void)
 {
 	/* gpmc_io_dir, MCR */
-	writel(0x4800008C, 0x19000000);
+	volatile unsigned int *MCR = (unsigned int *) 0x4800008C;
+	*MCR = 0x19000000;
 
 	/* NOR FLASH CS0 */
 	/* signal - Gpmc_clk; pin - J4; offset - 0x0088; mode 0; Byte-3 */
diff --git a/cpu/arm1136/start.S b/cpu/arm1136/start.S
index 17c7a83..8b765f1 100644
--- a/cpu/arm1136/start.S
+++ b/cpu/arm1136/start.S
@@ -35,6 +35,25 @@
 #endif
 .globl _start
 _start: b	reset
+#ifdef CONFIG_ONENAND_IPL
+	ldr	pc, _hang
+	ldr	pc, _hang
+	ldr	pc, _hang
+	ldr	pc, _hang
+	ldr	pc, _hang
+	ldr	pc, _hang
+	ldr	pc, _hang
+
+_hang:
+	.word	do_hang
+	.word	0x12345678
+	.word	0x12345678
+	.word	0x12345678
+	.word	0x12345678
+	.word	0x12345678
+	.word	0x12345678
+	.word	0x12345678	/* now 16*4=64 */
+#else
 	ldr	pc, _undefined_instruction
 	ldr	pc, _software_interrupt
 	ldr	pc, _prefetch_abort
@@ -51,6 +70,7 @@ _not_used:		.word not_used
 _irq:			.word irq
 _fiq:			.word fiq
 _pad:			.word 0x12345678 /* now 16*4=64 */
+#endif	/* CONFIG_ONENAND_IPL */
 .global _end_vect
 _end_vect:
 
@@ -139,7 +159,9 @@ relocate:				/* relocate U-Boot to RAM	    */
 	adr	r0, _start		/* r0 <- current position of code   */
 	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
 	cmp	r0, r1			/* don't reloc during debug	    */
+#ifndef CONFIG_ONENAND_IPL
 	beq	stack_setup
+#endif	/* CONFIG_ONENAND_IPL */
 
 	ldr	r2, _armboot_start
 	ldr	r3, _bss_start
@@ -156,26 +178,36 @@ copy_loop:
 	/* Set up the stack						    */
 stack_setup:
 	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
+#ifdef CONFIG_ONENAND_IPL
+	sub	sp, r0, #128		/* leave 32 words for abort-stack   */
+#else
 	sub	r0, r0, #CFG_MALLOC_LEN /* malloc area			    */
 	sub	r0, r0, #CFG_GBL_DATA_SIZE /* bdinfo			    */
 #ifdef CONFIG_USE_IRQ
 	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
 #endif
 	sub	sp, r0, #12		/* leave 3 words for abort-stack    */
+#endif	/* CONFIG_ONENAND_IPL */
 
 clear_bss:
 	ldr	r0, _bss_start		/* find start of bss segment	    */
 	ldr	r1, _bss_end		/* stop here			    */
 	mov	r2, #0x00000000		/* clear			    */
 
+#ifndef CONFIG_ONENAND_IPL
 clbss_l:str	r2, [r0]		/* clear loop...		    */
 	add	r0, r0, #4
 	cmp	r0, r1
 	bne	clbss_l
+#endif
 
 	ldr	pc, _start_armboot
 
+#ifdef CONFIG_ONENAND_IPL
+_start_armboot: .word start_oneboot
+#else
 _start_armboot: .word start_armboot
+#endif
 
 
 /*
@@ -214,6 +246,8 @@ cpu_init_crit:
 	bl	lowlevel_init	/* go setup pll,mux,memory */
 	mov	lr, ip		/* restore link */
 	mov	pc, lr		/* back to my caller */
+
+#ifndef CONFIG_ONENAND_IPL
 /*
  *************************************************************************
  *
@@ -326,10 +360,17 @@ cpu_init_crit:
 	.macro get_fiq_stack			@ setup FIQ stack
 	ldr	sp, FIQ_STACK_START
 	.endm
+#endif	/* CONFIG_ONENAND_IPL */
 
 /*
  * exception handlers
  */
+#ifdef CONFIG_ONENAND_IPL
+	.align	5
+do_hang:
+	ldr	sp, _TEXT_BASE			/* use 32 words about stack */
+	bl	hang				/* hang and never return */
+#else	/* !CONFIG_ONENAND IPL */
 	.align	5
 undefined_instruction:
 	get_bad_stack
@@ -415,3 +456,4 @@ rstctl:
 	.word	PM_RSTCTRL_WKUP
 
 #endif
+#endif	/* CONFIG_ONENAND_IPL */
diff --git a/onenand_ipl/board/apollon/Makefile b/onenand_ipl/board/apollon/Makefile
new file mode 100644
index 0000000..66a0959
--- /dev/null
+++ b/onenand_ipl/board/apollon/Makefile
@@ -0,0 +1,65 @@
+
+include $(TOPDIR)/config.mk
+include $(TOPDIR)/include/config.mk
+include $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/config.mk
+
+LDSCRIPT= $(TOPDIR)/onenand_ipl/board/$(BOARDDIR)/u-boot.onenand.lds
+LDFLAGS	= -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)
+AFLAGS	+= -DCONFIG_ONENAND_IPL
+CFLAGS	+= -DCONFIG_ONENAND_IPL
+OBJCLFAGS += --gap-fill=0x00
+
+SOBJS	= start.o low_levelinit.o # _memcpy32.o
+COBJS	= apollon.o onenand_read.o onenand_boot.o
+
+SRCS	:= $(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c))
+OBJS	:= $(addprefix $(obj),$(SOBJS) $(COBJS))
+__OBJS	:= $(SOBJS) $(COBJS)
+LNDIR	:= $(OBJTREE)/onenand_ipl/board/$(BOARDDIR)
+
+onenandobj	:= $(OBJTREE)/onenand_ipl/
+
+ALL	= $(onenandobj)onenand-ipl $(onenandobj)onenand-ipl.bin $(onenandobj)onenand-ipl-2k.bin
+
+all:	$(obj).depend $(ALL)
+
+$(onenandobj)onenand-ipl-2k.bin:	$(onenandobj)onenand-ipl
+	$(OBJCOPY) ${OBJCFLAGS} --pad-to=0x800 -O binary $< $@
+
+$(onenandobj)onenand-ipl.bin:	$(onenandobj)onenand-ipl
+	$(OBJCOPY) ${OBJCFLAGS} -O binary $< $@
+
+$(onenandobj)onenand-ipl:	$(OBJS)
+	cd $(LNDIR) && $(LD) $(LDFLAGS) $$UNDEF_SYM $(__OBJS) \
+		-Map $(onenandobj)onenand-ipl.map \
+		-o $(onenandobj)onenand-ipl
+
+# create symbolic links from common files
+
+# from cpu directory
+$(obj)start.S:
+	rm -f $(obj)start.S
+	ln -s $(SRCTREE)/cpu/$(CPU)/start.S $(obj)start.S
+
+# from onenand_ipl directory
+$(obj)onenand_ipl.h:
+	rm -f $(obj)onenand_ipl.h
+	ln -s $(SRCTREE)/onenand_ipl/onenand_ipl.h $(obj)onenand_ipl.h
+
+$(obj)onenand_boot.c:	$(obj)onenand_ipl.h
+	rm -f $(obj)onenand_boot.c
+	ln -s $(SRCTREE)/onenand_ipl/onenand_boot.c $(obj)onenand_boot.c
+
+$(obj)onenand_read.c:	$(obj)onenand_ipl.h
+	rm -f $(obj)onenand_read.c
+	ln -s $(SRCTREE)/onenand_ipl/onenand_read.c $(obj)onenand_read.c
+
+$(obj)%.o:	$(obj)%.S
+	$(CC) $(AFLAGS) -c -o $@ $<
+
+$(obj)%.o:	$(obj)$.c
+	$(CC) $(CFLAGS) -c -o $@ $<
+
+include $(SRCTREE)/rules.mk
+
+sinclude $(obj).depend
diff --git a/onenand_ipl/board/apollon/apollon.c b/onenand_ipl/board/apollon/apollon.c
new file mode 100644
index 0000000..acf5c29
--- /dev/null
+++ b/onenand_ipl/board/apollon/apollon.c
@@ -0,0 +1,70 @@
+/*
+ * (C) Copyright 2005-2008 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>
+#include <asm/arch/mux.h>
+
+#define write_config_reg(reg, value)                                    \
+do {                                                                    \
+	writeb(value, reg);                                             \
+} while (0)
+
+/*****************************************
+ * Routine: board_init
+ * Description: Early hardware init.
+ *****************************************/
+int board_init(void)
+{
+	return 0;
+}
+
+#ifdef CFG_PRINTF
+/* Pin Muxing registers used for UART1 */
+/****************************************
+ * Routine: muxSetupUART1  (ostboot)
+ * Description: Set up uart1 muxing
+ *****************************************/
+static void muxSetupUART1(void)
+{
+	/* UART1_CTS pin configuration, PIN = D21 */
+	write_config_reg(CONTROL_PADCONF_UART1_CTS, 0);
+	/* UART1_RTS pin configuration, PIN = H21 */
+	write_config_reg(CONTROL_PADCONF_UART1_RTS, 0);
+	/* UART1_TX pin configuration, PIN = L20 */
+	write_config_reg(CONTROL_PADCONF_UART1_TX, 0);
+	/* UART1_RX pin configuration, PIN = T21 */
+	write_config_reg(CONTROL_PADCONF_UART1_RX, 0);
+}
+#endif
+
+/**********************************************************
+ * Routine: s_init
+ * Description: Does early system init of muxing and clocks.
+ * - Called at time when only stack is available.
+ **********************************************************/
+int s_init(int skip)
+{
+#ifdef CFG_PRINTF
+	muxSetupUART1();
+#endif
+	return 0;
+}
diff --git a/onenand_ipl/board/apollon/config.mk b/onenand_ipl/board/apollon/config.mk
new file mode 100644
index 0000000..fd9c506
--- /dev/null
+++ b/onenand_ipl/board/apollon/config.mk
@@ -0,0 +1,14 @@
+#
+# (C) Copyright 2005-2008 Samsung Electronics
+# Kyungmin Park <kyungmin.park@samsung.com>
+#
+# Samsung Apollon board with OMAP2420 (ARM1136) cpu
+#
+# Apollon has 1 bank of 128MB mDDR-SDRAM on CS0
+# Physical Address:
+# 8000'0000 (bank0)
+# 8800'0000 (bank1)
+# Linux-Kernel is expected to be at 8000'8000, entry 8000'8000
+# (mem base + reserved)
+
+TEXT_BASE = 0x00000000
diff --git a/onenand_ipl/board/apollon/low_levelinit.S b/onenand_ipl/board/apollon/low_levelinit.S
new file mode 100644
index 0000000..417a5a7
--- /dev/null
+++ b/onenand_ipl/board/apollon/low_levelinit.S
@@ -0,0 +1,205 @@
+/*
+ * Board specific setup info
+ *
+ * (C) Copyright 2005-2008 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Derived from board/omap2420h4/platform.S
+ *
+ * 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 <config.h>
+#include <asm/arch/omap2420.h>
+#include <asm/arch/mem.h>
+#include <asm/arch/clocks.h>
+
+#define APOLLON_CS0_BASE	0x00000000
+
+#ifdef PRCM_CONFIG_I
+#define SDRC_ACTIM_CTRLA_0_VAL	0x7BA35907
+#define SDRC_ACTIM_CTRLB_0_VAL	0x00000013
+#define SDRC_RFR_CTRL_0_VAL	0x00044C01
+
+/* GPMC */
+#define APOLLON_GPMC_CONFIG1_0	0xe30d1201
+#define APOLLON_GPMC_CONFIG2_0	0x000c1000
+#define APOLLON_GPMC_CONFIG3_0	0x00030400
+#define APOLLON_GPMC_CONFIG4_0	0x0B841006
+#define APOLLON_GPMC_CONFIG5_0	0x020F0C11
+#define APOLLON_GPMC_CONFIG6_0	0x00000000
+#define APOLLON_GPMC_CONFIG7_0	(0x00000e40 | (APOLLON_CS0_BASE >> 24))
+
+#elif defined(PRCM_CONFIG_II)
+#define SDRC_ACTIM_CTRLA_0_VAL	0x4A59B485
+#define SDRC_ACTIM_CTRLB_0_VAL	0x0000000C
+#define SDRC_RFR_CTRL_0_VAL	0x00030001
+
+/* GPMC */
+#define APOLLON_GPMC_CONFIG1_0	0xe30d1201
+#define APOLLON_GPMC_CONFIG2_0	0x00080E81
+#define APOLLON_GPMC_CONFIG3_0	0x00030400
+#define APOLLON_GPMC_CONFIG4_0	0x08041586
+#define APOLLON_GPMC_CONFIG5_0	0x020C090E
+#define APOLLON_GPMC_CONFIG6_0	0x00000000
+#define APOLLON_GPMC_CONFIG7_0	(0x00000e40 | (APOLLON_CS0_BASE >> 24))
+
+#else
+#error "Please configure PRCM schecm"
+#endif
+
+_TEXT_BASE:
+	.word	TEXT_BASE	/* sdram load addr from config.mk */
+
+.globl lowlevel_init
+lowlevel_init:
+	mov r3, r0     /* save skip information */
+
+	/* Disable watchdog */
+	ldr	r0, =WD2_BASE
+	ldr	r1, =WD_UNLOCK1
+	str	r1, [r0, #WSPR]
+
+	ldr	r1, =WD_UNLOCK2
+	str	r1, [r0, #WSPR]
+
+#ifdef DEBUG_LED
+	/* LED0 OFF */
+	ldr	r0, =0x480000E5		/* ball AA10, mode 3 */
+	mov	r1, #0x0b
+	strb	r1, [r0]
+#endif
+
+	/* Pin muxing for SDRC */
+	mov	r1, #0x00
+	ldr	r0, =0x480000A1		/* ball C12, mode 0 */
+	strb	r1, [r0]
+
+	ldr	r0, =0x48000032		/* ball D11, mode 0 */
+	strb	r1, [r0]
+
+	ldr	r0, =0x480000A3		/* ball B13, mode 0 */
+	strb	r1, [r0]
+
+	/* SDRC setting */
+	ldr	r0, =OMAP2420_SDRC_BASE
+	ldr	r1, =0x00000010
+	str	r1, [r0, #0x10]
+
+	ldr	r1, =0x00000100
+	str	r1, [r0, #0x44]
+
+	/* SDRC CS0 configuration */
+#ifdef CONFIG_APOLLON_PLUS
+	ldr	r1, =0x01702011
+#else
+	ldr	r1, =0x00d04011
+#endif
+	str	r1, [r0, #0x80]
+
+	ldr	r1, =SDRC_ACTIM_CTRLA_0_VAL
+	str	r1, [r0, #0x9C]
+
+	ldr	r1, =SDRC_ACTIM_CTRLB_0_VAL
+	str	r1, [r0, #0xA0]
+
+	ldr	r1, =SDRC_RFR_CTRL_0_VAL
+	str	r1, [r0, #0xA4]
+
+	ldr	r1, =0x00000041
+	str	r1, [r0, #0x70]
+
+	/* Manual command sequence */
+	ldr	r1, =0x00000007
+	str	r1, [r0, #0xA8]
+
+	ldr	r1, =0x00000000
+	str	r1, [r0, #0xA8]
+
+	ldr	r1, =0x00000001
+	str	r1, [r0, #0xA8]
+
+	ldr	r1, =0x00000002
+	str	r1, [r0, #0xA8]
+	str	r1, [r0, #0xA8]
+
+	/*
+	 * CS0 SDRC Mode register
+	 *   Burst length = 4 - DDR memory
+	 *   Serial mode
+	 *   CAS latency = 3
+	 */
+	ldr	r1, =0x00000032
+	str	r1, [r0, #0x84]
+
+	/* Note: You MUST set EMR values */
+	/* EMR1 & EMR2 */
+	ldr	r1, =0x00000000
+	str	r1, [r0, #0x88]
+	str	r1, [r0, #0x8C]
+
+#ifdef OLD_SDRC_DLLA_CTRL
+	/* SDRC_DLLA_CTRL */
+	ldr	r1, =0x00007306
+	str	r1, [r0, #0x60]
+
+	ldr	r1, =0x00007303
+	str	r1, [r0, #0x60]
+#else
+	/* SDRC_DLLA_CTRL */
+	ldr	r1, =0x00000506
+	str	r1, [r0, #0x60]
+
+	ldr	r1, =0x00000503
+	str	r1, [r0, #0x60]
+#endif
+
+#ifdef __BROKEN_FEATURE__
+	/* SDRC_DLLB_CTRL */
+	ldr	r1, =0x00000506
+	str	r1, [r0, #0x68]
+
+	ldr	r1, =0x00000503
+	str	r1, [r0, #0x68]
+#endif
+
+	/* little delay after init */
+	mov	r2, #0x1800
+1:
+	subs	r2, r2, #0x1
+        bne	1b
+
+	ldr	sp, SRAM_STACK
+        str     ip, [sp]	/* stash old link register */
+	mov	ip, lr		/* save link reg across call */
+        mov     r0, r3		/* pass skip info to s_init */
+
+        bl      s_init		/* go setup pll,mux,memory */
+
+        ldr     ip, [sp]	/* restore save ip */
+	mov	lr, ip		/* restore link reg */
+
+	/* back to arch calling code */
+	mov	pc,	lr
+
+	/* the literal pools origin */
+	.ltorg
+
+SRAM_STACK:
+	.word LOW_LEVEL_SRAM_STACK
diff --git a/onenand_ipl/board/apollon/u-boot.onenand.lds b/onenand_ipl/board/apollon/u-boot.onenand.lds
new file mode 100644
index 0000000..559f9f2
--- /dev/null
+++ b/onenand_ipl/board/apollon/u-boot.onenand.lds
@@ -0,0 +1,53 @@
+/*
+ * (C) Copyright 2005-2008 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Derived from X-loader
+ *
+ * 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
+ */
+
+OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+	. = 0x00000000;
+
+	. = ALIGN(4);
+	.text      :
+	{
+	  start.o	(.text)
+	  *(.text)
+	}
+
+	. = ALIGN(4);
+	.rodata : { *(.rodata) }
+
+	. = ALIGN(4);
+	.data : { *(.data) }
+
+	. = ALIGN(4);
+	.got : { *(.got) }
+
+	. = ALIGN(4);
+	__bss_start = .;
+	.bss : { *(.bss) }
+	_end = .;
+}
diff --git a/onenand_ipl/onenand_boot.c b/onenand_ipl/onenand_boot.c
new file mode 100644
index 0000000..f30deae
--- /dev/null
+++ b/onenand_ipl/onenand_boot.c
@@ -0,0 +1,81 @@
+/*
+ * (C) Copyright 2005-2008 Samsung Electronics
+ * Kyungmin Park <kyungmin.park@samsung.com>
+ *
+ * Derived from x-loader
+ *
+ * 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>
+#include <version.h>
+
+#include "onenand_ipl.h"
+
+#ifdef CFG_PRINTF
+int print_info(void)
+{
+	printf(XLOADER_VERSION);
+
+	return 0;
+}
+#endif
+
+typedef int (init_fnc_t)(void);
+
+init_fnc_t *init_sequence[] = {
+	board_init,		/* basic board dependent setup */
+#ifdef CFG_PRINTF
+	serial_init,		/* serial communications setup */
+	print_info,
+#endif
+	NULL,
+};
+
+void start_oneboot(void)
+{
+	init_fnc_t **init_fnc_ptr;
+	uchar *buf;
+
+	for (init_fnc_ptr = init_sequence; *init_fnc_ptr; ++init_fnc_ptr) {
+		if ((*init_fnc_ptr)() != 0)
+			hang();
+	}
+
+	buf = (uchar *) CFG_LOAD_ADDR;
+
+	if (!onenand_read_block(buf, ONENAND_START_BLOCK))
+		buf += ONENAND_BLOCK_SIZE;
+
+	if (buf == (uchar *)CFG_LOAD_ADDR)
+		hang();
+
+	/* go run U-Boot and never return */
+	printf("Starting OS Bootloader...\n");
+	((init_fnc_t *)CFG_LOAD_ADDR)();
+
+	/* should never come here */
+}
+
+void hang(void)
+{
+	/* if board_hang() returns, hange here */
+	printf("X-Loader hangs\n");
+	for (;;);
+}
diff --git a/onenand_ipl/onenand_ipl.h b/onenand_ipl/onenand_ipl.h
new file mode 100644
index 0000000..b9c6669
--- /dev/null
+++ b/onenand_ipl/onenand_ipl.h
@@ -0,0 +1,44 @@
+/*
+ * (C) Copyright 2005-2008 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 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
+ */
+
+#ifndef _ONENAND_IPL_H
+#define _ONENAND_IPL_H
+
+#include <linux/mtd/onenand_regs.h>
+
+#define ONENAND_START_BLOCK             0
+#define ONENAND_BLOCK_SIZE              2048
+
+#ifndef CFG_PRINTF
+#define printf(format, args...)
+#endif
+
+#define onenand_readw(a)        readw(a)
+#define onenand_writew(v, a)    writew(v, a)
+
+#define THIS_ONENAND(a)         (CFG_ONENAND_BASE + (a))
+
+#define READ_INTERRUPT()                                                \
+	onenand_readw(THIS_ONENAND(ONENAND_REG_INTERRUPT))
+
+#define ONENAND_PAGE_SIZE                       2048
+
+extern int onenand_read_block(unsigned char *buf, ulong block);
+#endif
diff --git a/onenand_ipl/onenand_read.c b/onenand_ipl/onenand_read.c
new file mode 100644
index 0000000..f553220
--- /dev/null
+++ b/onenand_ipl/onenand_read.c
@@ -0,0 +1,105 @@
+/*
+ * (C) Copyright 2005-2008 Samsung Electronis
+ * 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>
+
+#include <asm/io.h>
+#include <asm/string.h>
+
+#include "onenand_ipl.h"
+
+#define onenand_block_address(block)		(block)
+#define onenand_sector_address(page)		(page << 2)
+#define onenand_buffer_address()		((1 << 3) << 8)
+#define onenand_bufferram_address(block)	(0)
+
+/* read a page with ECC */
+static inline int onenand_read_page(ulong block, ulong page, u_char *buf)
+{
+	unsigned long *base;
+
+#ifndef __HAVE_ARCH_MEMCPY32
+	unsigned int offset, value;
+	unsigned long *p;
+#endif
+
+	onenand_writew(onenand_block_address(block),
+		THIS_ONENAND(ONENAND_REG_START_ADDRESS1));
+
+	onenand_writew(onenand_sector_address(page),
+		THIS_ONENAND(ONENAND_REG_START_ADDRESS8));
+
+	onenand_writew(onenand_buffer_address(),
+		THIS_ONENAND(ONENAND_REG_START_BUFFER));
+
+	onenand_writew(onenand_bufferram_address(block),
+		THIS_ONENAND(ONENAND_REG_START_ADDRESS2));
+
+	onenand_writew(ONENAND_INT_CLEAR, THIS_ONENAND(ONENAND_REG_INTERRUPT));
+
+	onenand_writew(ONENAND_CMD_READ, THIS_ONENAND(ONENAND_REG_COMMAND));
+
+#ifndef __HAVE_ARCH_MEMCPY32
+	p = (unsigned long *) buf;
+#endif
+	base = (unsigned long *) (CFG_ONENAND_BASE + ONENAND_DATARAM);
+
+	while (!(READ_INTERRUPT() & ONENAND_INT_READ))
+		continue;
+
+#ifdef __HAVE_ARCH_MEMCPY32
+	/* 32 bytes boundary memory copy */
+	memcpy32(buf, base, ONENAND_PAGE_SIZE);
+#else
+	for (offset = 0; offset < (ONENAND_PAGE_SIZE >> 2); offset++) {
+		value = *(base + offset);
+		*p++ = value;
+	}
+#endif
+
+	return 0;
+}
+
+#define ONENAND_START_PAGE		1
+#define ONENAND_PAGES_PER_BLOCK		64
+
+/**
+ * onenand_read_block - Read a block data to buf
+ * @return 0 on success
+ */
+int onenand_read_block(unsigned char *buf, ulong block)
+{
+	int page, offset = 0;
+
+	/* NOTE: you must read page from page 1 of block 0 */
+	/* read the block page by page*/
+	for (page = ONENAND_START_PAGE;
+	    page < ONENAND_PAGES_PER_BLOCK; page++) {
+
+		onenand_read_page(block, page, buf + offset);
+
+		offset += ONENAND_PAGE_SIZE;
+	}
+
+	return 0;
+}