All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 4/7] Support for ARM/U-Boot platforms
@ 2013-03-24 17:01 Leif Lindholm
  2013-04-01  2:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-04-09  0:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 2 replies; 14+ messages in thread
From: Leif Lindholm @ 2013-03-24 17:01 UTC (permalink / raw)
  To: grub-devel

[-- Attachment #1: Type: text/plain, Size: 1 bytes --]



[-- Attachment #2: 0004-arm-uboot-support.patch --]
[-- Type: application/octet-stream, Size: 12265 bytes --]

=== 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);


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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-03-24 17:01 [PATCH 4/7] Support for ARM/U-Boot platforms Leif Lindholm
@ 2013-04-01  2:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-04-01  9:53   ` Francesco Lavra
  2013-04-03 16:32   ` Leif Lindholm
  2013-04-09  0:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 2 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-04-01  2:15 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 1992 bytes --]

Which architecture is raspberry pie? I have one here and it would be
good if I could use it for testing.

> +#define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000
> +#define GRUB_KERNEL_MACHINE_HEAP_SIZE  (grub_size_t) (2 * 1024 * 1024)

Why so small heap?

> === 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"

Where is uboot_imgname set?

> +    mv "$grub_imgname" "$raw_imgname"
> +    mkimage -T kernel -A ARM -O Linux -a 0x08000000 -e 0x08000000 -C none -d "$raw_imgname" "$grub_imgname"

Is it from uboot? You need to check for its availability

> @@ -1687,6 +1707,9 @@
>  	core_size = program_size + header_size + footer_size;
>        }
>        break;
> +    case IMAGE_UBOOT:
> +      /* Raw image, header added by grub-install */
> +      break;

What is this additional header? Is it just ELF? Why not use ELF codepath?


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-01  2:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2013-04-01  9:53   ` Francesco Lavra
  2013-04-01 11:24     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-04-03 16:32   ` Leif Lindholm
  1 sibling, 1 reply; 14+ messages in thread
From: Francesco Lavra @ 2013-04-01  9:53 UTC (permalink / raw)
  To: grub-devel

On 04/01/2013 04:15 AM, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> Which architecture is raspberry pie? I have one here and it would be
> good if I could use it for testing.

It's ARMv6, so unfortunately it's not supported by this port, which
works only on ARMv7.

> 
>> +#define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000
>> +#define GRUB_KERNEL_MACHINE_HEAP_SIZE  (grub_size_t) (2 * 1024 * 1024)
> 
> Why so small heap?
> 
>> === 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"
> 
> Where is uboot_imgname set?
> 
>> +    mv "$grub_imgname" "$raw_imgname"
>> +    mkimage -T kernel -A ARM -O Linux -a 0x08000000 -e 0x08000000 -C none -d "$raw_imgname" "$grub_imgname"
> 
> Is it from uboot? You need to check for its availability
> 
>> @@ -1687,6 +1707,9 @@
>>  	core_size = program_size + header_size + footer_size;
>>        }
>>        break;
>> +    case IMAGE_UBOOT:
>> +      /* Raw image, header added by grub-install */
>> +      break;
> 
> What is this additional header? Is it just ELF? Why not use ELF codepath?

No, it's not an ELF header, it's a U-Boot-specific header added by the
mkimage utility launched by grub-install.

--
Francesco


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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-01  9:53   ` Francesco Lavra
@ 2013-04-01 11:24     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-04-01 14:29       ` Francesco Lavra
  0 siblings, 1 reply; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-04-01 11:24 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 387 bytes --]

On 01.04.2013 11:53, Francesco Lavra wrote:

> On 04/01/2013 04:15 AM, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
>> > Which architecture is raspberry pie? I have one here and it would be
>> > good if I could use it for testing.
> It's ARMv6, so unfortunately it's not supported by this port, which
> works only on ARMv7.
> 

Which parts prevent it from working on ARMv6?


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-01 11:24     ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2013-04-01 14:29       ` Francesco Lavra
  2013-04-03 10:29         ` Leif Lindholm
  0 siblings, 1 reply; 14+ messages in thread
From: Francesco Lavra @ 2013-04-01 14:29 UTC (permalink / raw)
  To: grub-devel

On 04/01/2013 01:24 PM, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
> On 01.04.2013 11:53, Francesco Lavra wrote:
> 
>> On 04/01/2013 04:15 AM, Vladimir 'φ-coder/phcoder' Serbinenko wrote:
>>>> Which architecture is raspberry pie? I have one here and it would be
>>>> good if I could use it for testing.
>> It's ARMv6, so unfortunately it's not supported by this port, which
>> works only on ARMv7.
>>
> 
> Which parts prevent it from working on ARMv6?

I haven't studied ARMv6, but I can say that at least some assembly
instructions used by the cache maintenance code in kern/arm/cache.S
(such as DMB, DSB and ISB) have been introduced in ARMv7, as well as
some coprocessor operations (specifically, I'm looking at those used in
the clean_invalidate_dcache routine in the same file).


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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-01 14:29       ` Francesco Lavra
@ 2013-04-03 10:29         ` Leif Lindholm
  0 siblings, 0 replies; 14+ messages in thread
From: Leif Lindholm @ 2013-04-03 10:29 UTC (permalink / raw)
  To: The development of GNU GRUB

On Mon, Apr 01, 2013 at 04:29:02PM +0200, Francesco Lavra wrote:
> >> On 04/01/2013 04:15 AM, Vladimir '??-coder/phcoder' Serbinenko wrote:
> >>>> Which architecture is raspberry pie? I have one here and it would be
> >>>> good if I could use it for testing.
> >> It's ARMv6, so unfortunately it's not supported by this port, which
> >> works only on ARMv7.
> > 
> > Which parts prevent it from working on ARMv6?
> 
> I haven't studied ARMv6, but I can say that at least some assembly
> instructions used by the cache maintenance code in kern/arm/cache.S
> (such as DMB, DSB and ISB) have been introduced in ARMv7, as well as
> some coprocessor operations (specifically, I'm looking at those used in
> the clean_invalidate_dcache routine in the same file).

That pretty much sums it up.
Plus, with the ARM1176 not supporting Thumb-2 extensions of Thumb
instruction set, you would also need to ensure all of the ASM could
build as ARM, and that all relocations required for an ARM build were
implemented.

/
    Leif


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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-01  2:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-04-01  9:53   ` Francesco Lavra
@ 2013-04-03 16:32   ` Leif Lindholm
  2013-04-08 10:47     ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 1 reply; 14+ messages in thread
From: Leif Lindholm @ 2013-04-03 16:32 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: phcoder

On Mon, Apr 01, 2013 at 04:15:03AM +0200, Vladimir '??-coder/phcoder' Serbinenko wrote:
> > +#define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000
> > +#define GRUB_KERNEL_MACHINE_HEAP_SIZE  (grub_size_t) (2 * 1024 * 1024)
> 
> Why so small heap?
 
I copied ieee1275 HEAP_MIN_SIZE to begin with, and it was always enough.
(Since U-Boot doesn't provide any memory mapping service, kernel and
initrd are not going on the heap.)
I could increase it?

> > === 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"
> 
> Where is uboot_imgname set?

*cough* that would be a typo then - should be grub_imgname.
 
> > +    mv "$grub_imgname" "$raw_imgname"
> > +    mkimage -T kernel -A ARM -O Linux -a 0x08000000 -e 0x08000000 -C none -d "$raw_imgname" "$grub_imgname"
> 
> Is it from uboot? You need to check for its availability
 
Yes.

/
    Leif


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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-03 16:32   ` Leif Lindholm
@ 2013-04-08 10:47     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-04-09 10:26       ` Leif Lindholm
  0 siblings, 1 reply; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-04-08 10:47 UTC (permalink / raw)
  To: Leif Lindholm; +Cc: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 5599 bytes --]

On 03.04.2013 18:32, Leif Lindholm wrote:

