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
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to