summaryrefslogtreecommitdiffstats
path: root/sys/boot/common/load_elf.c
diff options
context:
space:
mode:
authornwhitehorn <nwhitehorn@FreeBSD.org>2015-01-31 07:22:29 +0000
committernwhitehorn <nwhitehorn@FreeBSD.org>2015-01-31 07:22:29 +0000
commit7551e7e8833f8cfc60c758b438fbbd912bc3121c (patch)
tree791402888b91fc41ca7c79ea6846753005d5b6fa /sys/boot/common/load_elf.c
parentaa993eaf7222e8015ec03249aa68da689c92132a (diff)
downloadFreeBSD-src-7551e7e8833f8cfc60c758b438fbbd912bc3121c.zip
FreeBSD-src-7551e7e8833f8cfc60c758b438fbbd912bc3121c.tar.gz
Add support for booting relocatable kernels on PowerPC.
Diffstat (limited to 'sys/boot/common/load_elf.c')
-rw-r--r--sys/boot/common/load_elf.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/sys/boot/common/load_elf.c b/sys/boot/common/load_elf.c
index 4c801e9..6ab2ba4 100644
--- a/sys/boot/common/load_elf.c
+++ b/sys/boot/common/load_elf.c
@@ -175,7 +175,33 @@ __elfN(loadfile_raw)(char *filename, u_int64_t dest,
* Check to see what sort of module we are.
*/
kfp = file_findfile(NULL, __elfN(kerneltype));
- if (ehdr->e_type == ET_DYN) {
+#ifdef __powerpc__
+ /*
+ * Kernels can be ET_DYN, so just assume the first loaded object is the
+ * kernel. This assumption will be checked later.
+ */
+ if (kfp == NULL)
+ ef.kernel = 1;
+#endif
+ if (ef.kernel || ehdr->e_type == ET_EXEC) {
+ /* Looks like a kernel */
+ if (kfp != NULL) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: kernel already loaded\n");
+ err = EPERM;
+ goto oerr;
+ }
+ /*
+ * Calculate destination address based on kernel entrypoint
+ */
+ dest = (ehdr->e_entry & ~PAGE_MASK);
+ if (dest == 0) {
+ printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: not a kernel (maybe static binary?)\n");
+ err = EPERM;
+ goto oerr;
+ }
+ ef.kernel = 1;
+
+ } else if (ehdr->e_type == ET_DYN) {
/* Looks like a kld module */
if (multiboot != 0) {
printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: can't load module as multiboot\n");
@@ -195,24 +221,6 @@ __elfN(loadfile_raw)(char *filename, u_int64_t dest,
/* Looks OK, got ahead */
ef.kernel = 0;
- } else if (ehdr->e_type == ET_EXEC) {
- /* Looks like a kernel */
- if (kfp != NULL) {
- printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: kernel already loaded\n");
- err = EPERM;
- goto oerr;
- }
- /*
- * Calculate destination address based on kernel entrypoint
- */
- dest = (ehdr->e_entry & ~PAGE_MASK);
- if (dest == 0) {
- printf("elf" __XSTRING(__ELF_WORD_SIZE) "_loadfile: not a kernel (maybe static binary?)\n");
- err = EPERM;
- goto oerr;
- }
- ef.kernel = 1;
-
} else {
err = EFTYPE;
goto oerr;
OpenPOWER on IntegriCloud