> On Mon, Apr 01, 2013 at 04:15:03AM +0200, Vladimir '??-coder/phcoder' Serbinenko wrote:
>>> +#define GRUB_KERNEL_MACHINE_STACK_SIZE 0x40000
>>> +#define GRUB_KERNEL_MACHINE_HEAP_SIZE  (grub_size_t) (2 * 1024 * 1024)
>>
>> Why so small heap?
>  
> I copied ieee1275 HEAP_MIN_SIZE to begin with, and it was always enough.
> (Since U-Boot doesn't provide any memory mapping service, kernel and
> initrd are not going on the heap.)

On x86 we reuse heap for kernels as well

> I could increase it?
> 

If we want to support any kind of graphics (gfxterm, gfxmenu) on arm as well, we'll need more heap

>>> === 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"
>>
>> Where is uboot_imgname set?
> 
> *cough* that would be a typo then - should be grub_imgname.
>  
>>> +    mv "$grub_imgname" "$raw_imgname"
>>> +    mkimage -T kernel -A ARM -O Linux -a 0x08000000 -e 0x08000000 -C none -d "$raw_imgname" "$grub_imgname"
>>
>> Is it from uboot? You need to check for its availability
>  
> Yes.
> 

the header is trivial. I added it to grub-mkimage (patch at the bottom).
Trouble is that grub-install now rightfully warns about the lack of platform-specific install.
What do we have to do to register the image at u-boot? Put it in specific location?
Also you spoke about relocatable image but AFAICT header always specifies load address. Do you have a way around it?

=== modified file 'util/grub-install.in'
--- util/grub-install.in	2013-04-07 00:41:07 +0000
+++ util/grub-install.in	2013-04-08 10:42:46 +0000
@@ -833,14 +833,6 @@
 		-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-04-07 00:41:07 +0000
+++ util/grub-mkimage.c	2013-04-08 09:40:18 +0000
@@ -40,6 +40,7 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <grub/efi/pe32.h>
+#include <grub/uboot/image.h>
 
 #define _GNU_SOURCE	1
 #include <argp.h>
@@ -1499,6 +1500,42 @@
       core_size = rom_size;
     }
     break;
+
+    case IMAGE_UBOOT:
+    {
+      struct grub_uboot_image_header *hdr;
+      GRUB_PROPERLY_ALIGNED_ARRAY (crc32_context, GRUB_MD_CRC32->contextsize);
+
+      hdr = xmalloc (core_size + sizeof (struct grub_uboot_image_header));
+      memcpy (hdr + 1, core_img, core_size);
+
+      memset (hdr, 0, sizeof (*hdr));
+      hdr->ih_magic = grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAGIC);
+      hdr->ih_time = grub_cpu_to_be32 (time (0));
+      hdr->ih_size = grub_cpu_to_be32 (core_size);
+      hdr->ih_load = grub_cpu_to_be32 (image_target->link_addr);
+      hdr->ih_ep = grub_cpu_to_be32 (image_target->link_addr);
+      hdr->ih_os = GRUB_UBOOT_IH_OS_LINUX;
+      hdr->ih_arch = GRUB_UBOOT_IH_ARCH_ARM;
+      hdr->ih_type = GRUB_UBOOT_IH_TYPE_KERNEL;
+      hdr->ih_comp = GRUB_UBOOT_IH_COMP_NONE;
+
+      GRUB_MD_CRC32->init(crc32_context);
+      GRUB_MD_CRC32->write(crc32_context, hdr + 1, core_size);
+      GRUB_MD_CRC32->final(crc32_context);
+      hdr->ih_dcrc = grub_get_unaligned32 (GRUB_MD_CRC32->read (crc32_context));
+
+      GRUB_MD_CRC32->init(crc32_context);
+      GRUB_MD_CRC32->write(crc32_context, hdr, sizeof (*hdr));
+      GRUB_MD_CRC32->final(crc32_context);
+      hdr->ih_hcrc = grub_get_unaligned32 (GRUB_MD_CRC32->read (crc32_context));
+
+      free (core_img);
+      core_img = (char *) hdr;
+      core_size += sizeof (struct grub_uboot_image_header);
+    }
+    break;
+
     case IMAGE_MIPS_ARC:
       {
 	char *ecoff_img;
@@ -1725,9 +1762,6 @@
 	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);



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-03-24 17:01 [PATCH 4/7] Support for ARM/U-Boot platforms Leif Lindholm
  2013-04-01  2:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2013-04-09  0:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-04-09 11:39   ` Leif Lindholm
  1 sibling, 1 reply; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-04-09  0:15 UTC (permalink / raw)
  To: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 7021 bytes --]

On 24.03.2013 18:01, Leif Lindholm wrote:

> 
> 0004-arm-uboot-support.patch
> 
> 
> === 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

This start is wrong. Even if modules start later due to alignment, BSS
starts at __bss_start. Additional problem is that both __bss_start and
_end may be unaligned unless special care is taken (like putting a dummy
uint32_t at the beginning of BSS by putting it at the end of startup.S
or using ld options)

> +	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]
> +	

Instead of temporary stashing the values to registers you can just init
those values in C code to e.g. 0x55aa55aa so they'll be in .data and so
accessible from the very beginning.

> +	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.
> +	 */

Only modules are aligned. BSS itself is still at _bss.

> +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)

Can be trivially simplified to:
mvn	r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
add	r0, r0, r1
and	r0, r0, r1
which can be then inlined. Also it's more reliable to save grub_modbase
as soon as we computed it in asm part (and use 0x55aa55aa trick to make
it accessible early)




[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-08 10:47     ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2013-04-09 10:26       ` Leif Lindholm
  2013-04-09 17:26         ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 1 reply; 14+ messages in thread
From: Leif Lindholm @ 2013-04-09 10:26 UTC (permalink / raw)
  To: Vladimir '??-coder/phcoder' Serbinenko
  Cc: The development of GNU GRUB

On Mon, Apr 08, 2013 at 12:47:48PM +0200, Vladimir '??-coder/phcoder' Serbinenko wrote:
> >> Why so small heap?
> >  
> > I copied ieee1275 HEAP_MIN_SIZE to begin with, and it was always enough.
> > (Since U-Boot doesn't provide any memory mapping service, kernel and
> > initrd are not going on the heap.)
> 
> On x86 we reuse heap for kernels as well
 
This might be difficult to combine with the intersection of U-Boot and
the defined ARM Linux boot process.

> > I could increase it?
> 
> If we want to support any kind of graphics (gfxterm, gfxmenu) on arm as well, we'll need more heap

OK.
 
> >> Is it from uboot? You need to check for its availability
> >  
> > Yes.
> 
> the header is trivial. I added it to grub-mkimage (patch at the bottom).

Neat, thanks :)

> Trouble is that grub-install now rightfully warns about the lack of
> platform-specific install.
> What do we have to do to register the image at u-boot?
> Put it in specific location?

EFI provides three very nice things:
- Standardised partition and filesystem type for bootloaders.
- Standardised runtime services for updating selected boot image.
- Standardised "removable media" bootloader path.

U-Boot has neither, and different platforms use different mechanisms to
affect boot images - some "prime" the enviroment with a uEnv.txt, some
search around a predefined set of filesystems for boot scripts, some
require you to manually "setenv" from within U-Boot.

Debian use a special package called flash-kernel to abstract these things
away.

So in short, I think the only sane thing grub-install can do for arm-uboot,
is what I already have it do - generate an image with the required modules
embedded. Now, maybe it shouldn't be grub/arm-uboot/core.img, but that was
what I ended up using.

> Also you spoke about relocatable image but AFAICT header always
> specifies load address. Do you have a way around it?

Well, it's not so much a way around it as somthing that almost ampounts
to a new port (certainly a new image type).
The proper fix would be to generate it as an ELF image _instead_, and use
U-Boot's ELF loader support to load it properly.

