Skip to contentSkip to conversation

GRUB port for ARMv7-A U-Boot

RFC New Leif Lindholm 1 participant 1 message Nov 20, 2012 Kbuild

lore
Share & tools
lore
#0 lore raw

RFC v2 1/1 GRUB port for ARMv7-A U-Boot

This is an updated patch for enabling support for running under ARMv7-A U-Boot, based on some of Colin's feedback during UDS.

This is somewhat better tested from a usage-standpoint, having added necessary support to commands like grub-install.

The version contained in this patch is also available as revision 4613 from lp:~leif-lindholm/linaro-grub/arm-uboot.
Basic build and usage documentation is being kept at
https://wiki.linaro.org/LEG/Kernel/GRUB

Third-party code
----------------
I have rewritten the U-Boot glue layer in as much of a clean-room way as can be done with a fairly trivial piece of code that you've already read through a lot. This also gets rid of the special crc32 code. The api_public.h header (GPLv2+, (c) Rafal Jaworowski) is still included.

The standalone "libgcc" helper implementation remains - there is no safe workaround for the __clear_cache() issue, and requiring a parallel embedded toolchain specifically for building GRUB does not make sense. Nevertheless, all of the included code is (c) FSF.

libfdt (see below).

FDT
---
I did look into reusing the openfirmware code for device-tree handling, but found no actual handling code in there. All actual scanning and manipulation is performed through callbacks into openfirmware (using IEEE1275_CALL_ENTRY_FN()).
So now I have tried instead to import libfdt the way gcrypt and Unicode is imported. It generates a grub-core/Makefile.libfdt.def exporting a library which is for now used only by the Linux loader.

Other
-----
The hack of calling uboot-mkimage from within grub-mkimage is now gone - this is done more correctly by grub-install instead.

grub-install uses the UUID "trick" to make Grub find its modules now, alleviating the need for special U-Boot environment variables.

Limitations
-----------
- Dynamic linker implemented only for ARMv7-A Thumb instruction set.
- Currently runs uncached, with MMU off.
- No support for ATAG parsing or rewriting, only supports device tree as a means of passing information to the Linux kernel. (If an ATAG list is passed from U-Boot, it can be passed on unmodified, but the "linux" command will not pass on command line parameters.)
- Currently a statically linked kernel, requires RAM at 0x08000000.
- No write support for block devices. Not provided by U-Boot.

Missing
-------
Still, the testbench support and qemu configurations for grub-shell and its dependents.
grub-mkrescue

Potential future developments
-----------------------------
- Implement networking support.
- Make GRUB kernel a fully relocateable ELF.
- Implement chainloader.
- Enable caches/MMU.

Comments welcome.

autogen.sh +4 -1
diff -purN trunk/autogen.sh arm-uboot/autogen.sh
@@ -14,6 +14,9 @@ python util/import_unicode.py unicode/Un
 echo "Importing libgcrypt..."
 python util/import_gcry.py grub-core/lib/libgcrypt/ grub-core
 
+echo "Importing libfdt..."
+python util/import_libfdt.py grub-core/lib/dtc/ grub-core
+
 echo "Creating Makefile.tpl..."
 python gentpl.py | sed -e '/^$/{N;/^\n$/D;}' > Makefile.tpl
 
@@ -27,7 +30,7 @@ if [ "x${GRUB_CONTRIB}" != x ]; then
 fi
 
 UTIL_DEFS='Makefile.util.def Makefile.utilgcry.def'
-CORE_DEFS='grub-core/Makefile.core.def grub-core/Makefile.gcry.def'
+CORE_DEFS='grub-core/Makefile.core.def grub-core/Makefile.gcry.def grub-core/Makefile.libfdt.def'
 
 for extra in contrib/*/Makefile.util.def; do
   if test -e "$extra"; then
.bzrignore +2 -0
diff -purN trunk/.bzrignore arm-uboot/.bzrignore
@@ -128,6 +128,7 @@ depcomp
 mdate-sh
 texinfo.tex
 grub-core/lib/libgcrypt-grub
+grub-core/lib/dtc-grub
 **/.deps
 **/.deps-util
 **/.deps-core
