diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index 67de6bc..9c2db9f 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -90,12 +90,6 @@ static void load_gdt(const u64 *boot_gdt, u16 num_entries)
 	asm volatile("lgdtl %0\n" : : "m" (gdt));
 }
 
-void init_gd(gd_t *id, u64 *gdt_addr)
-{
-	id->gd_addr = id;
-	setup_gdt(id, gdt_addr);
-}
-
 void setup_gdt(gd_t *id, u64 *gdt_addr)
 {
 	/* CS: code, read/execute, 4 GB, base 0 */
diff --git a/arch/x86/cpu/start.S b/arch/x86/cpu/start.S
index ee0dabe..4842ff1 100644
--- a/arch/x86/cpu/start.S
+++ b/arch/x86/cpu/start.S
@@ -83,13 +83,33 @@ car_init_ret:
 	 * or fully initialised SDRAM - we really don't care which)
 	 * starting at CONFIG_SYS_CAR_ADDR to be used as a temporary stack
 	 */
-	movl	$CONFIG_SYS_INIT_SP_ADDR, %esp
 
-	/* Initialise the Global Data Pointer */
-	movl	$CONFIG_SYS_INIT_GD_ADDR, %eax
-	movl	%eax, %edx
-	addl	$GENERATED_GBL_DATA_SIZE, %edx
-	call	init_gd;
+	/* Stack grows down from top of CAR */
+	movl	$(CONFIG_SYS_CAR_ADDR + CONFIG_SYS_CAR_SIZE), %esp
+
+	/* Reserve space on stack for global data */
+	subl	$GENERATED_GBL_DATA_SIZE, %esp
+
+	/* Align global data to 16-byte boundary */
+	andl	$0xfffffff0, %esp
+
+	/* Setup first parameter to setup_gdt */
+	movl	%esp, %eax
+
+	/* Reserve space for global descriptor table */
+	subl	$X86_GDT_SIZE, %esp
+
+	/* Align temporary global descriptor table to 16-byte boundary */
+	andl	$0xfffffff0, %esp
+
+	/* Set second parameter to setup_gdt */
+	movl	%esp, %edx
+
+	/* gd->gd_addr = gd (Required to allow gd->xyz to work) */
+	movl	%eax, (%eax)
+
+	/* Setup global descriptor table so gd->xyz works */
+	call	setup_gdt
 
 	/* Set parameter to board_init_f() to boot flags */
 	xorl	%eax, %eax
@@ -113,9 +133,42 @@ board_init_f_r_trampoline:
 	 * %eax = Address of top of new stack
 	 */
 
-	/* Setup stack in RAM */
+	/* Stack grows down from top of SDRAM */
 	movl	%eax, %esp
 
+	/* Reserve space on stack for global data */
+	subl	$GENERATED_GBL_DATA_SIZE, %esp
+
+	/* Align global data to 16-byte boundary */
+	andl	$0xfffffff0, %esp
+
+	/* Setup first parameter to memcpy (and setup_gdt) */
+	movl	%esp, %eax
+
+	/* Setup second parameter to memcpy */
+	fs movl 0, %edx
+
+	/* Set third parameter to memcpy */
+	movl	$GENERATED_GBL_DATA_SIZE, %ecx
+
+	/* Copy global data from CAR to SDRAM stack */
+	call	memcpy
+
+	/* Reserve space for global descriptor table */
+	subl	$X86_GDT_SIZE, %esp
+
+	/* Align global descriptor table to 16-byte boundary */
+	andl	$0xfffffff0, %esp
+
+	/* Set second parameter to setup_gdt */
+	movl	%esp, %edx
+
+	/* gd->gd_addr = gd (Required to allow gd->xyz to work) */
+	movl	%eax, (%eax)
+
+	/* Setup global descriptor table so gd->xyz works */
+	call	setup_gdt
+
 	/* Re-enter U-Boot by calling board_init_f_r */
 	call	board_init_f_r
 
diff --git a/arch/x86/include/asm/global_data.h b/arch/x86/include/asm/global_data.h
index 8a8896e..c55543e 100644
--- a/arch/x86/include/asm/global_data.h
+++ b/arch/x86/include/asm/global_data.h
@@ -56,7 +56,6 @@ typedef	struct global_data {
 	unsigned long	relocaddr;	/* Start address of U-Boot in RAM */
 	unsigned long	start_addr_sp;	/* start_addr_stackpointer */
 	unsigned long	gdt_addr;	/* Location of GDT */
-	unsigned long	new_gd_addr;	/* New location of Global Data */
 	phys_size_t	ram_size;	/* RAM size */
 	unsigned long	reset_status;	/* reset status register at boot */
 	void		**jt;		/* jump table */
diff --git a/arch/x86/include/asm/init_helpers.h b/arch/x86/include/asm/init_helpers.h
index 192f18e..d11d35a 100644
--- a/arch/x86/include/asm/init_helpers.h
+++ b/arch/x86/include/asm/init_helpers.h
@@ -29,7 +29,6 @@ int display_dram_config(void);
 int init_baudrate_f(void);
 int calculate_relocation_address(void);
 
-int copy_gd_to_ram_f_r(void);
 int init_cache_f_r(void);
 
 int set_reloc_flag_r(void);
diff --git a/arch/x86/include/asm/processor.h b/arch/x86/include/asm/processor.h
index 6eb5180..17f27cb 100644
--- a/arch/x86/include/asm/processor.h
+++ b/arch/x86/include/asm/processor.h
@@ -41,6 +41,7 @@ enum {
 #else
 /* NOTE: If the above enum is modified, this define must be checked */
 #define X86_GDT_ENTRY_32BIT_DS	3
+#define X86_GDT_NUM_ENTRIES	7
 #endif
 
 #define X86_GDT_SIZE		(X86_GDT_NUM_ENTRIES * X86_GDT_ENTRY_SIZE)
diff --git a/arch/x86/lib/board.c b/arch/x86/lib/board.c
index 5f0b62c..100ac1e 100644
--- a/arch/x86/lib/board.c
+++ b/arch/x86/lib/board.c
@@ -36,6 +36,7 @@
 #include <stdio_dev.h>
 #include <asm/u-boot-x86.h>
 #include <asm/relocate.h>
+#include <asm/processor.h>
 
 #include <asm/init_helpers.h>
 #include <asm/init_wrappers.h>
@@ -121,7 +122,6 @@ init_fnc_t *init_sequence_f[] = {
  * initialise the CPU caches (to speed up the relocation process)
  */
 init_fnc_t *init_sequence_f_r[] = {
-	copy_gd_to_ram_f_r,
 	init_cache_f_r,
 	copy_uboot_to_ram,
 	clear_bss,
diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c
index 9f4dee0..d228906 100644
--- a/arch/x86/lib/init_helpers.c
+++ b/arch/x86/lib/init_helpers.c
@@ -83,18 +83,8 @@ int calculate_relocation_address(void)
 	 *       requirements
 	 */
 
-	/* Global Data is at top of available memory */
+	/* Stack is at top of available memory */
 	dest_addr = gd->ram_size;
-	dest_addr -= GENERATED_GBL_DATA_SIZE;
-	dest_addr &= ~15;
-	gd->new_gd_addr = dest_addr;
-
-	/* GDT is below Global Data */
-	dest_addr -= X86_GDT_SIZE;
-	dest_addr &= ~15;
-	gd->gdt_addr = dest_addr;
-
-	/* Stack is below GDT */
 	gd->start_addr_sp = dest_addr;
 
 	/* U-Boot is below the stack */
@@ -107,31 +97,6 @@ int calculate_relocation_address(void)
 	return 0;
 }
 
-int copy_gd_to_ram_f_r(void)
-{
-	gd_t *ram_gd;
-
-	/*
-	 * Global data is still in temporary memory (the CPU cache).
-	 * calculate_relocation_address() has set gd->new_gd_addr to
-	 * where the global data lives in RAM but getting it there
-	 * safely is a bit tricky due to the 'F-Segment Hack' that
-	 * we need to use for x86
-	 */
-	ram_gd = (gd_t *)gd->new_gd_addr;
-	memcpy((void *)ram_gd, gd, sizeof(gd_t));
-
-	/*
-	 * Reload the Global Descriptor Table so FS points to the
-	 * in-RAM copy of Global Data (calculate_relocation_address()
-	 * has already calculated the in-RAM location of the GDT)
-	 */
-	ram_gd->gd_addr = (ulong)ram_gd;
-	init_gd(ram_gd, (u64 *)gd->gdt_addr);
-
-	return 0;
-}
-
 int init_cache_f_r(void)
 {
 	/* Initialise the CPU cache(s) */
diff --git a/include/configs/eNET.h b/include/configs/eNET.h
index d5c9cad..3c6c6f1 100644
--- a/include/configs/eNET.h
+++ b/include/configs/eNET.h
@@ -169,16 +169,10 @@
 #define CONFIG_SYS_STACK_SIZE			(32 * 1024)
 #define CONFIG_SYS_CAR_ADDR			0x19200000
 #define CONFIG_SYS_CAR_SIZE			(16 * 1024)
-#define CONFIG_SYS_INIT_SP_ADDR			(CONFIG_SYS_CAR_ADDR + \
-						 CONFIG_SYS_CAR_SIZE)
 #define CONFIG_SYS_MONITOR_BASE			CONFIG_SYS_TEXT_BASE
 #define CONFIG_SYS_MONITOR_LEN			(256 * 1024)
 #define CONFIG_SYS_MALLOC_LEN			(CONFIG_ENV_SECT_SIZE + \
 						 128*1024)
-/* Address of temporary Global Data */
-#define CONFIG_SYS_INIT_GD_ADDR			CONFIG_SYS_CAR_ADDR
-
-
 /* allow to overwrite serial and ethaddr */
 #define CONFIG_ENV_OVERWRITE
 
