1/* $NetBSD: devopen.c,v 1.4 2008/04/28 20:23:18 martin Exp $ */ 2 3/*- 4 * Copyright (c) 2004 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by UCHIYAMA Yasushi. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32#include <lib/libsa/stand.h> 33#include <lib/libkern/libkern.h> 34 35#include <netinet/in.h> 36#include <lib/libsa/dev_net.h> 37#include <lib/libsa/ufs.h> 38#include <lib/libsa/nfs.h> 39#include <lib/libsa/dev_net.h> 40#include <machine/sbd.h> 41 42#include "local.h" 43 44extern uint8_t kernel_binary[]; 45extern int kernel_binary_size; 46 47extern struct fs_ops datafs_ops; 48extern struct fs_ops bfs_ops; 49struct fs_ops ufs_ops = FS_OPS(ufs); 50struct fs_ops nfs_ops = FS_OPS(nfs); 51 52extern struct devsw netdevsw; 53extern struct devsw dkdevsw; 54char fname[16]; 55 56/* Referenced by libsa/open.c */ 57struct fs_ops file_system[1]; 58int nfsys = 1; 59struct devsw devsw[1]; 60int ndevs = 1; 61 62int 63devopen(struct open_file *f, const char *request, char **file) 64{ 65 char *p, *filename; 66 int disk, partition; 67 void *addr; 68 size_t size; 69 70 strcpy(fname, request); 71 72 filename = 0; 73 for (p = fname; *p; p++) { 74 if (*p == ':') { 75 filename = p + 1; 76 *p = '\0'; 77 break; 78 } 79 } 80 81 if (filename == 0) { /* not a loader's request. probably ufs_ls() */ 82 printf("request=%s\n", request); 83 f->f_dev = &dkdevsw; 84 file_system[0] = ufs_ops; 85 devsw[0] = dkdevsw; 86 *file = "/"; 87 return 0; 88 } 89 90 /* Data section */ 91 if (strcmp(fname, "mem") == 0) { 92 data_attach(kernel_binary, kernel_binary_size); 93 *file = "noname"; 94 f->f_flags |= F_NODEV; 95 file_system[0] = datafs_ops; 96 printf("data(compiled):noname\n"); 97 return 0; 98 } 99 100 /* NFS boot */ 101 if (strcmp(fname, "nfs") == 0) { 102 if (!DEVICE_CAPABILITY.network_enabled) { 103 printf("Network disabled.\n"); 104 return -1; 105 } 106 try_bootp = true; 107 file_system[0] = nfs_ops; 108 f->f_dev = &netdevsw; 109 if (*filename == '\0') { 110 printf("set kernel filename. ex.) nfs:netbsd\n"); 111 return 1; 112 } 113 *--filename = '/'; 114 *file = filename; 115 printf("nfs:/%s\n", filename); 116 net_open(f); 117 return 0; 118 } 119 120 /* FD boot */ 121 if (strcmp(fname, "fd") == 0) { 122 printf("floppy(boot):/%s (ustarfs)\n", filename); 123 f->f_dev = &dkdevsw; 124 file_system[0] = datafs_ops; 125 devsw[0] = dkdevsw; 126 device_attach(NVSRAM_BOOTDEV_FLOPPYDISK, -1, -1); 127 if (!ustarfs_load(filename, &addr, &size)) 128 return -1; 129 data_attach(addr, size); 130 *file = filename; 131 return 0; 132 } 133 134 /* Disk boot */ 135 if (strncmp(fname, "sd", 2) == 0) { 136 enum fstype fs; 137 if (!DEVICE_CAPABILITY.disk_enabled) { 138 printf("Disk disabled.\n"); 139 return -1; 140 } 141 142 disk = fname[2] - '0'; 143 partition = fname[3] - 'a'; 144 if (disk < 0 || disk > 9 || partition < 0 || partition > 15) { 145 fs = FSTYPE_USTARFS; 146 printf("disk(boot):%s ", filename); 147 device_attach(NVSRAM_BOOTDEV_HARDDISK, -1, -1); 148 } else { 149 fs = fstype(partition); 150 printf("disk(%d,%d):/%s ", 151 disk, partition, filename); 152 device_attach(NVSRAM_BOOTDEV_HARDDISK, disk, partition); 153 } 154 155 switch (fs) { 156 case FSTYPE_UFS: 157 printf(" (ufs)\n"); 158 f->f_dev = &dkdevsw; 159 file_system[0] = ufs_ops; 160 devsw[0] = dkdevsw; 161 break; 162 case FSTYPE_BFS: 163 printf(" (bfs)\n"); 164 f->f_flags |= F_NODEV; 165 file_system[0] = bfs_ops; 166 break; 167 case FSTYPE_USTARFS: 168 printf(" (ustarfs)\n"); 169 f->f_dev = &dkdevsw; 170 file_system[0] = datafs_ops; 171 devsw[0] = dkdevsw; 172 if (!ustarfs_load(filename, &addr, &size)) 173 return -1; 174 data_attach(addr, size); 175 break; 176 } 177 *file = filename; 178 return 0; 179 } 180 181 printf("%s invalid.\n", fname); 182 183 return -1; 184} 185