=== modified file 'Makefile.util.def'
--- Makefile.util.def	2013-03-24 13:03:12 +0000
+++ Makefile.util.def	2013-03-24 13:03:31 +0000
@@ -467,6 +467,7 @@
   enable = mips_loongson;
   enable = ia64_efi;
   enable = powerpc_ieee1275;
+  enable = arm_uboot;
 };
 
 script = {

=== modified file 'grub-core/Makefile.am'
--- grub-core/Makefile.am	2013-03-20 16:13:31 +0000
+++ grub-core/Makefile.am	2013-03-24 13:03:31 +0000
@@ -211,6 +211,13 @@
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
 endif
 
+if COND_arm_uboot
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/uboot.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/uboot/disk.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+endif
+
 if COND_emu
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/datetime.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/emu/misc.h

=== modified file 'grub-core/Makefile.core.def'
--- grub-core/Makefile.core.def	2013-03-24 13:03:12 +0000
+++ grub-core/Makefile.core.def	2013-03-24 13:03:31 +0000
@@ -79,6 +79,7 @@
   mips_startup = kern/mips/startup.S;
   sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
   powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
+  arm_uboot_startup = kern/arm/uboot/startup.S;
 
   common = kern/command.c;
   common = kern/corecmd.c;

=== added directory 'grub-core/kern/arm/uboot'
=== added file 'grub-core/kern/arm/uboot/startup.S'
--- grub-core/kern/arm/uboot/startup.S	1970-01-01 00:00:00 +0000
+++ grub-core/kern/arm/uboot/startup.S	2013-03-24 13:03:31 +0000
@@ -0,0 +1,176 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013  Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/offsets.h>
+#include <grub/symbol.h>
+#include <grub/machine/kernel.h>
+
+/*
+ * GRUB is called from U-Boot as a Linux Kernel type image, which
+ * means among other things that it always enters in ARM state.
+ *
+ *
+ * Overview of GRUB image layout:
+ *
+ * _start:
+ *              Entry point (1 ARM branch instruction, to "codestart")
+ * grub_total_module_size:
+ *              Data field: Size of included module blob
+ *              (when generated by grub-mkimage)
+ * codestart:
+ *              Remainder of statically-linked executable code and data.
+ * __bss_start:
+ *              Start of included module blob.
+ *              Also where global/static variables are located.
+ * _end:
+ *              End of bss region (but not necessarily module blob).
+ * <overflow>:
+ *              Any part of the module blob that extends beyond _end.
+ * <modules>:
+ *              Loadable modules, post relocation.
+ * <stack>:     
+ * <heap>:
+ */
+	
+	.text
+	.arm
+FUNCTION(_start)
+	b	codestart
+	
+	@ Size of final image integrated module blob - set by grub-mkimage
+	. = _start + GRUB_KERNEL_MACHINE_TOTAL_MODULE_SIZE
+VARIABLE(grub_total_module_size)
+	.long 	0
+
+FUNCTION(codestart)
+	@ Store context: Machine ID, atags/dtb, ...
+	@ U-Boot API signature is stored on the U-Boot heap
+	@ Stack pointer used as start address for signature probing
+	mov	r12, sp
+	ldr	sp, =entry_state
+	push	{r4-r12,lr}	@ store U-Boot context (sp in r12)
+
+	@ Put kernel parameters aside until we can store them (further down)
+	mov	r4, r1		@ machine type
+	mov	r5, r2		@ boot data
+
+	@ Modules have been stored as a blob in BSS,
+	@ they need to be manually relocated to _end or
+	@ (__bss_start + grub_total_module_size), whichever greater.
+	bl	uboot_get_real_bss_start	@ r0 = src
+	ldr	r1, =EXT_C(_end)		@ dst = End of BSS
+	ldr	r2, grub_total_module_size	@ blob size
+	add	r3, r0, r2			@ blob end
+	cmp	r1, r3				@ _end < blob end?
+	movlt	r1, r3				@ dst = blob end + blob size
+	
+1:	ldr	r3, [r0], #4 			@ r3 = *src++ 
+	str	r3, [r1], #4			@ *dst++ = r3 
+	subs	r2, #4				@ remaining -= 4
+	bne	1b				@ while remaining != 0
+	
+	@ Set up a new stack, beyond the end of copied modules.
+	ldr	r3, =GRUB_KERNEL_MACHINE_STACK_SIZE
+	add	r3, r1, r3	@ Place stack beyond end of modules
+	and	sp, r3, #~0x7	@ Ensure 8-byte alignment
+
+	@ Since we _are_ the C run-time, we need to manually zero the BSS
+	@ region before continuing
+	bl	uboot_get_real_bss_start	@ zero from here
+	ldr	r1, =EXT_C(_end)		@ to here
+	mov	r2, #0
+1:	str	r2, [r0], #4
+	cmp	r0, r1
+	bne	1b
+
+	@ Global variables now accessible - store kernel parameters in memory
+	ldr     r12, =EXT_C(uboot_machine_type)
+	str     r4, [r12]
+	ldr     r12, =EXT_C(uboot_boot_data)
+	str     r5, [r12]
+	
+	b	EXT_C(grub_main)
+
+	/*
+	 * __bss_start does not actually point to the start of the runtime
+	 * BSS, but rather to the next byte following the preceding data.
+	 */
+FUNCTION (uboot_get_real_bss_start)
+	ldr	r0, =EXT_C(__bss_start)		@ src
+	tst	r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
+	beq	1f
+	mvn	r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
+	and	r0, r0, r1
+	add	r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN)
+1:	bx	lr
+
+	/*
+	 * uboot_syscall():
+	 *   This function is effectively a veneer, so it cannot
+	 *   modify the stack or corrupt any registers other than
+	 *   r12 (ip). Furthermore it needs to restore r8 for
+	 *   U-Boot (Global Data Pointer) and preserve it for Grub.
+	 */
+FUNCTION(uboot_syscall)
+	ldr	ip, =transition_space
+	stm	ip, {r8, lr}
+	ldr	ip, =gd_backup
+	ldr	r8, [ip]
+	ldr	ip, =uboot_syscall_ptr
+	mov	lr, pc
+	ldr	pc, [ip]
+	ldr	ip, =gd_backup
+	str	r8, [ip]
+	ldr	ip, =transition_space
+	ldm	ip, {r8, lr}
+	bx	lr
+	
+FUNCTION(uboot_return)
+	ldr	sp, =entry_state_end
+	pop	{r4-r12, lr}
+	mov	sp, r12
+	bx	lr
+
+	
+	.data
+	.align	3	@ 8-byte alignment for stack
+@ U-boot context stack space
+entry_state_end:	
+	.long	0	@ r4
+	.long	0	@ r5
+	.long	0	@ r6
+	.long	0	@ r7
+gd_backup:	
+	.long	0	@ r8 - U-Boot global data pointer
+	.long	0	@ r9
+	.long	0	@ r10
+	.long	0	@ r11
+VARIABLE(uboot_search_hint)@ U-Boot stack pointer - 
+	.long	0	@ also API signature address hint.
+	.long	0	@ lr
+entry_state:		@ backup for U-Boot context
+
+@ GRUB context stack space
+transition_space:	
+	.long	0	@ r8
+	.long	0	@ lr
+
+VARIABLE(uboot_syscall_ptr)
+	.long	0	@
+
+	.end

