Index: user/nwhitehorn/kboot/powerpc/kboot/main.c =================================================================== --- user/nwhitehorn/kboot/powerpc/kboot/main.c (revision 276331) +++ user/nwhitehorn/kboot/powerpc/kboot/main.c (revision 276332) @@ -1,186 +1,210 @@ /*- * Copyright (C) 2010-2014 Nathan Whitehorn * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL TOOLS GMBH BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include __FBSDID("$FreeBSD$"); #include #include #define _KERNEL #include #include "bootstrap.h" #include "host_syscall.h" struct arch_switch archsw; extern void *_end; extern char bootprog_name[]; extern char bootprog_rev[]; extern char bootprog_date[]; extern char bootprog_maker[]; int kboot_getdev(void **vdev, const char *devspec, const char **path); ssize_t kboot_copyin(const void *src, vm_offset_t dest, const size_t len); ssize_t kboot_copyout(vm_offset_t src, void *dest, const size_t len); ssize_t kboot_readin(const int fd, vm_offset_t dest, const size_t len); int kboot_autoload(void); int kboot_setcurrdev(struct env_var *ev, int flags, const void *value); int kboot_getdev(void **vdev, const char *devspec, const char **path) { - printf("Devspec: %s\n", devspec); - return (0); + int i; + const char *devpath, *filepath; + struct devsw *dv; + + if (devspec[0] == '/') { + devpath = getenv("currdev"); + filepath = devspec; + } else { + devpath = devspec; + if (strchr(devspec, ':') == NULL) + filepath = NULL; + else + filepath = strchr(devspec, ':') + 1; + } + for (i = 0; (dv = devsw[i]) != NULL; i++) { + if (strncmp(dv->dv_name, devpath, strlen(dv->dv_name)) == 0) + goto found; + } + return (ENOENT); + +found: + if (path != NULL) + *path = filepath; + else if (path != NULL) + *path = strchr(devspec, ':') + 1; + *vdev = strdup(devpath); } int main(int argc, const char **argv) { void *heapbase; /* * Set the heap to one page after the end of the loader. */ heapbase = host_getmem(0, 0x100000); setheap(heapbase, heapbase + 0x100000); /* * Set up console. */ cons_probe(); printf("Boot device: %s\n", argv[1]); archsw.arch_getdev = kboot_getdev; archsw.arch_copyin = kboot_copyin; archsw.arch_copyout = kboot_copyout; archsw.arch_readin = kboot_readin; archsw.arch_autoload = kboot_autoload; printf("\n"); printf("%s, Revision %s\n", bootprog_name, bootprog_rev); printf("(%s, %s)\n", bootprog_maker, bootprog_date); setenv("currdev", argv[1], 1); setenv("loaddev", argv[1], 1); setenv("LINES", "24", 1); interact(NULL); /* doesn't return */ return (0); } void exit(int code) { /* XXX: host_exit */ } void delay(int usecs) { /* XXX */ } int getsecs() { /* XXX */ return (0); } time_t time(time_t *tloc) { time_t rv; rv = getsecs(); if (tloc != NULL) *tloc = rv; return (rv); } ssize_t kboot_copyin(const void *src, vm_offset_t dest, const size_t len) { bcopy(src, (void *)dest, len); return (len); } ssize_t kboot_copyout(vm_offset_t src, void *dest, const size_t len) { bcopy((void *)src, dest, len); return (len); } ssize_t kboot_readin(const int fd, vm_offset_t dest, const size_t len) { void *buf; size_t resid, chunk, get; ssize_t got; vm_offset_t p; p = dest; chunk = min(PAGE_SIZE, len); buf = malloc(chunk); if (buf == NULL) { printf("kboot_readin: buf malloc failed\n"); return(0); } for (resid = len; resid > 0; resid -= got, p += got) { get = min(chunk, resid); got = read(fd, buf, get); if (got <= 0) { if (got < 0) printf("kboot_readin: read failed\n"); break; } bcopy(buf, (void *)p, got); } free(buf); return (len - resid); } int kboot_autoload(void) { return (0); } void _start(int argc, const char **argv, char **env) { main(argc, argv); }