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