@@ -136,6 +137,7 @@ Makefile.util.am
 contrib
 grub-core/Makefile.core.am
 grub-core/Makefile.gcry.def
+grub-core/Makefile.libfdt.def
 grub-core/contrib
 grub-core/gdb_grub
 grub-core/genmod.sh
conf/Makefile.common +14 -0
diff -purN trunk/conf/Makefile.common arm-uboot/conf/Makefile.common
@@ -37,6 +37,12 @@ if COND_sparc64_ieee1275
   CFLAGS_PLATFORM += -mno-app-regs
   LDFLAGS_PLATFORM = -Wl,-melf64_sparc -mno-relax
 endif
+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
+  CCASFLAGS_PLATFORM = -Wa,-mimplicit-it=thumb
+endif
 
 # Other options
 
@@ -58,6 +64,7 @@ if ! COND_i386_coreboot
 if ! COND_i386_multiboot
 if ! COND_i386_ieee1275
 if ! COND_x86_64_efi
+if ! COND_arm
 LDADD_KERNEL += -lgcc
 endif
 endif
@@ -66,9 +73,14 @@ endif
 endif
 endif
 endif
+endif
 
 CFLAGS_KERNEL = $(CFLAGS_CPU) $(CFLAGS_PLATFORM) -ffreestanding
+if ! COND_arm
 LDFLAGS_KERNEL = $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC) -static-libgcc
+else
+LDFLAGS_KERNEL = $(LDFLAGS_CPU) $(LDFLAGS_PLATFORM) -nostdlib $(TARGET_LDFLAGS_OLDMAGIC)
+endif
 CPPFLAGS_KERNEL = $(CPPFLAGS_CPU) $(CPPFLAGS_PLATFORM)
 CCASFLAGS_KERNEL = $(CCASFLAGS_CPU) $(CCASFLAGS_PLATFORM)
 if COND_CYGWIN
@@ -108,6 +120,8 @@ CPPFLAGS_GCRY = -I$(top_srcdir)/grub-cor
 CFLAGS_GNULIB = -Wno-undef -Wno-sign-compare -Wno-unused -Wno-unused-parameter -Wno-redundant-decls -Wno-unreachable-code -Wno-conversion -Wno-old-style-definition -Wno-unsafe-loop-optimizations
 CPPFLAGS_GNULIB = -I$(top_builddir)/grub-core/gnulib -I$(top_srcdir)/grub-core/gnulib
 
+CPPFLAGS_LIBFDT = -I$(top_srcdir)/grub-core/lib/dtc-grub/libfdt
+
 CFLAGS_POSIX = -fno-builtin
 CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap
 
configure.ac +11 -1
diff -purN trunk/configure.ac arm-uboot/configure.ac
@@ -79,6 +79,9 @@ case "$target_cpu" in
                 target_cpu=mips;
 		machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_CPU_MIPS=1";
 		;;
+  arm*)
+		target_cpu=arm;
+		;;
 esac
 
 # Specify the platform (such as firmware).
@@ -99,6 +102,7 @@ if test "x$with_platform" = x; then
     mipsel-*) platform=loongson ;;
     mips-*) platform=arc ;;
     ia64-*) platform=efi ;;
+    arm-*) platform=uboot ;;
     *) AC_MSG_ERROR([unsupported CPU: "$target_cpu"]) ;;
   esac
 else
@@ -133,6 +137,7 @@ case "$target_cpu"-"$platform" in
   mipsel-yeeloong) platform=loongson ;;
   mipsel-fuloong) platform=loongson ;;
   mipsel-loongson) ;;
+  arm-uboot) platform=uboot ;;
   *-emu) ;;
   *) AC_MSG_ERROR([platform "$platform" is not supported for target CPU "$target_cpu"]) ;;
 esac
@@ -164,6 +169,7 @@ case "$platform" in
   multiboot)	machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MULTIBOOT=1" ;;
   efi)		machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EFI=1" ;;
   ieee1275)	machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_IEEE1275=1" ;;