/
    Leif


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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-09  0:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2013-04-09 11:39   ` Leif Lindholm
  2013-04-09 11:55     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-04-09 12:45     ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 2 replies; 14+ messages in thread
From: Leif Lindholm @ 2013-04-09 11:39 UTC (permalink / raw)
  To: The development of GNU GRUB; +Cc: phcoder

On Tue, Apr 09, 2013 at 02:15:20AM +0200, Vladimir '??-coder/phcoder' Serbinenko wrote:
> > === 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
[...]
> > +	@ 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
> 
> This start is wrong. Even if modules start later due to alignment, BSS
> starts at __bss_start. Additional problem is that both __bss_start and
> _end may be unaligned unless special care is taken (like putting a dummy
> uint32_t at the beginning of BSS by putting it at the end of startup.S
> or using ld options)
 
My main concern here is getting the module start address right.
But see below.

> > +	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]
> > +	
> 
> Instead of temporary stashing the values to registers you can just init
> those values in C code to e.g. 0x55aa55aa so they'll be in .data and so
> accessible from the very beginning.

Neat :)
I'll do that.
 
> > +	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.
> > +	 */
> 
> Only modules are aligned. BSS itself is still at _bss.
 
My issue with this statement is that this definition of BSS can
include padding before the first symbol inside the BSS.
I accept that it can also contain less-aligned symbols, which is a
problem that I need to handle in the code above.

> > +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)
> 
> Can be trivially simplified to:
> mvn	r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
> add	r0, r0, r1
> and	r0, r0, r1

Yes, I may have been a bit silly when writing the above (and now), but
I don't follow (0xfffffff8 + __bss_start) & 0xfffffff8 ?
Do you mean:
	mvn   r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN)
	add   r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
	and   r0, r0, r1

> which can be then inlined. Also it's more reliable to save grub_modbase
> as soon as we computed it in asm part (and use 0x55aa55aa trick to make
> it accessible early)
 
OK, that makes sense. And having done that, it can be inlined, since I no
longer need it from within uboot/init.c.

/
    Leif


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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-09 11:39   ` Leif Lindholm
@ 2013-04-09 11:55     ` Vladimir 'φ-coder/phcoder' Serbinenko
  2013-04-09 12:45     ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 0 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-04-09 11:55 UTC (permalink / raw)
  To: Leif Lindholm, The development of GRUB 2

[-- Attachment #1: Type: text/plain, Size: 3672 bytes --]

On 09.04.2013 13:39, Leif Lindholm wrote:

> On Tue, Apr 09, 2013 at 02:15:20AM +0200, Vladimir '??-coder/phcoder' Serbinenko wrote:
>>> === 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
> [...]
>>> +	@ 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
>>
>> This start is wrong. Even if modules start later due to alignment, BSS
>> starts at __bss_start. Additional problem is that both __bss_start and
>> _end may be unaligned unless special care is taken (like putting a dummy
>> uint32_t at the beginning of BSS by putting it at the end of startup.S
>> or using ld options)
>  
> My main concern here is getting the module start address right.
> But see below.
> 
>>> +	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]
>>> +	
>>
>> Instead of temporary stashing the values to registers you can just init
>> those values in C code to e.g. 0x55aa55aa so they'll be in .data and so
>> accessible from the very beginning.
> 
> Neat :)
> I'll do that.
>  
>>> +	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.
>>> +	 */
>>
>> Only modules are aligned. BSS itself is still at _bss.
>  
> My issue with this statement is that this definition of BSS can
> include padding before the first symbol inside the BSS.
> I accept that it can also contain less-aligned symbols, which is a
> problem that I need to handle in the code above.
> 

Actually since BSS surely contains at least one uint32_t its start and
has to be aligned to 32-bit. So we can just align_up __bss_start to 4
and _end align_down to 4. This would work correctly enough even with the
presence of the bug you rerported to GCC folks.

>>> +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)
>>
>> Can be trivially simplified to:
>> mvn	r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
>> add	r0, r0, r1
>> and	r0, r0, r1
> 
> Yes, I may have been a bit silly when writing the above (and now), but
> I don't follow (0xfffffff8 + __bss_start) & 0xfffffff8 ?
> Do you mean:
> 	mvn   r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN)
> 	add   r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
> 	and   r0, r0, r1
> 

Yes, sorry, I proposed it without testing and I'm a beginner in ARM asm.

>> which can be then inlined. Also it's more reliable to save grub_modbase
>> as soon as we computed it in asm part (and use 0x55aa55aa trick to make
>> it accessible early)
>  
> OK, that makes sense. And having done that, it can be inlined, since I no
> longer need it from within uboot/init.c.
> 
> /
>     Leif
> 




[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-09 11:39   ` Leif Lindholm
  2013-04-09 11:55     ` Vladimir 'φ-coder/phcoder' Serbinenko
@ 2013-04-09 12:45     ` Vladimir 'φ-coder/phcoder' Serbinenko
  1 sibling, 0 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-04-09 12:45 UTC (permalink / raw)
  To: Leif Lindholm, The development of GRUB 2


[-- Attachment #1.1: Type: text/plain, Size: 187 bytes --]

Here is what I have in my local tree (full patch). Contains also an
initial attempt at i386-uboot but given sorry state of uboot on i386,
I'll probably abandon it instead of finishing

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1.2: q.diff --]
[-- Type: text/x-diff; name="q.diff", Size: 36224 bytes --]

=== modified file 'Makefile.util.def'
--- Makefile.util.def	2013-04-07 00:41:07 +0000
+++ Makefile.util.def	2013-04-09 12:14:38 +0000
@@ -150,7 +150,7 @@
   common = util/resolve.c;
   common = grub-core/kern/emu/argp_common.c;
 
-  arm = grub-core/kern/arm/dl.c;
+  common = grub-core/kern/arm/dl.c;
 
   extra_dist = util/grub-mkimagexx.c;
 
@@ -472,7 +472,6 @@
   enable = mips_loongson;
   enable = ia64_efi;
   enable = powerpc_ieee1275;
-  enable = arm_uboot;
 };
 
 script = {

=== modified file 'conf/Makefile.common'
--- conf/Makefile.common	2013-04-07 00:41:07 +0000
+++ conf/Makefile.common	2013-04-07 16:08:07 +0000
@@ -40,8 +40,7 @@
 if COND_arm
 # Image entry point always in ARM (A32) state - ensure proper functionality if
 # the rest is built for the Thumb (T32) state.
-  CFLAGS_PLATFORM += -mthumb-interwork -mno-unaligned-access -mlong-calls
-  CCASFLAGS_PLATFORM = -Wa,-mimplicit-it=thumb
+  CFLAGS_PLATFORM += -mthumb-interwork -march=armv6 -mlong-calls
   LDFLAGS_PLATFORM = -Wl,--wrap=__clear_cache
 endif
 

=== modified file 'configure.ac'
--- configure.ac	2013-04-07 00:41:07 +0000
+++ configure.ac	2013-04-08 21:48:08 +0000
@@ -141,6 +141,7 @@
   i386-linuxbios) platform=coreboot ;;
   i386-ieee1275) ;;
   i386-qemu) ;;
+  i386-uboot) ;;
   powerpc-ieee1275) ;;
   sparc64-ieee1275) ;;
   ia64-efi) ;;
@@ -717,7 +718,7 @@
 fi
 
 # Check for libgcc symbols
-AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __ucmpdi2 _restgpr_14_x __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3 __ctzdi2 __ctzsi2)
+AC_CHECK_FUNCS(__bswapsi2 __bswapdi2 __ashldi3 __ashrdi3 __lshrdi3 __ucmpdi2 _restgpr_14_x __udivsi3 __umoddi3 __udivdi3 __divsi3 __modsi3 __umodsi3 __moddi3 __divdi3 __ctzdi2 __ctzsi2 __aeabi_ulcmp)
 
 if test "x$TARGET_APPLE_CC" = x1 ; then
 CFLAGS="$TARGET_CFLAGS -nostdlib"
@@ -1149,6 +1150,7 @@
 AM_CONDITIONAL([COND_i386_ieee1275], [test x$target_cpu = xi386 -a x$platform = xieee1275])
 AM_CONDITIONAL([COND_i386_coreboot], [test x$target_cpu = xi386 -a x$platform = xcoreboot])
 AM_CONDITIONAL([COND_i386_multiboot], [test x$target_cpu = xi386 -a x$platform = xmultiboot])
