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.
This commit is contained in:
parent
6eb36900d3
commit
d2e4d8580d
@ -290,14 +290,25 @@ __elfN(loadimage)(struct preloaded_file *fp, elf_file_t ef, u_int64_t off)
|
||||
} 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
|
||||
|
Loading…
x
Reference in New Issue
Block a user