+  uboot)	machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_UBOOT=1" ;;
   qemu)		machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_QEMU=1" ;;
   pc)		machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_PCBIOS=1" ;;
   emu)		machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_EMU=1" ;;
@@ -172,6 +178,7 @@ case "$platform" in
   arc)	machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARC=1" ;;
 esac
 case "$target_cpu" in
+  arm)      	machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_ARM=1" ;;
   mips |mipsel)      	machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_MIPS=1" ;;
   sparc64)      machine_CPPFLAGS="$machine_CPPFLAGS -DGRUB_MACHINE_SPARC64=1" ;;
 esac
@@ -669,7 +676,8 @@ else
 CFLAGS="$TARGET_CFLAGS -nostdlib -Wl,--defsym,___main=0x8100 -Wno-error"
 fi
 CPPFLAGS="$TARGET_CPPFLAGS"
-if test x$target_cpu = xi386 || test x$target_cpu = xx86_64 ; then
+
+if test x$target_cpu = xi386 || test x$target_cpu = xx86_64 || test x$target_cpu = xarm ; then
 LIBS=
 else
 LIBS=-lgcc
@@ -1116,6 +1124,8 @@ AM_CONDITIONAL([COND_powerpc_ieee1275],
 AM_CONDITIONAL([COND_mips], [test x$target_cpu = xmips -o x$target_cpu = xmipsel])
 AM_CONDITIONAL([COND_mipsel], [test x$target_cpu = xmipsel])
 AM_CONDITIONAL([COND_mipseb], [test x$target_cpu = xmips])
+AM_CONDITIONAL([COND_arm], [test x$target_cpu = xarm ])
+AM_CONDITIONAL([COND_arm_uboot], [test x$target_cpu = xarm -a x$platform = xuboot])
 
 AM_CONDITIONAL([COND_HOST_HURD], [test x$host_kernel = xhurd])
 AM_CONDITIONAL([COND_HOST_LINUX], [test x$host_kernel = xlinux])
gentpl.py +7 -2
diff -purN trunk/gentpl.py arm-uboot/gentpl.py
@@ -23,7 +23,7 @@ GRUB_PLATFORMS = [ "emu", "i386_pc", "i3
                    "i386_multiboot", "i386_ieee1275", "x86_64_efi",
                    "mips_loongson", "sparc64_ieee1275",
                    "powerpc_ieee1275", "mips_arc", "ia64_efi",
-                   "mips_qemu_mips" ]
+                   "mips_qemu_mips", "arm_uboot" ]
 
 GROUPS = {}
 
@@ -36,10 +36,12 @@ GROUPS["x86"]      = GROUPS["i386"] + GR
 GROUPS["mips"]     = [ "mips_loongson", "mips_qemu_mips", "mips_arc" ]
 GROUPS["sparc64"]  = [ "sparc64_ieee1275" ]
 GROUPS["powerpc"]  = [ "powerpc_ieee1275" ]
+GROUPS["arm"]      = [ "arm_uboot" ]
 
 # Groups based on firmware
 GROUPS["efi"]  = [ "i386_efi", "x86_64_efi", "ia64_efi" ]
 GROUPS["ieee1275"]   = [ "i386_ieee1275", "sparc64_ieee1275", "powerpc_ieee1275" ]
+GROUPS["uboot"] = [ "arm_uboot" ]
 
 # emu is a special case so many core functionality isn't needed on this platform
 GROUPS["noemu"]   = GRUB_PLATFORMS[:]; GROUPS["noemu"].remove("emu")
@@ -57,10 +59,13 @@ GROUPS["videomodules"]   = GRUB_PLATFORM
 for i in GROUPS["videoinkernel"]: GROUPS["videomodules"].remove(i)
 
 # Similar for terminfo