+AM_CONDITIONAL([COND_i386_uboot], [test x$target_cpu = xi386 -a x$platform = xuboot])
 AM_CONDITIONAL([COND_x86_64_efi], [test x$target_cpu = xx86_64 -a x$platform = xefi])
 AM_CONDITIONAL([COND_mips_loongson], [test x$target_cpu = xmipsel -a x$platform = xloongson])
 AM_CONDITIONAL([COND_mips_qemu_mips], [test "(" x$target_cpu = xmips -o x$target_cpu = xmipsel ")"  -a x$platform = xqemu_mips])

=== modified file 'gentpl.py'
--- gentpl.py	2013-04-07 00:41:07 +0000
+++ gentpl.py	2013-04-08 23:20:22 +0000
@@ -20,7 +20,8 @@
 #
 
 GRUB_PLATFORMS = [ "emu", "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot",
-                   "i386_multiboot", "i386_ieee1275", "x86_64_efi",
+                   "i386_multiboot", "i386_ieee1275", "i386_uboot",
+                   "x86_64_efi",
                    "mips_loongson", "sparc64_ieee1275",
                    "powerpc_ieee1275", "mips_arc", "ia64_efi",
                    "mips_qemu_mips", "arm_uboot", "arm_efi" ]
@@ -30,7 +31,7 @@
 GROUPS["common"]   = GRUB_PLATFORMS[:]
 
 # Groups based on CPU
-GROUPS["i386"]     = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275" ]
+GROUPS["i386"]     = [ "i386_pc", "i386_efi", "i386_qemu", "i386_coreboot", "i386_multiboot", "i386_ieee1275", "i386_uboot" ]
 GROUPS["x86_64"]   = [ "x86_64_efi" ]
 GROUPS["x86"]      = GROUPS["i386"] + GROUPS["x86_64"]
 GROUPS["mips"]     = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
@@ -41,7 +42,7 @@
 # Groups based on firmware
 GROUPS["efi"]  = [ "i386_efi", "x86_64_efi", "ia64_efi", "arm_efi" ]
 GROUPS["ieee1275"]   = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
-GROUPS["uboot"] = [ "arm_uboot" ]
+GROUPS["uboot"] = [ "arm_uboot", "i386_uboot" ]
 
 # emu is a special case so many core functionality isn't needed on this platform
 GROUPS["noemu"]   = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu")
@@ -64,7 +65,7 @@
 for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
 
 # Flattened Device Trees (FDT)
-GROUPS["fdt"] = [ "arm_uboot", "arm_efi" ]
+GROUPS["fdt"] = [ "arm_uboot", "arm_efi", "i386_uboot" ]
 
 # Miscelaneous groups schedulded to disappear in future
 GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]

=== modified file 'grub-core/Makefile.am'
--- grub-core/Makefile.am	2013-04-07 00:41:07 +0000
+++ grub-core/Makefile.am	2013-04-08 23:41:09 +0000
@@ -132,6 +132,15 @@
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
 endif
 
+if COND_i386_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/terminfo.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/extcmd.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/lib/arg.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/i386/tsc.h
+endif
+
 if COND_x86_64_efi
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/efi.h
 KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/efi/disk.h

=== modified file 'grub-core/Makefile.core.def'
--- grub-core/Makefile.core.def	2013-04-07 00:41:07 +0000
+++ grub-core/Makefile.core.def	2013-04-09 00:05:56 +0000
@@ -79,6 +79,7 @@
   i386_ieee1275_startup = kern/i386/ieee1275/startup.S;
   i386_coreboot_startup = kern/i386/coreboot/startup.S;
   i386_multiboot_startup = kern/i386/coreboot/startup.S;
+  i386_uboot_startup = kern/i386/uboot/startup.S;
   mips_startup = kern/mips/startup.S;
   sparc64_ieee1275_startup = kern/sparc64/ieee1275/crt0.S;
   powerpc_ieee1275_startup = kern/powerpc/ieee1275/startup.S;
@@ -492,6 +493,7 @@
   enable = i386_ieee1275;
   enable = i386_coreboot;
   enable = i386_multiboot;
+  enable = i386_uboot;
 };
 
 module = {
@@ -569,11 +571,13 @@
   i386_pc = commands/i386/pc/acpi.c;
   i386_coreboot = commands/i386/pc/acpi.c;
   i386_multiboot = commands/i386/pc/acpi.c;
+  i386_uboot = commands/i386/pc/acpi.c;
 
   enable = efi;
   enable = i386_pc;
   enable = i386_coreboot;
   enable = i386_multiboot;
+  enable = i386_uboot;
 };
 
 module = {
@@ -1057,6 +1061,8 @@
   i386_multiboot = efiemu/i386/pc/cfgtables.c;
   i386_ieee1275 = efiemu/i386/nocfgtables.c;
   i386_qemu = efiemu/i386/nocfgtables.c;
+  i386_uboot = efiemu/i386/pc/cfgtables.c;
+
   common = efiemu/mm.c;
   common = efiemu/loadcore_common.c;
   common = efiemu/symbols.c;
@@ -1077,6 +1083,7 @@
   enable = i386_ieee1275;
   enable = i386_multiboot;
   enable = i386_qemu;
+  enable = i386_uboot;
 };
 
 module = {
@@ -1656,6 +1663,7 @@
 
   enable = terminfomodule;
   enable = ieee1275;
+  enable = i386_uboot;
 };
 
 module = {

=== modified file 'grub-core/disk/uboot/ubootdisk.c'
--- grub-core/disk/uboot/ubootdisk.c	2013-04-07 00:41:07 +0000
+++ grub-core/disk/uboot/ubootdisk.c	2013-04-08 08:34:08 +0000
@@ -246,7 +246,7 @@
   grub_dprintf ("ubootdisk", "(%s) blocksize=%d, log_sector_size=%d\n",
 		disk->name, d->block_size, disk->log_sector_size);
 
-  disk->total_sectors = GRUB_DISK_SIZE_UNKNOWN;
+  disk->total_sectors = devinfo->di_stor.block_count;
   disk->data = d;
 
   return GRUB_ERR_NONE;

=== modified file 'grub-core/kern/arm/dl.c'
--- grub-core/kern/arm/dl.c	2013-04-07 00:41:07 +0000
+++ grub-core/kern/arm/dl.c	2013-04-09 11:44:28 +0000
@@ -23,17 +23,11 @@
 #include <grub/err.h>
 #include <grub/mm.h>
 #include <grub/i18n.h>
+#include <grub/arm/reloc.h>
 
 #ifdef GRUB_UTIL
 # include <grub/util/misc.h>
 #else
-# if !defined(__thumb2__)
-#  error "Relocations not implemented for A32 ("ARM") instruction set yet!"
-# endif
-
-grub_err_t reloc_jump24 (grub_uint32_t *addr, Elf32_Addr sym_addr);
-grub_err_t reloc_thm_call (grub_uint16_t *addr, Elf32_Addr sym_addr);
-grub_err_t reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr);
 
 #ifdef DL_DEBUG
 static const char *symstrtab;
@@ -104,7 +98,7 @@
  *   B.W, BL and BLX
  */
 grub_err_t
-reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
+grub_arm_reloc_thm_call (grub_uint16_t *target, Elf32_Addr sym_addr)
 {
   grub_int32_t offset, offset_low, offset_high;
   grub_uint32_t sign, j1, j2, is_blx;
@@ -122,14 +116,8 @@
 
   /* If BLX, target symbol must be ARM (target address LSB == 0) */
   if (is_blx && (sym_addr & 1))
-    {
-#ifndef GRUB_UTIL
-      return grub_error
-	(GRUB_ERR_BUG, N_("Relocation targeting wrong execution state"));
-#else
-      grub_util_error ("Relocation targeting wrong execution state");
-#endif
-    }
+    return grub_error (GRUB_ERR_BUG,
+		       N_("Relocation targeting wrong execution state"));
 
   offset_low = -16777216;
   offset_high = is_blx ? 16777212 : 16777214;
@@ -159,18 +147,12 @@
 #endif
 
   if ((offset < offset_low) || (offset > offset_high))
-    {
-#ifdef GRUB_UTIL
-      grub_util_error ("Relocation out of range");
-#else
-      return grub_error
-	(GRUB_ERR_OUT_OF_RANGE, N_("THM_CALL Relocation out of range."));
-#endif
-    }
+    return grub_error (GRUB_ERR_OUT_OF_RANGE,
+		       N_("THM_CALL Relocation out of range."));
 
 #ifdef GRUB_UTIL
-  grub_util_info ("    relative destination = 0x%08x",
-		  (unsigned int)target + offset);
+  grub_util_info ("    relative destination = 0x%08lx",
+		  (unsigned long)target + offset);
 #endif
 
   /* Reassemble instruction word */
@@ -200,7 +182,7 @@
  * Relocate conditional Thumb (T32) B<c>.W
  */
 grub_err_t
-reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr)
+grub_arm_reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr)
 {
   grub_int32_t offset;
   grub_uint32_t insword, insmask;
@@ -260,7 +242,7 @@
  * Relocate ARM (A32) B
  */
 grub_err_t
-reloc_jump24 (grub_uint32_t *addr, Elf32_Addr sym_addr)
+grub_arm_reloc_jump24 (grub_uint32_t *addr, Elf32_Addr sym_addr)
 {
   grub_uint32_t insword;
   grub_int32_t offset;
@@ -358,9 +340,10 @@
 	      return retval;
 	  }
 	  break;
+	case R_ARM_CALL:
 	case R_ARM_JUMP24:
 	  {
-	    retval = reloc_jump24 (target, sym_addr);
+	    retval = grub_arm_reloc_jump24 (target, sym_addr);
 	    if (retval != GRUB_ERR_NONE)
 	      return retval;
 	  }
@@ -369,7 +352,7 @@
 	case R_ARM_THM_JUMP24:
 	  {
 	    /* Thumb instructions can be 16-bit aligned */
-	    retval = reloc_thm_call ((grub_uint16_t *) target, sym_addr);
+	    retval = grub_arm_reloc_thm_call ((grub_uint16_t *) target, sym_addr);
 	    if (retval != GRUB_ERR_NONE)
 	      return retval;
 	  }
@@ -377,7 +360,7 @@
 	case R_ARM_THM_JUMP19:
 	  {
 	    /* Thumb instructions can be 16-bit aligned */
-	    retval = reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr);
+	    retval = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr);
 	    if (retval != GRUB_ERR_NONE)
 	      return retval;
 	  }

=== modified file 'grub-core/kern/arm/uboot/startup.S'
--- grub-core/kern/arm/uboot/startup.S	2013-04-07 00:41:07 +0000
+++ grub-core/kern/arm/uboot/startup.S	2013-04-09 12:36:48 +0000
@@ -65,20 +65,29 @@
 	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
+	ldr     r12, =EXT_C(uboot_machine_type)
+	str     r1, [r12]
+	ldr     r12, =EXT_C(uboot_boot_data)
+	str     r2, [r12]
+
 
 	@ 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	r0, =EXT_C(__bss_start)		@ src
+	add	r0, r0, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
+	mvn	r1, #(GRUB_KERNEL_MACHINE_MOD_ALIGN - 1)
+	and	r0, r0, r1
+
 	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
-	
+
+	ldr     r12, =EXT_C(grub_modbase)
+	str     r1, [r12]
+
 1:	ldr	r3, [r0], #4 			@ r3 = *src++ 
 	str	r3, [r1], #4			@ *dst++ = r3 
 	subs	r2, #4				@ remaining -= 4
@@ -91,35 +100,16 @@
 
 	@ 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	r0, =EXT_C(__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

=== modified file 'grub-core/kern/dl.c'
--- grub-core/kern/dl.c	2013-03-19 19:25:09 +0000
+++ grub-core/kern/dl.c	2013-04-07 16:08:07 +0000
@@ -588,7 +588,7 @@
 {
   grub_dprintf ("modules", "flushing 0x%lx bytes at %p\n",
 		(unsigned long) mod->sz, mod->base);
-  grub_arch_sync_caches (mod->base, mod->sz);
+  //  grub_arch_sync_caches (mod->base, mod->sz);
 }
 
 /* Load a module from core memory.  */

=== added directory 'grub-core/kern/i386/uboot'
=== added file 'grub-core/kern/i386/uboot/startup.S'
--- grub-core/kern/i386/uboot/startup.S	1970-01-01 00:00:00 +0000
+++ grub-core/kern/i386/uboot/startup.S	2013-04-08 23:47:50 +0000
@@ -0,0 +1,61 @@
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 1999,2000,2001,2002,2003,2005,2006,2007,2008 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/symbol.h>
+/* For stack parameters.  */
+#include <grub/i386/pc/memory.h>
+#include <grub/machine/memory.h>
+#include <grub/offsets.h>
+
+/*
+ * Note: GRUB is compiled with the options -mrtd and -mregparm=3.
+ *       So the first three arguments are passed in %eax, %edx, and %ecx,
+ *       respectively, and if a function has a fixed number of arguments
+ *       and the number if greater than three, the function must return
+ *       with "ret $N" where N is ((the number of arguments) - 3) * 4.
+ */
+
+	.file	"startup.S"
+	.text
+	.globl	start, _start
+start:
+_start:
+
+	/* clean out the bss */
+	movl	$BSS_START_SYMBOL, %edi
+
+	/* compute the bss length */
+	movl	$END_SYMBOL, %ecx
+	subl	%edi, %ecx
+		
+	/* clean out */
+	xorl	%eax, %eax
+	cld
+	rep
+	stosb
+
+	/*
+	 *  Call the start of main body of C code.
+	 */
+	call	EXT_C(grub_main)
+
+	/* This should never happen.  */
+	cli
+1:	
+	hlt
+	jmp 1b

=== modified file 'grub-core/kern/uboot/init.c'
--- grub-core/kern/uboot/init.c	2013-04-07 00:41:07 +0000
+++ grub-core/kern/uboot/init.c	2013-04-09 12:23:57 +0000
@@ -35,10 +35,10 @@
 extern grub_size_t grub_total_module_size;
 extern int (*uboot_syscall_ptr) (int, int *, ...);
 
-grub_addr_t grub_modbase;
-
-grub_uint32_t uboot_machine_type;
-grub_addr_t uboot_boot_data;
+/* Set to anything other than zero so it lands in .data and not .bss.  */
+grub_addr_t grub_modbase = 0x55aa55aa;
+grub_uint32_t uboot_machine_type = 0x55aa55aa;
+grub_addr_t uboot_boot_data = 0x55aa55aa;
 
 static unsigned long timer_start;
 
@@ -69,7 +69,6 @@
 void
 grub_machine_init (void)
 {
-  grub_addr_t end, real_bss_start;
   int ver;
 
   /* First of all - establish connection with U-Boot */
@@ -85,26 +84,14 @@
       uboot_puts ("invalid U-Boot API version\n");
     }
 
-  /*
-   * Modules were relocated to _end, or __bss_start + grub_total_module_size,
-   * whichever greater. (And __bss_start may not point to actual BSS start...)
-   */
-  real_bss_start = uboot_get_real_bss_start ();
-  end = real_bss_start + grub_total_module_size;
-  if (end < (grub_addr_t) _end)
-    end = (grub_addr_t) _end;
-  grub_modbase = end;
-
   /* Initialize the console so that GRUB can display messages.  */
   grub_console_init_early ();
 
   /* Enumerate memory and initialize the memory management system. */
   grub_uboot_mm_init ();
 
-  grub_dprintf ("init", "__bss_start: 0x%08x, real_bss_start: 0x%08x\n",
-		(grub_addr_t) __bss_start, real_bss_start);
-  grub_dprintf ("init", "end: 0x%08x, _end: 0x%08x\n",
-		(grub_addr_t) end, (grub_addr_t) _end);
+  grub_dprintf ("init", "__bss_start: %p\n", __bss_start);
+  grub_dprintf ("init", "_end: %p\n", _end);
   grub_dprintf ("init", "grub_modbase: %p\n", (void *) grub_modbase);
   grub_dprintf ("init", "grub_modules_get_end(): %p\n",
 		(void *) grub_modules_get_end ());

=== modified file 'grub-core/lib/uboot/datetime.c'
--- grub-core/lib/uboot/datetime.c	2013-04-07 00:41:07 +0000
+++ grub-core/lib/uboot/datetime.c	2013-04-08 23:31:38 +0000
@@ -25,6 +25,7 @@
 GRUB_MOD_LICENSE ("GPLv3+");
 
 /* No simple platform-independent RTC access exists in U-Boot. */
+#ifndef __i386__
 
 grub_err_t
 grub_get_datetime (struct grub_datetime *datetime __attribute__ ((unused)))
@@ -39,3 +40,5 @@
   return grub_error (GRUB_ERR_INVALID_COMMAND,
 		     "can\'t set datetime using U-Boot");
 }
