svn commit: r247301 - head/sys/boot/common
Ian Lepore
ian at FreeBSD.org
Tue Feb 26 03:24:46 UTC 2013
Author: ian
Date: Tue Feb 26 03:24:45 2013
New Revision: 247301
URL: http://svnweb.freebsd.org/changeset/base/247301
Log:
Adjust the arm kernel entry point address properly regardless of whether the
e_entry field holds a physical or a virtual address. Add a comment block
that explains the assumptions being made by the adjustment code.
Modified:
head/sys/boot/common/load_elf.c
Modified: head/sys/boot/common/load_elf.c
==============================================================================
--- head/sys/boot/common/load_elf.c Tue Feb 26 02:13:02 2013 (r247300)
+++ head/sys/boot/common/load_elf.c Tue Feb 26 03:24:45 2013 (r247301)
@@ -290,14 +290,25 @@ __elfN(loadimage)(struct preloaded_file
} else
off = 0;
#elif defined(__arm__)
- if (off & 0xf0000000u) {
- off = -(off & 0xf0000000u);
- ehdr->e_entry += off;
+ /*
+ * The elf headers in some kernels specify virtual addresses in all
+ * header fields. More recently, the e_entry and p_paddr fields are the
+ * proper physical addresses. Even when the p_paddr fields are correct,
+ * the MI code below uses the p_vaddr fields with an offset added for
+ * loading (doing so is arguably wrong). To make loading work, we need
+ * an offset that represents the difference between physical and virtual
+ * addressing. ARM kernels are always linked at 0xC0000000. Depending
+ * on the headers, the offset value passed in may be physical or virtual
+ * (because it typically comes from e_entry), but we always replace
+ * whatever is passed in with the va<->pa offset. On the other hand, we
+ * only adjust the entry point if it's a virtual address to begin with.
+ */
+ off = -0xc0000000u;
+ if ((ehdr->e_entry & 0xc0000000u) == 0xc000000u)
+ ehdr->e_entry += off;
#ifdef ELF_VERBOSE
- printf("Converted entry 0x%08x\n", ehdr->e_entry);
+ printf("ehdr->e_entry 0x%08x, va<->pa off %llx\n", ehdr->e_entry, off);
#endif
- } else
- off = 0;
#else
off = 0; /* other archs use direct mapped kernels */
#endif
More information about the svn-src-all
mailing list