Date: Mon, 29 Dec 2014 14:14:40 +0000 (UTC) From: Nathan Whitehorn <nwhitehorn@FreeBSD.org> To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r276361 - user/nwhitehorn/kboot/powerpc/kboot Message-ID: <201412291414.sBTEEeRK059691@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
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); }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201412291414.sBTEEeRK059691>