+
+#endif

=== modified file 'grub-core/lib/uboot/reboot.c'
--- grub-core/lib/uboot/reboot.c	2013-04-07 00:41:07 +0000
+++ grub-core/lib/uboot/reboot.c	2013-04-08 23:32:06 +0000
@@ -20,6 +20,8 @@
 #include <grub/misc.h>
 #include <grub/uboot/uboot.h>
 
+#ifndef __i386__
+
 void
 grub_reboot (void)
 {
@@ -28,3 +30,5 @@
   uboot_reset ();
   while (1);
 }
+
+#endif

=== added file 'include/grub/arm/reloc.h'
--- include/grub/arm/reloc.h	1970-01-01 00:00:00 +0000
+++ include/grub/arm/reloc.h	2013-04-09 11:38:30 +0000
@@ -0,0 +1,26 @@
+/*
+ *  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_ARM_RELOC_H
+#define GRUB_ARM_RELOC_H 1
+
+grub_err_t grub_arm_reloc_jump24 (grub_uint32_t *addr, Elf32_Addr sym_addr);
+grub_err_t grub_arm_reloc_thm_call (grub_uint16_t *addr, Elf32_Addr sym_addr);
+grub_err_t grub_arm_reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr);
+
+#endif

=== added directory 'include/grub/i386/uboot'
=== added file 'include/grub/i386/uboot/kernel.h'
--- include/grub/i386/uboot/kernel.h	1970-01-01 00:00:00 +0000
+++ include/grub/i386/uboot/kernel.h	2013-04-08 23:34:00 +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 */

=== added file 'include/grub/i386/uboot/memory.h'
--- include/grub/i386/uboot/memory.h	1970-01-01 00:00:00 +0000
+++ include/grub/i386/uboot/memory.h	2013-04-08 23:33:14 +0000
@@ -0,0 +1,1 @@
+#include <grub/i386/coreboot/memory.h>

=== added file 'include/grub/i386/uboot/serial.h'
--- include/grub/i386/uboot/serial.h	1970-01-01 00:00:00 +0000
+++ include/grub/i386/uboot/serial.h	2013-04-08 23:52:51 +0000
@@ -0,0 +1,1 @@
+#include <grub/i386/coreboot/serial.h>

=== modified file 'include/grub/libgcc.h'
--- include/grub/libgcc.h	2013-04-07 00:41:07 +0000
+++ include/grub/libgcc.h	2013-04-07 16:08:07 +0000
@@ -122,4 +122,5 @@
 void EXPORT_FUNC (__aeabi_uidiv) (void);
 void EXPORT_FUNC (__aeabi_uidivmod) (void);
 void EXPORT_FUNC (__wrap___clear_cache) (void *, void *);
+void EXPORT_FUNC (__aeabi_ulcmp) (void);
 #endif

=== modified file 'include/grub/uboot/api_public.h'
--- include/grub/uboot/api_public.h	2013-04-07 00:41:07 +0000
+++ include/grub/uboot/api_public.h	2013-04-07 16:08:07 +0000
@@ -61,9 +61,6 @@
 
 typedef int (*scp_t) (int, int *, ...);
 
-typedef grub_uint16_t uint16_t;
-typedef grub_uint32_t uint32_t;
-
 #define API_SIG_VERSION	1
 #define API_SIG_MAGIC	"UBootAPI"
 #define API_SIG_MAGLEN	8
@@ -71,8 +68,8 @@
 struct api_signature
 {
   char magic[API_SIG_MAGLEN];	/* magic string */
-  uint16_t version;		/* API version */
-  uint32_t checksum;		/* checksum of this sig struct */
+  grub_uint16_t version;	/* API version */
+  grub_uint32_t checksum;	/* checksum of this sig struct */
   scp_t syscall;		/* entry point to the API */
 };
 

