/* $NetBSD: devopen.c,v 1.5 2011/12/25 06:09:09 tsutsui Exp $ */ /*- * Copyright (c) 2004 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by UCHIYAMA Yasushi. * * 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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS * ``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 THE FOUNDATION OR CONTRIBUTORS * 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 #include #include #include #include #include #include #include #include "local.h" extern uint8_t kernel_binary[]; extern int kernel_binary_size; extern struct fs_ops datafs_ops; extern struct fs_ops bfs_ops; struct fs_ops ufs_ops = FS_OPS(ufs); struct fs_ops nfs_ops = FS_OPS(nfs); extern struct devsw netdevsw; extern struct devsw dkdevsw; char fname[16]; /* Referenced by libsa/open.c */ struct fs_ops file_system[1]; int nfsys = 1; struct devsw devsw[1]; int ndevs = 1; int devopen(struct open_file *f, const char *request, char **file) { char *p, *filename; int disk, partition; void *addr; size_t size; strcpy(fname, request); filename = 0; for (p = fname; *p; p++) { if (*p == ':') { filename = p + 1; *p = '\0'; break; } } if (filename == 0) { /* not a loader's request. probably ufs_ls() */ printf("request=%s\n", request); f->f_dev = &dkdevsw; file_system[0] = ufs_ops; devsw[0] = dkdevsw; *file = "/"; return 0; } /* Data section */ if (strcmp(fname, "mem") == 0) { data_attach(kernel_binary, kernel_binary_size); *file = "noname"; f->f_flags |= F_NODEV; file_system[0] = datafs_ops; printf("data(compiled):noname\n"); return 0; } /* NFS boot */ if (strcmp(fname, "nfs") == 0) { if (!DEVICE_CAPABILITY.network_enabled) { printf("Network disabled.\n"); return -1; } try_bootp = true; file_system[0] = nfs_ops; f->f_dev = &netdevsw; if (*filename == '\0') { printf("set kernel filename. ex.) nfs:netbsd\n"); return 1; } *--filename = '/'; *file = filename; printf("nfs:/%s\n", filename); net_open(f); return 0; } /* FD boot */ if (strcmp(fname, "fd") == 0) { printf("floppy(boot):/%s (ustarfs)\n", filename); f->f_dev = &dkdevsw; file_system[0] = datafs_ops; devsw[0] = dkdevsw; device_attach(NVSRAM_BOOTDEV_FLOPPYDISK, -1, -1); if (!ustarfs_load(filename, &addr, &size)) return -1; data_attach(addr, size); *file = filename; return 0; } /* Disk boot */ if (strncmp(fname, "sd", 2) == 0) { enum fstype fs; if (!DEVICE_CAPABILITY.disk_enabled) { printf("Disk disabled.\n"); return -1; } disk = fname[2] - '0'; partition = fname[3] - 'a'; if (disk < 0 || disk > 9 || partition < 0 || partition > 15) { fs = FSTYPE_USTARFS; printf("disk(boot):%s ", filename); device_attach(NVSRAM_BOOTDEV_HARDDISK, -1, -1); } else { fs = fstype(partition); printf("disk(%d,%d):/%s ", disk, partition, filename); device_attach(NVSRAM_BOOTDEV_HARDDISK, disk, partition); } switch (fs) { case FSTYPE_UFS: printf(" (ufs)\n"); f->f_dev = &dkdevsw; file_system[0] = ufs_ops; devsw[0] = dkdevsw; break; case FSTYPE_BFS: printf(" (bfs)\n"); f->f_flags |= F_NODEV; file_system[0] = bfs_ops; break; case FSTYPE_USTARFS: printf(" (ustarfs)\n"); f->f_dev = &dkdevsw; file_system[0] = datafs_ops; devsw[0] = dkdevsw; if (!ustarfs_load(filename, &addr, &size)) return -1; data_attach(addr, size); break; } *file = filename; return 0; } printf("%s invalid.\n", fname); return -1; }