Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 30 Dec 2014 20:22:43 +0000 (UTC)
From:      Nathan Whitehorn <nwhitehorn@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r276420 - user/nwhitehorn/kboot/powerpc/kboot
Message-ID:  <201412302022.sBUKMhMN038773@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: nwhitehorn
Date: Tue Dec 30 20:22:43 2014
New Revision: 276420
URL: https://svnweb.freebsd.org/changeset/base/276420

Log:
  Get FreeBSD kexec'ing. The trampoline needs to relocate the kernel back to
  where it is supposed to be (on top of Linux, usually) for this to actually
  do anything useful, but we're now getting much closer.

Modified:
  user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S
  user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h
  user/nwhitehorn/kboot/powerpc/kboot/main.c
  user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c

Modified: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S	Tue Dec 30 20:20:18 2014	(r276419)
+++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S	Tue Dec 30 20:22:43 2014	(r276420)
@@ -44,3 +44,19 @@ ENTRY(host_select)
 	sc
 	blr
 
+ENTRY(kexec_load)
+	lis	%r4,nkexec_segments@ha
+	ori	%r4,%r4,nkexec_segments@l
+	lwz	%r4,0(%r4)
+	lis	%r5,loaded_segments@ha
+	ori	%r5,%r5,loaded_segments@l
+	lis	%r6,21	# KEXEC_ARCH_PPC64
+	li	%r0,268 # __NR_kexec_load
+	sc
+	blr
+
+ENTRY(host_reboot)
+	li %r0,88 # SYS_reboot
+	sc
+	blr
+

Modified: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h	Tue Dec 30 20:20:18 2014	(r276419)
+++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h	Tue Dec 30 20:22:43 2014	(r276420)
@@ -44,5 +44,7 @@ struct host_timeval {
 int host_gettimeofday(struct host_timeval *a, void *b);
 int host_select(int nfds, long *readfds, long *writefds, long *exceptfds,
     struct host_timeval *timeout);
+int kexec_load(vm_offset_t start);
+int host_reboot(int, int, int, void *);
 
 #endif

Modified: user/nwhitehorn/kboot/powerpc/kboot/main.c
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/main.c	Tue Dec 30 20:20:18 2014	(r276419)
+++ user/nwhitehorn/kboot/powerpc/kboot/main.c	Tue Dec 30 20:22:43 2014	(r276420)
@@ -181,6 +181,7 @@ get_phys_buffer(vm_offset_t dest, const 
 {
 	int i = 0;
 	const size_t segsize = 2*1024*1024;
+	dest += 32*1024*1024; /* XXX Make nonoverlapping somehow */
 
 	for (i = 0; i < nkexec_segments; i++) {
 		if (dest >= (vm_offset_t)loaded_segments[i].mem &&

Modified: user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c	Tue Dec 30 20:20:18 2014	(r276419)
+++ user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c	Tue Dec 30 20:22:43 2014	(r276420)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <stand.h>
 
 #include "bootstrap.h"
+#include "host_syscall.h"
 
 extern char		end[];
 extern vm_offset_t	reloc;	/* From <arch>/conf.c */
@@ -65,6 +66,7 @@ ppc64_elf_exec(struct preloaded_file *fp
 	Elf_Ehdr		*e;
 	int			error;
 	uint32_t		*trampoline;
+	vm_offset_t		trampolinebase = 32*1024*1024; /* XXX */
 
 	if ((fmp = file_findmetadata(fp, MODINFOMD_ELFHDR)) == NULL) {
 		return(EFTYPE);
@@ -84,12 +86,21 @@ ppc64_elf_exec(struct preloaded_file *fp
 
 	trampoline[6] = mdp;
 	trampoline[7] = sizeof(mdp);
-	printf("Kernel entry at %#x ...\n", e->e_entry);
+	printf("Kernel entry at %#jx ...\n", e->e_entry);
 
 	dev_cleanup();
 
-	archsw.arch_copyin(trampoline, 0 /* XXX */, szkerneltramp);
-	/* XXX kexec_load, reboot */
+	archsw.arch_copyin(trampoline, trampolinebase, szkerneltramp);
+	free(trampoline);
+
+	error = kexec_load(trampolinebase);
+	if (error != 0)
+		panic("kexec_load returned error: %d", error);
+	error = host_reboot(0xfee1dead, 672274793,
+	    0x45584543 /* LINUX_REBOOT_CMD_KEXEC */, NULL);
+	if (error != 0)
+		panic("reboot returned error: %d", error);
+	while (1) {}
 
 	panic("exec returned");
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201412302022.sBUKMhMN038773>