=== added file 'include/grub/uboot/image.h'
--- include/grub/uboot/image.h	1970-01-01 00:00:00 +0000
+++ include/grub/uboot/image.h	2013-04-08 09:20:19 +0000
@@ -0,0 +1,175 @@
+/*
+ * (C) Copyright 2008 Semihalf
+ *
+ * (C) Copyright 2000-2005
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * 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
+ *
+ ********************************************************************
+ * NOTE: This header file defines an interface to U-Boot. Including
+ * this (unmodified) header file in another file is considered normal
+ * use of U-Boot, and does *not* fall under the heading of "derived
+ * work".
+ ********************************************************************
+ */
+
+#ifndef __GRUB_UBOOT_IMAGE_H__
+#define __GRUB_UBOOT_IMAGE_H__
+
+/*
+ * Operating System Codes
+ */
+#define GRUB_UBOOT_IH_OS_INVALID		0	/* Invalid OS	*/
+#define GRUB_UBOOT_IH_OS_OPENBSD		1	/* OpenBSD	*/
+#define GRUB_UBOOT_IH_OS_NETBSD		2	/* NetBSD	*/
+#define GRUB_UBOOT_IH_OS_FREEBSD		3	/* FreeBSD	*/
+#define GRUB_UBOOT_IH_OS_4_4BSD		4	/* 4.4BSD	*/
+#define GRUB_UBOOT_IH_OS_LINUX		5	/* Linux	*/
+#define GRUB_UBOOT_IH_OS_SVR4		6	/* SVR4		*/
+#define GRUB_UBOOT_IH_OS_ESIX		7	/* Esix		*/
+#define GRUB_UBOOT_IH_OS_SOLARIS		8	/* Solaris	*/
+#define GRUB_UBOOT_IH_OS_IRIX		9	/* Irix		*/
+#define GRUB_UBOOT_IH_OS_SCO		10	/* SCO		*/
+#define GRUB_UBOOT_IH_OS_DELL		11	/* Dell		*/
+#define GRUB_UBOOT_IH_OS_NCR		12	/* NCR		*/
+#define GRUB_UBOOT_IH_OS_LYNXOS		13	/* LynxOS	*/
+#define GRUB_UBOOT_IH_OS_VXWORKS		14	/* VxWorks	*/
+#define GRUB_UBOOT_IH_OS_PSOS		15	/* pSOS		*/
+#define GRUB_UBOOT_IH_OS_QNX		16	/* QNX		*/
+#define GRUB_UBOOT_IH_OS_U_BOOT		17	/* Firmware	*/
+#define GRUB_UBOOT_IH_OS_RTEMS		18	/* RTEMS	*/
+#define GRUB_UBOOT_IH_OS_ARTOS		19	/* ARTOS	*/
+#define GRUB_UBOOT_IH_OS_UNITY		20	/* Unity OS	*/
+#define GRUB_UBOOT_IH_OS_INTEGRITY		21	/* INTEGRITY	*/
+#define GRUB_UBOOT_IH_OS_OSE		22	/* OSE		*/
+
+/*
+ * CPU Architecture Codes (supported by Linux)
+ */
+#define GRUB_UBOOT_IH_ARCH_INVALID		0	/* Invalid CPU	*/
+#define GRUB_UBOOT_IH_ARCH_ALPHA		1	/* Alpha	*/
+#define GRUB_UBOOT_IH_ARCH_ARM		2	/* ARM		*/
+#define GRUB_UBOOT_IH_ARCH_I386		3	/* Intel x86	*/
+#define GRUB_UBOOT_IH_ARCH_IA64		4	/* IA64		*/
+#define GRUB_UBOOT_IH_ARCH_MIPS		5	/* MIPS		*/
+#define GRUB_UBOOT_IH_ARCH_MIPS64		6	/* MIPS	 64 Bit */
+#define GRUB_UBOOT_IH_ARCH_PPC		7	/* PowerPC	*/
+#define GRUB_UBOOT_IH_ARCH_S390		8	/* IBM S390	*/
+#define GRUB_UBOOT_IH_ARCH_SH		9	/* SuperH	*/
+#define GRUB_UBOOT_IH_ARCH_SPARC		10	/* Sparc	*/
+#define GRUB_UBOOT_IH_ARCH_SPARC64		11	/* Sparc 64 Bit */
+#define GRUB_UBOOT_IH_ARCH_M68K		12	/* M68K		*/
+#define GRUB_UBOOT_IH_ARCH_MICROBLAZE	14	/* MicroBlaze   */
+#define GRUB_UBOOT_IH_ARCH_NIOS2		15	/* Nios-II	*/
+#define GRUB_UBOOT_IH_ARCH_BLACKFIN	16	/* Blackfin	*/
+#define GRUB_UBOOT_IH_ARCH_AVR32		17	/* AVR32	*/
+#define GRUB_UBOOT_IH_ARCH_ST200	        18	/* STMicroelectronics ST200  */
+#define GRUB_UBOOT_IH_ARCH_SANDBOX		19	/* Sandbox architecture (test only) */
+#define GRUB_UBOOT_IH_ARCH_NDS32	        20	/* ANDES Technology - NDS32  */
+#define GRUB_UBOOT_IH_ARCH_OPENRISC        21	/* OpenRISC 1000  */
+
+/*
+ * Image Types
+ *
+ * "Standalone Programs" are directly runnable in the environment
+ *	provided by U-Boot; it is expected that (if they behave
+ *	well) you can continue to work in U-Boot after return from
+ *	the Standalone Program.
+ * "OS Kernel Images" are usually images of some Embedded OS which
+ *	will take over control completely. Usually these programs
+ *	will install their own set of exception handlers, device
+ *	drivers, set up the MMU, etc. - this means, that you cannot
+ *	expect to re-enter U-Boot except by resetting the CPU.
+ * "RAMDisk Images" are more or less just data blocks, and their
+ *	parameters (address, size) are passed to an OS kernel that is
+ *	being started.
+ * "Multi-File Images" contain several images, typically an OS
+ *	(Linux) kernel image and one or more data images like
+ *	RAMDisks. This construct is useful for instance when you want
+ *	to boot over the network using BOOTP etc., where the boot
+ *	server provides just a single image file, but you want to get
+ *	for instance an OS kernel and a RAMDisk image.
+ *
+ *	"Multi-File Images" start with a list of image sizes, each
+ *	image size (in bytes) specified by an "uint32_t" in network
+ *	byte order. This list is terminated by an "(uint32_t)0".
+ *	Immediately after the terminating 0 follow the images, one by
+ *	one, all aligned on "uint32_t" boundaries (size rounded up to
+ *	a multiple of 4 bytes - except for the last file).
+ *
+ * "Firmware Images" are binary images containing firmware (like
+ *	U-Boot or FPGA images) which usually will be programmed to
+ *	flash memory.
+ *
+ * "Script files" are command sequences that will be executed by
+ *	U-Boot's command interpreter; this feature is especially
+ *	useful when you configure U-Boot to use a real shell (hush)
+ *	as command interpreter (=> Shell Scripts).
+ */
+
+#define GRUB_UBOOT_IH_TYPE_INVALID		0	/* Invalid Image		*/
+#define GRUB_UBOOT_IH_TYPE_STANDALONE	1	/* Standalone Program		*/
+#define GRUB_UBOOT_IH_TYPE_KERNEL		2	/* OS Kernel Image		*/
+#define GRUB_UBOOT_IH_TYPE_RAMDISK		3	/* RAMDisk Image		*/
+#define GRUB_UBOOT_IH_TYPE_MULTI		4	/* Multi-File Image		*/
+#define GRUB_UBOOT_IH_TYPE_FIRMWARE	5	/* Firmware Image		*/
+#define GRUB_UBOOT_IH_TYPE_SCRIPT		6	/* Script file			*/
+#define GRUB_UBOOT_IH_TYPE_FILESYSTEM	7	/* Filesystem Image (any type)	*/
+#define GRUB_UBOOT_IH_TYPE_FLATDT		8	/* Binary Flat Device Tree Blob	*/
+#define GRUB_UBOOT_IH_TYPE_KWBIMAGE	9	/* Kirkwood Boot Image		*/
+#define GRUB_UBOOT_IH_TYPE_IMXIMAGE	10	/* Freescale IMXBoot Image	*/
+#define GRUB_UBOOT_IH_TYPE_UBLIMAGE	11	/* Davinci UBL Image		*/
+#define GRUB_UBOOT_IH_TYPE_OMAPIMAGE	12	/* TI OMAP Config Header Image	*/
+#define GRUB_UBOOT_IH_TYPE_AISIMAGE	13	/* TI Davinci AIS Image		*/
+#define GRUB_UBOOT_IH_TYPE_KERNEL_NOLOAD	14	/* OS Kernel Image, can run from any load address */
+#define GRUB_UBOOT_IH_TYPE_PBLIMAGE	15	/* Freescale PBL Boot Image	*/
+
+/*
+ * Compression Types
+ */
+#define GRUB_UBOOT_IH_COMP_NONE		0	/*  No	 Compression Used	*/
+#define GRUB_UBOOT_IH_COMP_GZIP		1	/* gzip	 Compression Used	*/
+#define GRUB_UBOOT_IH_COMP_BZIP2		2	/* bzip2 Compression Used	*/
+#define GRUB_UBOOT_IH_COMP_LZMA		3	/* lzma  Compression Used	*/
+#define GRUB_UBOOT_IH_COMP_LZO		4	/* lzo   Compression Used	*/
+
+#define GRUB_UBOOT_IH_MAGIC	0x27051956	/* Image Magic Number		*/
+#define GRUB_UBOOT_IH_NMLEN		32	/* Image Name Length		*/
+
+/*
+ * Legacy format image header,
+ * all data in network byte order (aka natural aka bigendian).
+ */
+struct grub_uboot_image_header {
+	grub_uint32_t	ih_magic;	/* Image Header Magic Number	*/
+	grub_uint32_t	ih_hcrc;	/* Image Header CRC Checksum	*/
+	grub_uint32_t	ih_time;	/* Image Creation Timestamp	*/
+	grub_uint32_t	ih_size;	/* Image Data Size		*/
+	grub_uint32_t	ih_load;	/* Data	 Load  Address		*/
+	grub_uint32_t	ih_ep;		/* Entry Point Address		*/
+	grub_uint32_t	ih_dcrc;	/* Image Data CRC Checksum	*/
+	grub_uint8_t	ih_os;		/* Operating System		*/
+	grub_uint8_t	ih_arch;	/* CPU architecture		*/
+	grub_uint8_t	ih_type;	/* Image Type			*/
+	grub_uint8_t	ih_comp;	/* Compression Type		*/
+	grub_uint8_t	ih_name[GRUB_UBOOT_IH_NMLEN];	/* Image Name		*/
+};
+
+#endif	/* __IMAGE_H__ */

