GRUB port for ARMv7-A U-Boot
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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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.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
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/uboot/datetime.c +41 -0
41 lines not on this page · raw message
grub-core/loader/arm/uboot/linux.c +379 -0
379 lines not on this page · raw message
grub-core/term/uboot/console.c +143 -0
143 lines not on this page · raw message
include/grub/elf.h +54 -11
65 lines not on this page · raw message
include/grub/uboot/api_public.h +184 -0
184 lines not on this page · 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
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.