svn commit: r276361 - user/nwhitehorn/kboot/powerpc/kboot

Nathan Whitehorn nwhitehorn at FreeBSD.org
Mon Dec 29 14:14:42 UTC 2014


Author: nwhitehorn
Date: Mon Dec 29 14:14:40 2014
New Revision: 276361
URL: https://svnweb.freebsd.org/changeset/base/276361

Log:
  Get the kernel loaded into some kexec_segments. The next hazard here is
  to write the equivalent of the kexec purgatory code to call into the kernel
  with useful arguments. The particular difficulty is in compiling a working
  device tree from the host kernel.

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	Mon Dec 29 13:50:59 2014	(r276360)
+++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.S	Mon Dec 29 14:14:40 2014	(r276361)
@@ -25,11 +25,7 @@ ENTRY(host_close)
 	sc
 	blr
 
-ENTRY(host_getmem) /* addr, size */
-	li %r5, 3 # PROT_READ | PROT_WRITE
-	li %r6, 0x1000 # MAP_ANON
-	li %r7, -1
-	li %r8, 0
+ENTRY(host_mmap)
 	li %r0, 477 # SYS_mmap
 	sc
 	blr

Modified: user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h	Mon Dec 29 13:50:59 2014	(r276360)
+++ user/nwhitehorn/kboot/powerpc/kboot/host_syscall.h	Mon Dec 29 14:14:40 2014	(r276361)
@@ -35,6 +35,7 @@ ssize_t host_write(int fd, const void *b
 ssize_t host_seek(int fd, uint64_t offset, int whence);
 int host_open(char *path, int flags, int mode);
 int host_close(int fd);
-void *host_getmem(void *addr, size_t len);
+void *host_mmap(void *addr, size_t len, int prot, int flags, int fd, off_t);
+#define host_getmem(size) host_mmap(0, size, 3 /* RW */, 0x1000 /* ANON */, -1, 0);
 
 #endif

Modified: user/nwhitehorn/kboot/powerpc/kboot/main.c
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/main.c	Mon Dec 29 13:50:59 2014	(r276360)
+++ user/nwhitehorn/kboot/powerpc/kboot/main.c	Mon Dec 29 14:14:40 2014	(r276361)
@@ -62,7 +62,7 @@ kboot_getdev(void **vdev, const char *de
 		filepath = strchr(devspec, ':') + 1;
 	} else {
 		devpath = getenv("currdev");
-		filepath = &devspec[1];
+		filepath = devspec;
 	}
 
 	for (i = 0; (dv = devsw[i]) != NULL; i++) {
@@ -92,12 +92,13 @@ int
 main(int argc, const char **argv)
 {
 	void *heapbase;
+	const size_t heapsize = 15*1024*1024;
 
 	/*
 	 * Set the heap to one page after the end of the loader.
 	 */
-	heapbase = host_getmem(0, 0x100000);
-	setheap(heapbase, heapbase + 0x100000);
+	heapbase = host_getmem(heapsize);
+	setheap(heapbase, heapbase + heapsize);
 
 	/*
 	 * Set up console.
@@ -156,17 +157,76 @@ time(time_t *tloc)
 	return (rv);
 }
 
+struct kexec_segment {
+	void *buf;
+	size_t bufsz;
+	void *mem;
+	size_t memsz;
+};
+
+struct kexec_segment loaded_segments[128];
+int nkexec_segments = 0;
+
+static ssize_t
+get_phys_buffer(vm_offset_t dest, const size_t len, void **buf)
+{
+	int i = 0;
+	const size_t segsize = 2*1024*1024;
+
+	for (i = 0; i < nkexec_segments; i++) {
+		if (dest >= (vm_offset_t)loaded_segments[i].mem &&
+		    dest < (vm_offset_t)loaded_segments[i].mem +
+		    loaded_segments[i].memsz)
+			goto out;
+	}
+
+	loaded_segments[nkexec_segments].buf = host_getmem(segsize);
+	loaded_segments[nkexec_segments].bufsz = segsize;
+	loaded_segments[nkexec_segments].mem = (void *)rounddown2(dest,segsize);
+	loaded_segments[nkexec_segments].memsz = segsize;
+	i = nkexec_segments;
+	nkexec_segments++;
+
+out:
+	*buf = loaded_segments[i].buf + (dest -
+	    (vm_offset_t)loaded_segments[i].mem);
+	return (min(len,loaded_segments[i].bufsz - (dest -
+	    (vm_offset_t)loaded_segments[i].mem)));
+}
+
 ssize_t
 kboot_copyin(const void *src, vm_offset_t dest, const size_t len)
 {
-	bcopy(src, (void *)dest, len);
+	ssize_t segsize, remainder;
+	void *destbuf;
+
+	remainder = len;
+	do {
+		segsize = get_phys_buffer(dest, remainder, &destbuf);
+		bcopy(src, destbuf, segsize);
+		remainder -= segsize;
+		src += segsize;
+		dest += segsize;
+	} while (remainder > 0);
+
 	return (len);
 }
 
 ssize_t
 kboot_copyout(vm_offset_t src, void *dest, const size_t len)
 {
-	bcopy((void *)src, dest, len);
+	ssize_t segsize, remainder;
+	void *srcbuf;
+
+	remainder = len;
+	do {
+		segsize = get_phys_buffer(src, remainder, &srcbuf);
+		bcopy(srcbuf, dest, segsize);
+		remainder -= segsize;
+		src += segsize;
+		dest += segsize;
+	} while (remainder > 0);
+
 	return (len);
 }
 
@@ -184,7 +244,7 @@ kboot_readin(const int fd, vm_offset_t d
 	buf = malloc(chunk);
 	if (buf == NULL) {
 		printf("kboot_readin: buf malloc failed\n");
-		return(0);
+		return (0);
 	}
 
 	for (resid = len; resid > 0; resid -= got, p += got) {
@@ -196,10 +256,10 @@ kboot_readin(const int fd, vm_offset_t d
 			break;
 		}
 
-		bcopy(buf, (void *)p, got);
+		kboot_copyin(buf, p, got);
 	}
 
-	free(buf);
+	free (buf);
 	return (len - resid);
 }
 

Modified: user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c
==============================================================================
--- user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c	Mon Dec 29 13:50:59 2014	(r276360)
+++ user/nwhitehorn/kboot/powerpc/kboot/ppc64_elf_freebsd.c	Mon Dec 29 14:14:40 2014	(r276361)
@@ -52,12 +52,6 @@ ppc64_elf_loadfile(char *filename, u_int
 	if (r != 0)
 		return (r);
 
-	/*
-	 * No need to sync the icache for modules: this will
-	 * be done by the kernel after relocation.
-	 */
-	if (!strcmp((*result)->f_type, "elf kernel"))
-		__syncicache((void *) (*result)->f_addr, (*result)->f_size);
 	return (0);
 }
 


More information about the svn-src-user mailing list