=== modified file 'util/grub-install.in'
--- util/grub-install.in	2013-04-07 00:41:07 +0000
+++ util/grub-install.in	2013-04-08 10:42:46 +0000
@@ -833,14 +833,6 @@
 		-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-04-07 00:41:07 +0000
+++ util/grub-mkimage.c	2013-04-09 11:45:10 +0000
@@ -40,6 +40,8 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <grub/efi/pe32.h>
+#include <grub/uboot/image.h>
+#include <grub/arm/reloc.h>
 
 #define _GNU_SOURCE	1
 #include <argp.h>
@@ -1499,6 +1501,42 @@
       core_size = rom_size;
     }
     break;
+
+    case IMAGE_UBOOT:
+    {
+      struct grub_uboot_image_header *hdr;
+      GRUB_PROPERLY_ALIGNED_ARRAY (crc32_context, GRUB_MD_CRC32->contextsize);
+
+      hdr = xmalloc (core_size + sizeof (struct grub_uboot_image_header));
+      memcpy (hdr + 1, core_img, core_size);
+
+      memset (hdr, 0, sizeof (*hdr));
+      hdr->ih_magic = grub_cpu_to_be32_compile_time (GRUB_UBOOT_IH_MAGIC);
+      hdr->ih_time = grub_cpu_to_be32 (time (0));
+      hdr->ih_size = grub_cpu_to_be32 (core_size);
+      hdr->ih_load = grub_cpu_to_be32 (image_target->link_addr);
+      hdr->ih_ep = grub_cpu_to_be32 (image_target->link_addr);
+      hdr->ih_os = GRUB_UBOOT_IH_OS_LINUX;
+      hdr->ih_arch = GRUB_UBOOT_IH_ARCH_ARM;
+      hdr->ih_type = GRUB_UBOOT_IH_TYPE_KERNEL;
+      hdr->ih_comp = GRUB_UBOOT_IH_COMP_NONE;
+
+      GRUB_MD_CRC32->init(crc32_context);
+      GRUB_MD_CRC32->write(crc32_context, hdr + 1, core_size);
+      GRUB_MD_CRC32->final(crc32_context);
+      hdr->ih_dcrc = grub_get_unaligned32 (GRUB_MD_CRC32->read (crc32_context));
+
+      GRUB_MD_CRC32->init(crc32_context);
+      GRUB_MD_CRC32->write(crc32_context, hdr, sizeof (*hdr));
+      GRUB_MD_CRC32->final(crc32_context);
+      hdr->ih_hcrc = grub_get_unaligned32 (GRUB_MD_CRC32->read (crc32_context));
+
+      free (core_img);
+      core_img = (char *) hdr;
+      core_size += sizeof (struct grub_uboot_image_header);
+    }
+    break;
+
     case IMAGE_MIPS_ARC:
       {
 	char *ecoff_img;
@@ -1725,9 +1763,6 @@
 	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);

=== modified file 'util/grub-mkimagexx.c'
--- util/grub-mkimagexx.c	2013-04-07 00:41:07 +0000
+++ util/grub-mkimagexx.c	2013-04-09 12:21:25 +0000
@@ -60,9 +60,6 @@
 
 static Elf_Addr SUFFIX (entry_point);
 
-grub_err_t reloc_thm_call (grub_uint16_t *addr, Elf32_Addr sym_addr);
-grub_err_t reloc_thm_jump19 (grub_uint16_t *addr, Elf32_Addr sym_addr);
-
 /* Relocate symbols; note that this function overwrites the symbol table.
    Return the address of a start symbol.  */
 static Elf_Addr
@@ -553,19 +550,27 @@
 		   case R_ARM_THM_CALL:
 		   case R_ARM_THM_JUMP24:
 		     {
-		       grub_util_info ("  THM_JUMP24:\ttarget=0x%08x\toffset=(0x%08x)",	(unsigned int) target, sym_addr);
+		       grub_err_t err;
+		       grub_util_info ("  THM_JUMP24:\ttarget=0x%08lx\toffset=(0x%08x)",	(unsigned long) target, sym_addr);
 		       sym_addr -= offset;
 		       /* Thumb instructions can be 16-bit aligned */
-		       reloc_thm_call ((grub_uint16_t *) target, sym_addr);
+		       err = grub_arm_reloc_thm_call ((grub_uint16_t *) target,
+						      sym_addr);
+		       if (err)
+			 grub_util_error ("%s", grub_errmsg);
 		     }
 		     break;
 		   case R_ARM_THM_JUMP19:
 		     {
+		       grub_err_t err;
 		       grub_util_info ("  THM_JUMP19:\toffset=%d\t(0x%08x)",
 				       sym_addr, sym_addr);
 		       sym_addr -= offset;
 		       /* Thumb instructions can be 16-bit aligned */
-		       reloc_thm_jump19 ((grub_uint16_t *) target, sym_addr);
+		       err = grub_arm_reloc_thm_jump19 ((grub_uint16_t *) target,
+							sym_addr);
+		       if (err)
+			 grub_util_error ("%s", grub_errmsg);
 		     }
 		     break;
 		   default:


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

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

* Re: [PATCH 4/7] Support for ARM/U-Boot platforms
  2013-04-09 10:26       ` Leif Lindholm
@ 2013-04-09 17:26         ` Vladimir 'φ-coder/phcoder' Serbinenko
  0 siblings, 0 replies; 14+ messages in thread
From: Vladimir 'φ-coder/phcoder' Serbinenko @ 2013-04-09 17:26 UTC (permalink / raw)
  To: Leif Lindholm; +Cc: The development of GNU GRUB

[-- Attachment #1: Type: text/plain, Size: 1946 bytes --]

>> Trouble is that grub-install now rightfully warns about the lack of

>> platform-specific install.
>> What do we have to do to register the image at u-boot?
>> Put it in specific location?
> 
> EFI provides three very nice things:
> - Standardised partition and filesystem type for bootloaders.
> - Standardised runtime services for updating selected boot image.
> - Standardised "removable media" bootloader path.
> 
> U-Boot has neither, and different platforms use different mechanisms to
> affect boot images - some "prime" the enviroment with a uEnv.txt, some
> search around a predefined set of filesystems for boot scripts, some
> require you to manually "setenv" from within U-Boot.

Is environment stored in flash?

> 
> Debian use a special package called flash-kernel to abstract these things
> away.
> 

Can we use it?

> So in short, I think the only sane thing grub-install can do for arm-uboot,
> is what I already have it do - generate an image with the required modules
> embedded.

If that's the only thing we do, then the warning should be kept.

> Now, maybe it shouldn't be grub/arm-uboot/core.img, but that was
> what I ended up using.
> 

I'd prefer to keep this file and make a copy if necessarry.

>> Also you spoke about relocatable image but AFAICT header always
>> specifies load address. Do you have a way around it?
> 
> Well, it's not so much a way around it as somthing that almost ampounts
> to a new port (certainly a new image type).
> The proper fix would be to generate it as an ELF image _instead_, and use
> U-Boot's ELF loader support to load it properly.
> 

It's not really a new port. We already have ports using several image
formats, e.g. i386-pc, sparc64-ieee1275, mips-loongson.
Doesn't U-boot terminate services if it loads an ELF? How good is its
ELF support? Does it handle relocations correctly? If it doesn't we can
use -fPIC for kernel.


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 294 bytes --]

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

end of thread, other threads:[~2013-04-09 17:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-24 17:01 [PATCH 4/7] Support for ARM/U-Boot platforms Leif Lindholm
2013-04-01  2:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-01  9:53   ` Francesco Lavra
2013-04-01 11:24     ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-01 14:29       ` Francesco Lavra
2013-04-03 10:29         ` Leif Lindholm
2013-04-03 16:32   ` Leif Lindholm
2013-04-08 10:47     ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-09 10:26       ` Leif Lindholm
2013-04-09 17:26         ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-09  0:15 ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-09 11:39   ` Leif Lindholm
2013-04-09 11:55     ` Vladimir 'φ-coder/phcoder' Serbinenko
2013-04-09 12:45     ` Vladimir 'φ-coder/phcoder' Serbinenko

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.