+/*
+ * Load U-Boot into RAM, initialize BSS, perform relocation adjustments
+ */
+void board_init_f (ulong stack_limit)
+{
+ void *text_start = &_i386boot_text_start;
+ void *u_boot_cmd_end = &__u_boot_cmd_end;
+ Elf32_Rel *rel_dyn_start = (Elf32_Rel *)&_i386boot_rel_dyn_start;
+ Elf32_Rel *rel_dyn_end = (Elf32_Rel *)&_i386boot_rel_dyn_end;
+ void *bss_start = &_i386boot_bss_start;
+ void *bss_size = &_i386boot_bss_size;
+
+ size_t uboot_size;
+ void *ram_start;
+ ulong rel_offset;
+ Elf32_Rel *re;
+
+ void (*start_func)(void *);
+
+ /* compiler optimization barrier needed for GCC >= 3.4 */
+ __asm__ __volatile__("": : :"memory");
+
+ uboot_size = (size_t)u_boot_cmd_end - (size_t)text_start;
+ ram_start = (void *)stack_limit - (uboot_size + (ulong)bss_size);
+ rel_offset = text_start - ram_start;
+ start_func = ram_bootstrap - rel_offset;
+
+ /* First stage CPU initialization */
+ if (cpu_init_f() != 0)
+ hang();
+
+ /* First stage Board initialization */
+ if (board_early_init_f() != 0)
+ hang();
+
+ /* Copy U-Boot into RAM */
+ memcpy(ram_start, text_start, (size_t)uboot_size);
+
+ /* Clear BSS */
+ memset(bss_start - rel_offset, 0, (size_t)bss_size);
+
+ /* Perform relocation adjustments */
+ for (re = rel_dyn_start; re < rel_dyn_end; re++)
+ {
+ if (re->r_offset >= TEXT_BASE)
+ if (*(ulong *)re->r_offset >= TEXT_BASE)
+ *(ulong *)(re->r_offset - rel_offset) -= (Elf32_Addr)rel_offset;
+ }
+
+ start_func(ram_start);
+
+ /* NOTREACHED - relocate_code() does not return */
+ while(1);
+}
+
+/*
+ * All attempts to jump straight from board_init_f() to board_init_r()
+ * have failed, hence this special 'bootstrap' function.
+ */
+void ram_bootstrap (void *ram_start)
+{
+ static gd_t gd_data;
+
+ /* compiler optimization barrier needed for GCC >= 3.4 */
+ __asm__ __volatile__("": : :"memory");
+
+ board_init_r(&gd_data, (ulong)ram_start);
+}
+
+void board_init_r(gd_t *id, ulong ram_start)