=== added directory 'include/grub/arm/uboot'
=== added file 'include/grub/arm/uboot/kernel.h'
--- include/grub/arm/uboot/kernel.h	1970-01-01 00:00:00 +0000
+++ include/grub/arm/uboot/kernel.h	2013-03-24 13:03:31 +0000
@@ -0,0 +1,32 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2013 Free Software Foundation, Inc.
+ *
+ *  GRUB 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 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_KERNEL_MACHINE_HEADER
+#define GRUB_KERNEL_MACHINE_HEADER	1
+
+#ifndef ASM_FILE
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+#endif /* ! ASM_FILE */
+
+#define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000
+#define GRUB_KERNEL_MACHINE_HEAP_SIZE  (grub_size_t) (2 * 1024 * 1024)
+
+#endif /* ! GRUB_KERNEL_MACHINE_HEADER */

=== modified file 'include/grub/offsets.h'
--- include/grub/offsets.h	2013-03-07 07:17:24 +0000
+++ include/grub/offsets.h	2013-03-24 13:03:31 +0000
@@ -103,6 +103,7 @@
 #define GRUB_KERNEL_I386_IEEE1275_MOD_GAP 0x0
 #define GRUB_KERNEL_I386_COREBOOT_MOD_GAP 0x0
 #define GRUB_KERNEL_SPARC64_IEEE1275_MOD_GAP 0x0
+#define GRUB_KERNEL_ARM_UBOOT_MOD_GAP 0x0
 
 #define GRUB_KERNEL_POWERPC_IEEE1275_MOD_ALIGN 0x1000
 #define GRUB_KERNEL_SPARC64_IEEE1275_MOD_ALIGN 0x1
@@ -111,6 +112,10 @@
 #define GRUB_KERNEL_MIPS_ARC_MOD_ALIGN 0x1
 #define GRUB_KERNEL_MIPS_QEMU_MIPS_MOD_ALIGN 0x1
 
+#define GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN 	0x8
+#define GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE	0x4
+#define GRUB_KERNEL_ARM_UBOOT_LINK_ADDR		0x08000000
+
 /* Minimal gap between _end and the start of the modules.  It's a hack
    for PowerMac to prevent "CLAIM failed" error.  The real fix is to
    rewrite grub-mkimage to generate valid ELF files.  */