-GROUPS["terminfoinkernel"] = ["mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["ieee1275"];
+GROUPS["terminfoinkernel"] = ["mips_loongson", "mips_arc", "mips_qemu_mips" ] + GROUPS["ieee1275"] + GROUPS["uboot"];
 GROUPS["terminfomodule"]   = GRUB_PLATFORMS[:];
 for i in GROUPS["terminfoinkernel"]: GROUPS["terminfomodule"].remove(i)
 
+# Flattened Device Trees (FDT)
+GROUPS["fdt"] = [ "arm_uboot" ]
+
 # Miscelaneous groups schedulded to disappear in future
 GROUPS["i386_coreboot_multiboot_qemu"] = ["i386_coreboot", "i386_multiboot", "i386_qemu"]
 GROUPS["nopc"] = GRUB_PLATFORMS[:]; GROUPS["nopc"].remove("i386_pc")
grub-core/disk/uboot/ubootdisk.c +345 -0

345 lines not on this page · raw message

grub-core/kern/arm/dl.c +327 -0

327 lines not on this page · raw message

grub-core/kern/arm/uboot/startup.S +163 -0

163 lines not on this page · raw message

grub-core/kern/main.c +4 -2
diff -purN trunk/grub-core/kern/main.c arm-uboot/grub-core/kern/main.c
@@ -30,8 +30,10 @@
 #include <grub/reader.h>
 #include <grub/parser.h>
 
-/* This is actualy platform-independant but used only on loongson and sparc.  */
-#if defined (GRUB_MACHINE_MIPS_LOONGSON) || defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64)
+/* This is actualy platform-independant but used only on some platforms.  */
+#if defined (GRUB_MACHINE_MIPS_LOONGSON) || \
+  defined (GRUB_MACHINE_MIPS_QEMU_MIPS) || defined (GRUB_MACHINE_SPARC64) || \
+  defined (GRUB_MACHINE_ARM)
 grub_addr_t
 grub_modules_get_end (void)
 {
grub-core/kern/uboot/hw.c +111 -0

111 lines not on this page · raw message

grub-core/kern/uboot/init.c +169 -0

169 lines not on this page · raw message

grub-core/kern/uboot/uboot.c +363 -0

363 lines not on this page · raw message

grub-core/lib/arm/libgcc.S +299 -0

299 lines not on this page · raw message

grub-core/lib/arm/setjmp.S +57 -0

57 lines not on this page · raw message

grub-core/lib/dtc/libfdt/fdt.c +222 -0

222 lines not on this page · raw message

grub-core/lib/dtc/libfdt/fdt.h +60 -0

60 lines not on this page · raw message

grub-core/lib/dtc/libfdt/fdt_ro.c +574 -0

574 lines not on this page · raw message

grub-core/lib/dtc/libfdt/fdt_rw.c +465 -0

138 lines not on this page · raw message

grub-core/lib/dtc/libfdt/fdt_strerror.c +96 -0

96 lines not on this page · raw message

grub-core/lib/dtc/libfdt/fdt_sw.c +256 -0

256 lines not on this page · raw message

grub-core/lib/dtc/libfdt/fdt_wip.c +118 -0

118 lines not on this page · raw message

grub-core/lib/dtc/libfdt/libfdt_env.h +23 -0
diff -purN trunk/grub-core/lib/dtc/libfdt/libfdt_env.h arm-uboot/grub-core/lib/dtc/libfdt/libfdt_env.h

Lines of this file are not shown. View the raw message.

grub-core/lib/dtc/libfdt/libfdt.h +1235 -0

1,235 lines not on this page · raw message

grub-core/lib/dtc/libfdt/libfdt_internal.h +95 -0

95 lines not on this page · raw message

grub-core/lib/dtc/libfdt/Makefile.libfdt +10 -0
diff -purN trunk/grub-core/lib/dtc/libfdt/Makefile.libfdt arm-uboot/grub-core/lib/dtc/libfdt/Makefile.libfdt

Lines of this file are not shown. View the raw message.

grub-core/lib/dtc/libfdt/TODO +3 -0
diff -purN trunk/grub-core/lib/dtc/libfdt/TODO arm-uboot/grub-core/lib/dtc/libfdt/TODO

Lines of this file are not shown. View the raw message.

grub-core/lib/dtc/libfdt/version.lds +54 -0

54 lines not on this page · raw message

grub-core/lib/dtc/libfdt-grub.diff +63 -0

63 lines not on this page · raw message

grub-core/lib/setjmp.S +2 -0
diff -purN trunk/grub-core/lib/setjmp.S arm-uboot/grub-core/lib/setjmp.S

Lines of this file are not shown. View the raw message.

grub-core/lib/uboot/datetime.c +41 -0

41 lines not on this page · raw message

grub-core/lib/uboot/halt.c +31 -0
diff -purN trunk/grub-core/lib/uboot/halt.c arm-uboot/grub-core/lib/uboot/halt.c

Lines of this file are not shown. View the raw message.

grub-core/lib/uboot/reboot.c +30 -0
diff -purN trunk/grub-core/lib/uboot/reboot.c arm-uboot/grub-core/lib/uboot/reboot.c

Lines of this file are not shown. View the raw message.

grub-core/loader/arm/uboot/linux.c +379 -0

379 lines not on this page · raw message

grub-core/Makefile.am +5 -0
diff -purN trunk/grub-core/Makefile.am arm-uboot/grub-core/Makefile.am

Lines of this file are not shown. View the raw message.

grub-core/Makefile.core.def +23 -0
diff -purN trunk/grub-core/Makefile.core.def arm-uboot/grub-core/Makefile.core.def

Lines of this file are not shown. View the raw message.

grub-core/term/terminfo.c +3 -1
diff -purN trunk/grub-core/term/terminfo.c arm-uboot/grub-core/term/terminfo.c

Lines of this file are not shown. View the raw message.

grub-core/term/uboot/console.c +143 -0

143 lines not on this page · raw message

include/grub/arm/linux.h +34 -0
diff -purN trunk/include/grub/arm/linux.h arm-uboot/include/grub/arm/linux.h

Lines of this file are not shown. View the raw message.

include/grub/arm/time.h +29 -0
diff -purN trunk/include/grub/arm/time.h arm-uboot/include/grub/arm/time.h

Lines of this file are not shown. View the raw message.

include/grub/arm/types.h +34 -0
diff -purN trunk/include/grub/arm/types.h arm-uboot/include/grub/arm/types.h

Lines of this file are not shown. View the raw message.

include/grub/arm/uboot/kernel.h +32 -0
diff -purN trunk/include/grub/arm/uboot/kernel.h arm-uboot/include/grub/arm/uboot/kernel.h

Lines of this file are not shown. View the raw message.

include/grub/disk.h +1 -0
diff -purN trunk/include/grub/disk.h arm-uboot/include/grub/disk.h

Lines of this file are not shown. View the raw message.

include/grub/elf.h +54 -11

65 lines not on this page · raw message

include/grub/libgcc.h +11 -0
diff -purN trunk/include/grub/libgcc.h arm-uboot/include/grub/libgcc.h

Lines of this file are not shown. View the raw message.

include/grub/offsets.h +5 -0
diff -purN trunk/include/grub/offsets.h arm-uboot/include/grub/offsets.h

Lines of this file are not shown. View the raw message.

include/grub/symbol.h +9 -5
diff -purN trunk/include/grub/symbol.h arm-uboot/include/grub/symbol.h

Lines of this file are not shown. View the raw message.

include/grub/uboot/api_public.h +184 -0

184 lines not on this page · raw message

include/grub/uboot/console.h +29 -0
diff -purN trunk/include/grub/uboot/console.h arm-uboot/include/grub/uboot/console.h

Lines of this file are not shown. View the raw message.

include/grub/uboot/disk.h +44 -0

44 lines not on this page · raw message

include/grub/uboot/uboot.h +148 -0

148 lines not on this page · raw message

Makefile.util.def +1 -0
diff -purN trunk/Makefile.util.def arm-uboot/Makefile.util.def

Lines of this file are not shown. View the raw message.

util/grub-install.in +11 -1
diff -purN trunk/util/grub-install.in arm-uboot/util/grub-install.in

Lines of this file are not shown. View the raw message.

util/grub-mkimage.c +26 -2
diff -purN trunk/util/grub-mkimage.c arm-uboot/util/grub-mkimage.c

Lines of this file are not shown. View the raw message.

util/import_libfdt.py +103 -0

103 lines not on this page · raw message

The rest of this diff is not shown. View the raw message.

Part of the diff is not shown here. View the raw message.