=== modified file 'util/grub-install.in'
--- util/grub-install.in	2013-01-27 15:17:21 +0000
+++ util/grub-install.in	2013-03-24 13:03:31 +0000
@@ -319,6 +319,8 @@
 		    target=i386-pc
 		fi
 		;;
+	    x"arm"*)
+		target="arm-uboot";;
 	    *)
 		gettext "Unable to determine your platform. Use --target." ;
 		echo	;;
@@ -338,7 +340,7 @@
     if [ x$disk_module = xunspecified ]; then
 	disk_module=biosdisk
     fi
-elif [ "${grub_modinfo_platform}" = "ieee1275" ] || [ "${grub_modinfo_platform}" = "efi" ] || [ "${grub_modinfo_platform}" = "arc" ] ; then
+elif [ "${grub_modinfo_platform}" = "ieee1275" ] || [ "${grub_modinfo_platform}" = "efi" ] || [ "${grub_modinfo_platform}" = "arc" ] || [ "${grub_modinfo_platform}" = "uboot" ] ; then
     disk_module=
 else
     disk_module=native
@@ -854,6 +856,14 @@
 		-L "$bootloader_id" -l "\\EFI\\$efi_distributor\\$efi_file"
 	fi
     fi
+elif [ x"${grub_modinfo_target_cpu}-${grub_modinfo_platform}" = xarm-uboot ]; then
+    grub_imgname="${grubdir}/${grub_modinfo_target_cpu}-$grub_modinfo_platform/core.${imgext}"
+    raw_imgname="${uboot_imgname}.raw"
+    mv "$grub_imgname" "$raw_imgname"
+    mkimage -T kernel -A ARM -O Linux -a 0x08000000 -e 0x08000000 -C none -d "$raw_imgname" "$grub_imgname"
+    if [ $? -eq 0 ]; then
+	rm -f "$raw_imgname"
+    fi
 else
     gettext "WARNING: no platform-specific install was performed" 1>&2
     echo 1>&2

=== modified file 'util/grub-mkimage.c'
--- util/grub-mkimage.c	2013-03-07 07:17:24 +0000
+++ util/grub-mkimage.c	2013-03-24 13:03:31 +0000
@@ -69,7 +69,7 @@
     IMAGE_SPARC64_AOUT, IMAGE_SPARC64_RAW, IMAGE_I386_IEEE1275,
     IMAGE_LOONGSON_ELF, IMAGE_QEMU, IMAGE_PPC, IMAGE_YEELOONG_FLASH,
     IMAGE_FULOONG2F_FLASH, IMAGE_I386_PC_PXE, IMAGE_MIPS_ARC,
-    IMAGE_QEMU_MIPS_FLASH
+    IMAGE_QEMU_MIPS_FLASH, IMAGE_UBOOT
   } id;
   enum
     {
@@ -453,6 +453,25 @@
       .link_align = GRUB_KERNEL_MIPS_QEMU_MIPS_LINK_ALIGN,
       .default_compression = COMPRESSION_NONE
     },
+    {
+      .dirname = "arm-uboot",
+      .names = { "arm-uboot", NULL },
+      .voidp_sizeof = 4,
+      .bigendian = 0,
+      .id = IMAGE_UBOOT, 
+      .flags = PLATFORM_FLAGS_NONE,
+      .total_module_size = GRUB_KERNEL_ARM_UBOOT_TOTAL_MODULE_SIZE,
+      .decompressor_compressed_size = TARGET_NO_FIELD,
+      .decompressor_uncompressed_size = TARGET_NO_FIELD,
+      .decompressor_uncompressed_addr = TARGET_NO_FIELD,
+      .section_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
+      .vaddr_offset = 0,
+      .link_addr = GRUB_KERNEL_ARM_UBOOT_LINK_ADDR,
+      .elf_target = EM_ARM,
+      .mod_gap = GRUB_KERNEL_ARM_UBOOT_MOD_GAP,
+      .mod_align = GRUB_KERNEL_ARM_UBOOT_MOD_ALIGN,
+      .link_align = 4
+    },
   };
 
 #define grub_target_to_host32(x) (grub_target_to_host32_real (image_target, (x)))
@@ -1020,6 +1039,7 @@
     case IMAGE_SPARC64_RAW:
     case IMAGE_I386_IEEE1275:
     case IMAGE_PPC:
+    case IMAGE_UBOOT:
       break;
     }
 
@@ -1687,6 +1707,9 @@
 	core_size = program_size + header_size + footer_size;
       }
       break;
+    case IMAGE_UBOOT:
+      /* Raw image, header added by grub-install */
+      break;
     }
 
   grub_util_write_image (core_img, core_size, out, outname);

